terry@edm.UUCP (Terry Tout) (08/17/87)
MINIX 1.2 looks good; as one person said a month or so ago: although the kernel for MINIX may be Version 7 compatible, the utilities are only up to Version 6. The new distribution seems to correct much of this. Yacc, lex, and uucp are still missing, but... Anyway, there are still two programs (which apparently have been posted before) that many people do not have. They are cal(1), and login(1). In an effort to alleviate this, I wrote a simple version of login, but it would be nice to get the "real" version posted by ast. Could someone out there post them? ========> <======== ===> In an attempt to keep from having 600 copies to be posted, how <=== ===> about the person who runs the archives on nosc or ast himself <=== ===> being the poster? <=== ========> <======== I also am missing the at_wini.c driver which was recently posted. Professor Tanenbaum: thank you very much for creating the operating system I love for the machine I have, and put me down as one of those poor unfortunate students who can't afford a hard-disk. Christopher Dutchyn ihnp4!alberta!edm!terry (Please don't overfill this mailbox, it doesn't belong to me....)
ast@cs.vu.nl (Andy Tanenbaum) (08/20/87)
In article <171@edm.UUCP> terry@edm.UUCP (Terry Tout) writes: > >Anyway, there are still two programs (which apparently have been posted >before) that many people do not have. They are cal(1), and login(1). Here they are (again). Andy Tanenbaum (ast@cs.vu.nl) : This is a shar archive. Extract with sh, not csh. : This archive ends with exit, so do not worry about trailing junk. : --------------------------- cut here -------------------------- PATH=/bin:/usr/bin:/usr/ucb echo Extracting \l\o\g\i\n\.\c sed 's/^X//' > \l\o\g\i\n\.\c << '+ END-OF-FILE '\l\o\g\i\n\.\c X/* login - log into the system Author: Patrick van Kleef */ X X#include "signal.h" X#include "sgtty.h" X#include "pwd.h" X Xmain() X{ X char buf[30], X buf1[30], X *crypt(); X int n, n1, bad; X struct sgttyb args; X struct passwd *pwd, *getpwnam(); X X args.sg_kill = '@'; X args.sg_erase = '\b'; X args.sg_flags = 06030; X ioctl (0, TIOCSETP, &args); X X X /* Get login name and passwd. */ X for (;;) { X bad = 0; X do { X write(1,"login: ",7); X n = read (0, buf, 30); X } while (n < 2); X buf[n - 1] = 0; X X /* Look up login/passwd. */ X if ((pwd = getpwnam (buf)) == 0) X bad++; X X if (bad || strlen (pwd->pw_passwd) != 0) { X args.sg_flags = 06020; X ioctl (0, TIOCSETP, &args); X write(1,"Password: ",10); X n1 = read (0, buf1, 30); X buf1[n1 - 1] = 0; X write(1,"\n",1); X args.sg_flags = 06030; X ioctl (0, TIOCSETP, &args); X if (bad || strcmp (pwd->pw_passwd, crypt(buf1, pwd->pw_passwd))) { X write (1,"Login incorrect\n",16); X continue; X } X } X X /* Successful login. */ X setgid (pwd->pw_gid); X setuid (pwd->pw_uid); X chdir (pwd->pw_dir); X if (pwd->pw_shell) { X execl(pwd->pw_shell, "-", (char *) 0); X } X execl("/bin/sh", "-", (char *) 0); X write(1,"exec failure\n",13); X } X} + END-OF-FILE login.c chmod 'u=rw,g=r,o=r' \l\o\g\i\n\.\c set `wc -c \l\o\g\i\n\.\c` count=$1 case $count in 1211) :;; *) echo 'Bad character count in '\l\o\g\i\n\.\c >&2 echo 'Count should be 1211' >&2 esac echo Extracting \c\a\l\.\c sed 's/^X//' > \c\a\l\.\c << '+ END-OF-FILE '\c\a\l\.\c X/* cal - print a calendar Author: Maritn Minow */ X X#include "../include/stdio.h" X X#define do3months domonth X#define IO_SUCCESS 0 /* Unix definitions */ X#define IO_ERROR 1 X#define EOS 0 X X#define ENTRY_SIZE 3 /* 3 bytes per value */ X#define DAYS_PER_WEEK 7 /* Sunday, etc. */ X#define WEEKS_PER_MONTH 6 /* Max. weeks in a month */ X#define MONTHS_PER_LINE 3 /* Three months across */ X#define MONTH_SPACE 3 /* Between each month */ X Xchar *badarg = {"Bad argument\n"}; Xchar *how = {"Usage: cal [month] year\n"}; X X/* X * calendar() stuffs data into layout[], X * output() copies from layout[] to outline[], (then trims blanks). X */ Xchar layout[MONTHS_PER_LINE][WEEKS_PER_MONTH][DAYS_PER_WEEK][ENTRY_SIZE]; Xchar outline[(MONTHS_PER_LINE * DAYS_PER_WEEK * ENTRY_SIZE) X + (MONTHS_PER_LINE * MONTH_SPACE) X + 1]; X Xchar *weekday = " S M Tu W Th F S"; Xchar *monthname[] = { X "???", /* No month 0 */ X "Jan", "Feb", "Mar", "Apr", "May", "Jun", X "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" X}; X Xmain(argc, argv) Xint argc; Xchar *argv[]; X{ X register int month; X register int year; X X register int arg1val; X int arg1len; X int arg2val; X X if (argc <= 1) { X usage(how); X } else { X arg1val = atoi(argv[1]); X arg1len = strlen(argv[1]); X if (argc == 2) { X /* X * Only one argument, if small, it's a month. If X * large, it's a year. Note: X * cal 0082 Year 0082 X * cal 82 Year 0082 X */ X if (arg1len <= 2 && arg1val <= 12) X do3months(year, arg1val); X else X doyear(arg1val); X } else { X /* X * Two arguments, allow 1980 12 or 12 1980 X */ X arg2val = atoi(argv[2]); X if (arg1len > 2) X do3months(arg1val, arg2val); X else X do3months(arg2val, arg1val); X } X } X exit(IO_SUCCESS); X} X Xdoyear(year) Xint year; X/* X * Print the calendar for an entire year. X */ X{ X register int month; X X if (year < 1 || year > 9999) usage(badarg); X if (year < 100) X printf("\n\n\n 00%2d\n\n", year); X else X printf("\n\n\n%35d\n\n", year); X for (month = 1; month <= 12; month += MONTHS_PER_LINE) { X printf("%12s%23s%23s\n", X monthname[month], X monthname[month+1], X monthname[month+2]); X printf("%s %s %s\n", weekday, weekday, weekday); X calendar(year, month+0, 0); X calendar(year, month+1, 1); X calendar(year, month+2, 2); X output(3); X#if MONTHS_PER_LINE != 3 X << error, the above won't work >> X#endif X } X printf("\n\n\n"); X} X Xdomonth(year, month) Xint year; Xint month; X/* X * Do one specific month -- note: no longer used X */ X{ X if (year < 1 || year > 9999) usage(badarg); X if (month <= 0 || month > 12) usage(badarg); X printf("%9s%5d\n\n%s\n", monthname[month], year, weekday); X calendar(year, month, 0); X output(1); X printf("\n\n"); X} X Xoutput(nmonths) Xint nmonths; /* Number of months to do */ X/* X * Clean up and output the text. X */ X{ X register int week; X register int month; X register char *outp; X int i; X char tmpbuf[21], *p; X X for (week = 0; week < WEEKS_PER_MONTH; week++) { X outp = outline; X for (month = 0; month < nmonths; month++) { X /* X * The -1 in the following removes X * the unwanted leading blank from X * the entry for Sunday. X */ X p = &layout[month][week][0][1]; X for (i=0; i<20; i++) tmpbuf[i] = *p++; X tmpbuf[20] = 0; X sprintf(outp, "%s ", tmpbuf); X outp += (DAYS_PER_WEEK * ENTRY_SIZE) + MONTH_SPACE - 1; X } X while (outp > outline && outp[-1] == ' ') outp--; X *outp = EOS; X puts(outline); X } X} X Xcalendar(year, month, index) Xint year; Xint month; Xint index; /* Which of the three months */ X/* X * Actually build the calendar for this month. X */ X{ X register char *tp; X int week; X register int wday; X register int today; X X setmonth(year, month); X for (week = 0; week < WEEKS_PER_MONTH; week++) { X for (wday = 0; wday < DAYS_PER_WEEK; wday++) { X tp = &layout[index][week][wday][0]; X *tp++ = ' '; X today = getdate(week, wday); X if (today <= 0) { X *tp++ = ' '; X *tp++ = ' '; X } X else if (today < 10) { X *tp++ = ' '; X *tp = (today + '0'); X } X else { X *tp++ = (today / 10) + '0'; X *tp = (today % 10) + '0'; X } X } X } X} X Xusage(s) Xchar *s; X{ X/* Fatal parameter error. */ X X fprintf(stderr, "%s", s); X exit(IO_ERROR); X} X X/* X * Calendar routines, intended for eventual porting to TeX X * X * date(year, month, week, wday) X * Returns the date on this week (0 is first, 5 last possible) X * and day of the week (Sunday == 0) X * Note: January is month 1. X * X * setmonth(year, month) X * Parameters are as above, sets getdate() for this month. X * X * int X * getdate(week, wday) X * Parameters are as above, uses the data set by setmonth() X */ X X/* X * This structure is used to pass data between setmonth() and getdate(). X * It needs considerable expansion if the Julian->Gregorian change is X * to be extended to other countries. X */ X Xstatic struct { X int this_month; /* month number used in 1752 checking */ X int feb; /* Days in February for this month */ X int sept; /* Days in September for this month */ X int days_in_month; /* Number of days in this month */ X int dow_first; /* Day of week of the 1st day in month */ X} info; X Xstatic int day_month[] = { /* 30 days hath September... */ X 0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 X}; X Xint Xdate(year, month, week, wday) Xint year; /* Calendar date being computed */ Xint month; /* January == 1 */ Xint week; /* Week in the month 0..5 inclusive */ Xint wday; /* Weekday, Sunday == 0 */ X/* X * Return the date of the month that fell on this week and weekday. X * Return zero if it's out of range. X */ X{ X setmonth(year, month); X return (getdate(week, wday)); X} X Xsetmonth(year, month) Xint year; /* Year to compute */ Xint month; /* Month, January is month 1 */ X/* X * Setup the parameters needed to compute this month X * (stored in the info structure). X */ X{ X register int i; X X if (month < 1 || month > 12) { /* Verify caller's parameters */ X info.days_in_month = 0; /* Garbage flag */ X return; X } X info.this_month = month; /* used in 1752 checking */ X info.dow_first = Jan1(year); /* Day of January 1st for now */ X info.feb = 29; /* Assume leap year */ X info.sept = 30; /* Assume normal year */ X /* X * Determine whether it's an ordinary year, a leap year X * or the magical calendar switch year of 1752. X */ X switch ((Jan1(year + 1) + 7 - info.dow_first) % 7) { X case 1: /* Not a leap year */ X info.feb = 28; X case 2: /* Ordinary leap year */ X break; X X default: /* The magical moment arrives */ X info.sept = 19; /* 19 days hath September */ X break; X } X info.days_in_month = X (month == 2) ? info.feb X : (month == 9) ? info.sept X : day_month[month]; X for (i = 1; i < month; i++) { X switch (i) { /* Special months? */ X case 2: /* February */ X info.dow_first += info.feb; X break; X X case 9: X info.dow_first += info.sept; X break; X X default: X info.dow_first += day_month[i]; X break; X } X } X info.dow_first %= 7; /* Now it's Sunday to Saturday */ X} X Xint getdate(week, wday) Xint week; Xint wday; X{ X register int today; X X /* X * Get a first guess at today's date and make sure it's in range. X */ X today = (week * 7) + wday - info.dow_first + 1; X if (today <= 0 || today > info.days_in_month) X return (0); X else if (info.sept == 19 && info.this_month == 9 X && today >= 3) /* The magical month? */ X return (today + 11); /* If so, some dates changed */ X else /* Otherwise, */ X return (today); /* Return the date */ X} X Xstatic int Jan1(year) Xint year; X/* X * Return day of the week for Jan 1 of the specified year. X */ X{ X register int day; X X day = year + 4 + ((year + 3) / 4); /* Julian Calendar */ X if (year > 1800) { /* If it's recent, do */ X day -= ((year - 1701) / 100); /* Clavian correction */ X day += ((year - 1601) / 400); /* Gregorian correction */ X } X if (year > 1752) /* Adjust for Gregorian */ X day += 3; /* calendar */ X return (day % 7); X} X + END-OF-FILE cal.c chmod 'u=rw,g=r,o=r' \c\a\l\.\c set `wc -c \c\a\l\.\c` count=$1 case $count in 7998) :;; *) echo 'Bad character count in '\c\a\l\.\c >&2 echo 'Count should be 7998' >&2 esac exit 0