Relay-Version: version B 2.10 5/3/83; site utzoo.UUCP Path: utzoo!mnetor!uunet!seismo!mcvax!botter!star!ast From: ast@cs.vu.nl (Andy Tanenbaum) Newsgroups: comp.os.minix Subject: Re: Cal, Login, at_wini.c Message-ID: <481@ast.cs.vu.nl> Date: Thu, 20-Aug-87 06:45:30 EDT Article-I.D.: ast.481 Posted: Thu Aug 20 06:45:30 1987 Date-Received: Sat, 22-Aug-87 09:48:05 EDT References: <171@edm.UUCP> Reply-To: ast@cs.vu.nl () Organization: VU Informatica, Amsterdam Lines: 431 Keywords: cal MINIX login at_wini.c 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