evas@euraiv1.UUCP (Eelco van Asperen) (10/02/87)
Here is part 6 of 9: Eelco van Asperen. # 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 echo Extracting commands/ar.dif sed 's/^X//' > commands/ar.dif << '+ END-OF-FILE 'commands/ar.dif X244c244 X< ar_fd = open_archive(argv[2], (show_fl || pr_fl) ? READ : APPEND); X--- X> ar_fd = open_archive(argv[2], (show_fl || pr_fl || ex_fl) ? READ : APPEND); + END-OF-FILE commands/ar.dif chmod u=rw,g=r,o=r commands/ar.dif set `sum commands/ar.dif` sum=$1 case $sum in 12600) :;; *) echo 'Bad sum in 'commands/ar.dif >&2 esac echo Extracting commands/basename.dif sed 's/^X//' > commands/basename.dif << '+ END-OF-FILE 'commands/basename.dif X21,23c21,23 X< if (d == NULL) X< d = argv[1]; X< else X--- X> if (d == NULL) X> d = argv[1]; X> else X27c27 X< prints("%s \n",d); X--- X> prints("%s\n",d); X35,36c35 X< prints("%s \n",c); X< } X--- X> } + END-OF-FILE commands/basename.dif chmod u=rw,g=r,o=r commands/basename.dif set `sum commands/basename.dif` sum=$1 case $sum in 12694) :;; *) echo 'Bad sum in 'commands/basename.dif >&2 esac echo Extracting commands/cal.c sed 's/^X//' > commands/cal.c << '+ END-OF-FILE 'commands/cal.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 ' /* this last quote is to fool Turbo C's X * simple builtin preprocessor X */ 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 commands/cal.c chmod u=rw,g=r,o=r commands/cal.c set `sum commands/cal.c` sum=$1 case $sum in 16624) :;; *) echo 'Bad sum in 'commands/cal.c >&2 esac echo Extracting commands/cat.dif sed 's/^X//' > commands/cat.dif << '+ END-OF-FILE 'commands/cat.dif X86c86 X< if (write(1, buffer, next - buffer) <= 0) quit(); X--- X> if (write(1, buffer, (int) (next - buffer)) <= 0) quit(); + END-OF-FILE commands/cat.dif chmod u=rw,g=r,o=r commands/cat.dif set `sum commands/cat.dif` sum=$1 case $sum in 8897) :;; *) echo 'Bad sum in 'commands/cat.dif >&2 esac echo Extracting commands/chmem.dif sed 's/^X//' > commands/chmem.dif << '+ END-OF-FILE 'commands/chmem.dif X1c1,18 X< /* chmem - set total memory size for execution Author: Andy Tanenbaum */ X--- X> /* chmem - set total memory size for execution Author: Andy Tanenbaum */ X> X> /* modified for use with Turbo C under DOS by Eelco van Asperen, 87/08/26 X> * X> * Changes made involve the use of unsigned long's rather than long's and X> * unsigned int's; and the mode-parameter for open() has to include O_BINARY X> * for Turbo C. X> */ X> X> #ifdef DOS X> # include <fcntl.h> X> # include <stdlib.h> X> X> # define RWMODE (O_RDWR|O_BINARY) X> #else X> # define RWMODE (2) X> #endif X> X9c26,34 X< #define SEPBIT 0x00200000 /* this bit is set for separate I/D */ X--- X> X> #ifdef DOS X> # define SEPBIT 0x00200000L /* this bit is set for separate I/D */ X> # define MAXPARAM 65520lu /* maximum for parameter */ X> #else X> # define SEPBIT 0x00200000 /* this bit is set for separate I/D */ X> # define MAXPARAM 65520 /* maximum for parameter */ X> #endif X> X28,32c53,60 X< X< char *p; X< unsigned int n; X< int fd, separate; X< long lsize, olddynam, newdynam, newtot, overflow, header[HLONG]; X--- X> char *p; X> int fd, separate; X> #ifdef DOS X> unsigned long lsize, olddynam, newdynam, newtot, overflow, header[HLONG]; X> #else X> unsigned int n; X> long lsize, olddynam, newdynam, newtot, overflow, header[HLONG]; X> #endif X37,41c65,73 X< n = atoi(p+1); X< lsize = n; X< if (n > 65520) stderr3("chmem: ", p+1, " too large\n"); X< X< fd = open(argv[2], 2); X--- X> #ifdef DOS X> lsize = (unsigned long) atol(p+1); X> #else X> n = atoi(p+1); X> lsize = n; X> #endif X> if (lsize > MAXPARAM) stderr3("chmem: ", p+1, " too large\n"); X> X> fd = open(argv[2], RWMODE); X63,64c95,103 X< printf("%s: Stack+malloc area changed from %D to %D bytes.\n", X< argv[2], olddynam, newdynam); X--- X> X> #ifdef DOS X> printf("%s: Stack+malloc area changed from %lu to %lu bytes.\n", X> argv[2], olddynam, newdynam); X> #else X> printf("%s: Stack+malloc area changed from %D to %D bytes.\n", X> argv[2], olddynam, newdynam); X> #endif X> X70c109 X< std_err("chmem {=+-} amount file\n"); X--- X> std_err("usage:\tchmem {=+-} amount file\n"); X81a121,133 X> X> #ifdef DOS X> X> std_err(s) X> char *s; X> { X> char *p = s; X> X> while(*p != 0) p++; X> write(2, s, p - s); X> } X> X> #endif + END-OF-FILE commands/chmem.dif chmod u=rw,g=r,o=r commands/chmem.dif set `sum commands/chmem.dif` sum=$1 case $sum in 40156) :;; *) echo 'Bad sum in 'commands/chmem.dif >&2 esac echo Extracting commands/cp.dif sed 's/^X//' > commands/cp.dif << '+ END-OF-FILE 'commands/cp.dif X47a48 X> exit(0); + END-OF-FILE commands/cp.dif chmod u=rw,g=r,o=r commands/cp.dif set `sum commands/cp.dif` sum=$1 case $sum in 1120) :;; *) echo 'Bad sum in 'commands/cp.dif >&2 esac echo Extracting commands/cpdir.c sed 's/^X//' > commands/cpdir.c << '+ END-OF-FILE 'commands/cpdir.c X/* cpdir - copy directory Author: Erik Baalbergen */ X X/* Use "cpdir [-v] src dst" to make a copy dst of directory src. X Cpdir should behave like the UNIX shell command X (cd src; tar cf - .) | (mkdir dst; cd dst; tar xf -) X but the linking structure of the tree, and the owner and time X information of files are not yet preserved. (See the work-yet-to-be-done list X below.) X The -v "verbose" flag enables you to see what's going on when running cpdir. X X Work yet to be done: X - preserve link structure, times, etc... X - 'stat' optimization (stat() is invoked twice for normal files) X - link checks, i.e. am I not overwriting a file/directory by itself? X * has been solved by letting 'cpdir' create the target directory X - handle character and block special files X * they're simply not copied X X Please report bugs and suggestions to erikb@cs.vu.nl X*/ X X#include "stdio.h" X X#define MKDIR1 "/bin/mkdir" X#define MKDIR2 "/usr/bin/mkdir" X#ifdef UNIX X#include <sys/types.h> X#include <sys/stat.h> X#else !UNIX X#include "stat.h" X#endif X X#define BUFSIZE 1024 X#define PLEN 256 X#define DIRSIZ 16 X Xchar *prog; Xint vflag = 0; /* verbose */ Xchar *strcpy(); X Xmain(argc, argv) X char *argv[]; X{ X int rc = 0; X char *p, *s; X X prog = *argv++; X if ((p = *argv) && *p == '-') { X argv++; X argc--; X while (*++p) { X switch (*p) { X case 'v': X vflag = 1; X break; X default: X fatal("illegal flag %s", p); X } X } X } X if (argc != 3) X fatal("Usage: cpdir [-v] source destination"); X if (ftype(s = *argv++) != S_IFDIR) X fatal("%s is not a directory", s); X cpdir(s, *argv); X exit(0); X} X Xcpdir(s, d) X char *s, *d; X{ X char spath[PLEN], dpath[PLEN]; X char ent[DIRSIZ + 1]; X register char *send = spath, *dend = dpath; X int fd, n; X X while (*send++ = *s++) {} X send--; X while (*dend++ = *d++) {} X if ((fd = open(spath, 0)) < 0) { X nonfatal("can't read directory %s", spath); X return; X } X *send++ = '/'; X ent[DIRSIZ] = '\0'; X mkdir(dpath); X dend[-1] = '/'; X while ((n = read(fd, ent, DIRSIZ)) == DIRSIZ) { X if (!((ent[0] == '\0' && ent[1] == '\0') X || (ent[2] == '.') && X (ent[3] == '\0' || (ent[3] == '.' && ent[4] == '\0')) X )) { X strcpy(send, ent + 2); X strcpy(dend, ent + 2); X switch (ftype(spath)) { X case S_IFDIR: X cpdir(spath, dpath); X break; X case S_IFREG: X cp(spath, dpath); X break; X default: X nonfatal("can't copy special file %s", spath); X } X } X } X close(fd); X if (n) X fatal("error in reading directory %s", spath); X} X Xmkdir(s) X char *s; X{ X int pid, status; X X if (vflag) X printf("mkdir %s\n", s); X if ((pid = fork()) == 0) { X execl(MKDIR1, "mkdir", s, (char *)0); X execl(MKDIR2, "mkdir", s, (char *)0); X fatal("can't execute %s or %s", MKDIR1, MKDIR2); X } X if (pid == -1) X fatal("can't fork", prog); X wait(&status); X if (status) X fatal("can't create %s", s); X} X Xcp(s, d) X char *s, *d; X{ X struct stat st; X char buf[BUFSIZE]; X int sfd, dfd, n; X X if (vflag) X printf("cp %s %s\n", s, d); X if ((sfd = open(s, 0)) < 0) X nonfatal("can't read %s", s); X else { X if (fstat(sfd, &st) < 0) X fatal("can't get file status of %s", s); X if ((dfd = creat(d, st.st_mode & 0777)) < 0) X fatal("can't create %s", d); X while ((n = read(sfd, buf, BUFSIZE)) > 0) X write(dfd, buf, n); X close(sfd); X close(dfd); X if (n) X fatal("error in reading file %s", s); X } X} X Xftype(s) X char *s; X{ X struct stat st; X X if (stat(s, &st) < 0) X fatal("can't get file status of %s", s); X return st.st_mode & S_IFMT; X} X Xnonfatal(s, a) X char *s, *a; X{ X fprintf(stderr, "%s: ", prog); X fprintf(stderr, s, a); X fprintf(stderr, "\n"); X} X Xfatal(s, a) X char *s, *a; X{ X nonfatal(s, a); X exit(1); X} X X + END-OF-FILE commands/cpdir.c chmod u=rw,g=r,o=r commands/cpdir.c set `sum commands/cpdir.c` sum=$1 case $sum in 8282) :;; *) echo 'Bad sum in 'commands/cpdir.c >&2 esac echo Extracting commands/df.dif sed 's/^X//' > commands/df.dif << '+ END-OF-FILE 'commands/df.dif X37d36 X< extern char *itoa(); X133a133 X> return(0); X146a147,149 X> extern char *itoa(); X> extern char *itoa(int); X> + END-OF-FILE commands/df.dif chmod u=rw,g=r,o=r commands/df.dif set `sum commands/df.dif` sum=$1 case $sum in 8568) :;; *) echo 'Bad sum in 'commands/df.dif >&2 esac echo Extracting commands/diff.c sed 's/^X//' > commands/diff.c << '+ END-OF-FILE 'commands/diff.c X/* diff - print differences between 2 files Author: Erik Baalbergen */ X X/* Poor man's implementation of diff(1) X - no options available X - may give more output than other diffs, due to the straight-forward algorithm X - runs out of memory if the differing chunks become too large X - input line length should not exceed LINELEN; longer lines are truncated, X while only the first LINELEN characters are compared X X Please report bugs and suggestions to erikb@cs.vu.nl X*/ X#include "stdio.h" XFILE *fopen(); X X#define LINELEN 128 X Xchar *prog; Xint diffs = 0; X Xmain(argc, argv) X char **argv; X{ X FILE *fp1 = NULL, *fp2 = NULL; X X prog = *argv++; X if (argc != 3) X fatal("use: %s file1 file2", prog); X if (strcmp(argv[0], "-") == 0) X fp1 = stdin; X else X if (strcmp(argv[1], "-") == 0) X fp2 = stdin; X if (fp1 == NULL && (fp1 = fopen(argv[0], "r")) == NULL) X fatal("can't read %s", argv[0]); X if (fp2 == NULL && (fp2 = fopen(argv[1], "r")) == NULL) X fatal("can't read %s", argv[1]); X diff(fp1, fp2); X exit(diffs > 0); X} X Xfatal(fmt, s) X char *fmt, *s; X{ X fprintf(stderr, "%s: ", prog); X fprintf(stderr, fmt, s); X fprintf(stderr, "\n"); X exit(2); X} X X/* the line module */ Xchar *malloc(); Xchar *fgets(); X Xstruct line { X struct line *l_next; X char l_text[LINELEN + 2]; X}; X Xstruct line *freelist = 0; X Xstruct line * Xnew_line() X{ X register struct line *l; X X if (l = freelist) X freelist = freelist->l_next; X else X if ((l = (struct line *)malloc(sizeof(struct line))) == 0) X fatal("out of memory"); X return l; X} X Xfree_line(l) X register struct line *l; X{ X l->l_next = freelist; X freelist = l; X} X X#define equal_line(l1, l2) (strcmp((l1)->l_text, (l2)->l_text) == 0) X Xint equal_3(l1, l2) X struct line *l1, *l2; X{ X register int i; X X for (i=0; i<3 && l1 && l2; ++i, l1=l1->l_next, l2=l2->l_next) { X if (!equal_line(l1, l2)) X return 0; X } X return (i==3); X} X Xstruct line * Xread_line(fp) X FILE *fp; X{ X register struct line *l = new_line(); X register char *p; X register int c; X X (p = &(l->l_text[LINELEN]))[1] = '\377'; X if (fgets(l->l_text, LINELEN + 2, fp) == NULL) { X free_line(l); X return 0; X } X if ((p[1] & 0377) != '\377' && *p != '\n') { X while ((c = fgetc(fp)) != '\n' && c != EOF) {} X *p++ = '\n'; X *p = '\0'; X } X l->l_next = 0; X return l; X} X X/* file window handler */ Xstruct f { X struct line *f_bwin, *f_ewin; X struct line *f_aside; X int f_linecnt; /* line number in file of last advanced line */ X FILE *f_fp; X}; X Xadvance(f) X register struct f *f; X{ X register struct line *l; X X if (l = f->f_bwin) { X if (f->f_ewin == l) X f->f_bwin = f->f_ewin = 0; X else X f->f_bwin = l->l_next; X free_line(l); X (f->f_linecnt)++; X } X} X Xaside(f, l) X struct f *f; X struct line *l; X{ X register struct line *ll; X X if (ll = l->l_next) { X while (ll->l_next) X ll = ll->l_next; X ll->l_next = f->f_aside; X f->f_aside = l->l_next; X l->l_next = 0; X f->f_ewin = l; X } X} X Xstruct line * Xnext(f) X register struct f *f; X{ X register struct line *l; X X if (l = f->f_aside) { X f->f_aside = l->l_next; X l->l_next = 0; X } X else X l = read_line(f->f_fp); X if (l) { X if (f->f_bwin == 0) X f->f_bwin = f->f_ewin = l; X else { X f->f_ewin->l_next = l; X f->f_ewin = l; X } X } X return l; X} X Xinit_f(f, fp) X register struct f *f; X FILE *fp; X{ X f->f_bwin = f->f_ewin = f->f_aside = 0; X f->f_linecnt = 0; X f->f_fp = fp; X} X Xupdate(f, s) X register struct f *f; X char *s; X{ X while (f->f_bwin && f->f_bwin != f->f_ewin) { X printf("%s%s", s, f->f_bwin->l_text); X advance(f); X } X} X X/* diff procedure */ Xdiff(fp1, fp2) X FILE *fp1, *fp2; X{ X struct f f1, f2; X struct line *l1, *s1, *b1, *l2, *s2, *b2; X register struct line *ll; X X init_f(&f1, fp1); X init_f(&f2, fp2); X l1 = next(&f1); X l2 = next(&f2); X while (l1 && l2) { X if (equal_line(l1, l2)) { Xequal: X advance(&f1); X advance(&f2); X l1 = next(&f1); X l2 = next(&f2); X continue; X } X s1 = b1 = l1; X s2 = b2 = l2; X /* read several more lines */ X next(&f1); next(&f1); X next(&f2); next(&f2); X /* start searching */ Xsearch: X if ((l2 = next(&f2)) == 0) X continue; X ll = s1; X b2 = b2->l_next; X do { X if (equal_3(ll, b2)) { X aside(&f1, ll); X aside(&f2, b2); X differ(&f1, &f2); X goto equal; X } X } while (ll = ll->l_next); X if ((l1 = next(&f1)) == 0) X continue; X ll = s2; X b1 = b1->l_next; X do { X if (equal_3(ll, b1)) { X aside(&f2, ll); X aside(&f1, b1); X differ(&f1, &f2); X goto equal; X } X } while (ll = ll->l_next); X goto search; X } X /* one of the files reached EOF */ X if (l1) /* eof on 2 */ X while (next(&f1)) {} X if (l2) X while (next(&f2)) {} X f1.f_ewin = 0; X f2.f_ewin = 0; X differ(&f1, &f2); X} X Xdiffer(f1, f2) X register struct f *f1, *f2; X{ X int cnt1 = f1->f_linecnt, len1 = wlen(f1), cnt2 = f2->f_linecnt, X len2 = wlen(f2); X X if ((len1 = wlen(f1)) || (len2 = wlen(f2))) { X if (len1 == 0) { X printf("%da", cnt1); X range(cnt2 + 1, cnt2 + len2); X } X else X if (len2 == 0) { X range(cnt1 + 1, cnt1 + len1); X printf("d%d", cnt2); X } X else { X range(cnt1 + 1, cnt1 + len1); X putchar('c'); X range(cnt2 + 1, cnt2 + len2); X } X putchar('\n'); X if (len1) X update(f1, "< "); X if (len1 && len2) X printf("---\n"); X if (len2) X update(f2, "> "); X diffs++; X } X} X Xwlen(f) X struct f *f; X{ X register cnt = 0; X register struct line *l = f->f_bwin, *e = f->f_ewin; X X while (l && l != e) { X cnt++; X l = l->l_next; X } X return cnt; X} X Xrange(a, b) X{ X printf(((a == b) ? "%d" : "%d,%d"), a, b); X} + END-OF-FILE commands/diff.c chmod u=rw,g=r,o=r commands/diff.c set `sum commands/diff.c` sum=$1 case $sum in 64242) :;; *) echo 'Bad sum in 'commands/diff.c >&2 esac echo Extracting commands/dosread.dif sed 's/^X//' > commands/dosread.dif << '+ END-OF-FILE 'commands/dosread.dif X16c16 X< #define DRIVE "/dev/fdX" X--- X> #define DRIVE "/dev/atX" X186c186 X< print_string(TRUE, "Diskette is neither 360K nor 1.2M\n"); X--- X> print_string(TRUE, "Diskette is not DOS 2.0 360K or 1.2M\n"); X279c279 X< while (*pathname != '/' && *pathname && i < 11) X--- X> while (*pathname != '/' && *pathname && i < 12) X494,506c494,502 X< for (i = 0, ptr = name; i < 8 && *ptr != '.' && *ptr; i++) X< entry->d_name[i] = *ptr++; X< while (i < 8) X< entry->d_name[i++] = ' '; X< r = strlen(name); X< while (r && name[r - 1] != '.') X< r--; X< X< i = 0; X< while (r && i < 3 && name[r]) X< entry->d_ext[i++] = name[r++]; X< while (i < 3) X< entry->d_ext[i++] = ' '; X--- X> bcopy(" ",&entry->d_name[0],11); /* clear entry */ X> for (i = 0, ptr = name; i < 8 && *ptr != '.' && *ptr; i++) X> entry->d_name[i] = *ptr++; X> while (*ptr != '.' && *ptr) X> ptr++; X> if (*ptr == '.') X> ptr++; X> for (i=0;i < 3 && *ptr; i++) X> entry->d_ext[i] = *ptr++; X584c580 X< day -= mon_len[i]; X--- X> day -= mon_len[i++]; X641c637 X< return (buffer - begin); X--- X> return (int) (buffer - begin); X819c815 X< write(2, buf, buf_ptr - buf); X--- X> write(2, buf, (int) (buf_ptr - buf)); + END-OF-FILE commands/dosread.dif chmod u=rw,g=r,o=r commands/dosread.dif set `sum commands/dosread.dif` sum=$1 case $sum in 14054) :;; *) echo 'Bad sum in 'commands/dosread.dif >&2 esac echo Extracting commands/fdisk.c sed 's/^X//' > commands/fdisk.c << '+ END-OF-FILE 'commands/fdisk.c X/* fdisk - partition a hard disk Author: Jakob Schripsema */ X X/* X * First run the DOS utilities FDISK and FORMAT. FDISK X * puts the boot code in sector 0. X * Then run fdisk X * X * fdisk /dev/hdx (MINIX) X * fdisk x: (DOS) X * X * Compiling X * X * cc -o fdisk -DUNIX fdisk.c (MINIX) X * cl -DDOS fdisk.c (DOS with MS C compiler) X */ X X#include "stdio.h" X#define UNIX /* for MINIX */ X X#ifdef DOS X#include <dos.h> X#endif X X/* X * Constants X */ X X#define NHEAD 4 /* # heads */ X#define NSEC 17 /* sectors / track */ X#define SECSIZE 512 /* sector size */ X#define OK 0 X#define ERR 1 X#define TABLEOFFSET 0x1be /* offset in boot sector*/ X/* X * Description of entry in partition table X */ X Xstruct part_entry { X char bootind; /* boot indicator 0/0x80 */ X char start_head; /* head value for first sector */ X char start_sec; /* sector value for first sector*/ X char start_cyl; /* track value for first sector */ X char sysind; /* system indicator 00=?? 01=DOS*/ X char last_head; /* head value for last sector */ X char last_sec; /* sector value for last sector */ X char last_cyl; /* track value for last sector */ X long lowsec; /* logical first sector */ X long size; /* size of partion in sectors */ X}; X X/* X * Globals X */ X Xchar secbuf[SECSIZE]; Xchar *devname; Xchar *dosstr = " DOS "; Xchar *ndosstr = "Non-DOS"; X X#ifdef DOS Xunion REGS regs; Xstruct SREGS sregs; Xint drivenum; X#endif X X#ifdef UNIX Xint devfd; X#endif X Xmain(argc,argv) Xint argc; Xchar *argv[]; X{ X char ch; X X /* init */ X X if (argc != 2) { X printf("Usage: fdisk /dev/hdx\n"); X exit(1); X } X X devname = argv[1]; X getboot(secbuf); /* get boot sector */ X X do { X dpl_partitions(); X print_menu(); X ch = get_a_char(); X putchar('\n'); X switch (ch) { X case 'c' : X change_table(); X break; X case 'w' : X if (chk_table() == OK) { X putboot(secbuf); X exit(0); X } X break; X case 'l' : X load_from_file(); X break; X case 's' : X save_to_file(); X break; X case 'p' : X dump_table(); X break; X case 'q' : X exit(0); X default : X printf(" %c ????\n",ch); X } X } X while (1); X} X X/* X * Read boot sector X */ X X#ifdef DOS X Xgetboot(buffer) Xchar *buffer; X{ X segread(&sregs); /* get ds */ X X if (devname[1] != ':') { X printf("Invalid drive %s\n",devname); X exit(1); X } X X if (*devname >= 'a') X *devname += 'A' - 'a'; X drivenum = (*devname - 'C') & 0xff; X if (drivenum < 0 || drivenum > 7) { X printf("Funny drive number %d\n",drivenum); X exit(1); X } X regs.x.ax = 0x201; /* read 1 sectors */ X regs.h.ch = 0; /* track */ X regs.h.cl = 1; /* first sector = 1 */ X regs.h.dh = 0; /* head = 0 */ X regs.h.dl = 0x80+drivenum;/* drive = 0 */ X sregs.es = sregs.ds; /* buffer address */ X regs.x.bx = (int)secbuf; X X int86x(0x13,®s,®s,&sregs); X if (regs.x.cflag) X { X printf("Cannot read boot sector\n"); X exit(1); X } X} X#endif X X#ifdef UNIX X Xgetboot(buffer) Xchar *buffer; X{ X devfd = open(devname,2); X if (devfd < 0) { X printf("Cannot open device %s\n",devname); X exit(1); X } X if (read(devfd,buffer,SECSIZE) != SECSIZE) { X printf("Cannot read boot sector\n"); X exit(2); X } X} X#endif X X/* X * Write boot sector X */ X X#ifdef DOS X Xputboot(buffer) Xchar *buffer; X{ X regs.x.ax = 0x301; /* read 1 sectors */ X regs.h.ch = 0; /* track */ X regs.h.cl = 1; /* first sector = 1 */ X regs.h.dh = 0; /* head = 0 */ X regs.h.dl = 0x80+drivenum;/* drive = 0 */ X sregs.es = sregs.ds; /* buffer address */ X regs.x.bx = (int)secbuf; X X int86x(0x13,®s,®s,&sregs); X if (regs.x.cflag) X { X printf("Cannot write boot sector\n"); X exit(1); X } X} X#endif X X#ifdef UNIX X Xputboot(buffer) Xchar *buffer; X{ X int r; X X if (lseek(devfd,0L,0) < 0) { X printf("Seek error during write\n"); X exit(1); X } X if (write(devfd,buffer,SECSIZE) != SECSIZE) { X printf("Write error\n"); X exit(1); X } X sync(); X} X#endif X X/* X * Load buffer from file X */ X Xload_from_file() X{ X char file[80]; X int fd; X X printf("Enter file name: "); X gets(file); X#ifdef UNIX X fd = open(file,0); X#endif X#ifdef DOS X fd = open(file,0x8000); X#endif X if (fd < 0) { X fprintf(stderr,"Cannot load from %s\n",file); X exit(1); X } X if (read(fd,secbuf,SECSIZE) != SECSIZE) { X fprintf(stderr,"Read error\n"); X exit(1); X } X close(fd); X} X X/* X * Save to file X */ X Xsave_to_file() X{ X char file[80]; X int fd; X X printf("Enter file name: "); X gets(file); X#ifdef UNIX X fd = creat(file,0644); X#endif X#ifdef DOS X fd = creat(file,0644); X if (fd < 0) { X fprintf(stderr,"Cannot creat %s\n",file); X exit(1); X } X close(fd); X fd = open(file,0x8001); X#endif X if (fd < 0) { X fprintf(stderr,"Cannot save to %s\n",file); X exit(1); X } X if (write(fd,secbuf,SECSIZE) != SECSIZE) { X fprintf(stderr,"Write error\n"); X exit(1); X } X close(fd); X} X X/* X * Dump partition table X */ X Xdump_table() X{ X struct part_entry *pe; X int i; X X pe = (struct part_entry *)&secbuf[TABLEOFFSET]; X printf("\n --first--- ---last---\n"); X printf("Prt ac hd sec cyl sys hd sec cyl low size\n"); X for (i = 1 ; i < 5 ; i++) { X printf(" %x %2x %x %2x %2x %2x %x %2x %2x %6D %9D\n", X i, X pe->bootind & 0xff, X pe->start_head & 0xff, X pe->start_sec & 0xff, X pe->start_cyl & 0xff, X pe->sysind & 0xff, X pe->last_head & 0xff, X pe->last_sec & 0xff, X pe->last_cyl & 0xff, X pe->lowsec, X pe->size); X pe++; X } X} X/* X * Display partition table X */ X Xdpl_partitions() X{ X struct part_entry *pe; X int i; X X printf("\nPartition Type Begin End Active\n"); X pe = (struct part_entry *)&secbuf[TABLEOFFSET]; X for (i = 1 ; i <= 4 ; i++) { X dpl_entry(i,pe); X pe++; X } X} X X/* X * Display an entry X */ X Xdpl_entry(number,entry) Xint number; Xstruct part_entry *entry; X{ X int low_cyl,high_cyl,temp; X char *typestring; X char active; X X if (entry->sysind == 0x01) X typestring = dosstr; X else X typestring = ndosstr; X printf("%5d %s ",number,typestring); X temp = entry->start_sec & 0xc0; X low_cyl = (entry->start_cyl & 0xff) + (temp << 2); X temp = entry->last_sec & 0xc0; X high_cyl = (entry->last_cyl & 0xff) + (temp << 2); X printf("%4d %4d",low_cyl,high_cyl); X if ((entry->bootind & 0xff) == 0x80) X active = 'A'; X else X active = 'N'; X printf(" %c\n",active); X} X X/* X * Check partition table X */ X Xchk_table() X{ X struct part_entry *pe; X int i; X int active; X long limit; X X pe = (struct part_entry *)&secbuf[TABLEOFFSET]; X limit = 0L; X active = 0; X for (i = 1 ; i < 5 ; i++) { X if (pe->size == 0L) X return(OK); X if (pe->lowsec <= limit) { X printf("Overlap between part. %d and %d\n",i,i-1); X return(ERR); X } X limit = pe->lowsec + pe->size - 1L; X if (pe->bootind == 0x80) X active++; X pe++; X } X if (active > 1) { X printf("%d active partitions\n",active); X return(ERR); X } X return(OK); X} X/* X * Check entry X * head/sector/track info must match logical sector number X * Used to check 'foreign' partition table during debugging X */ X Xchk_entry(entry) Xstruct part_entry *entry; X{ X char head; X char sector; X char track; X X sec_to_hst(entry->lowsec,&head,§or,&track); X if ( (head != entry->start_head) || X (sector != entry->start_sec) || X (track != entry->start_cyl)) X return(ERR); X sec_to_hst(entry->lowsec + entry->size - 1L,&head,§or,&track); X if ( (head != entry->last_head) || X (sector != entry->last_sec) || X (track != entry->last_cyl)) X return(ERR); X return(OK); X} X X/* X * Convert a logical sector number to X * head / sector / track X */ X Xsec_to_hst(logsec,hd,sec,cyl) Xlong logsec; Xchar *hd,*sec,*cyl; X{ X int bigcyl; X X bigcyl = logsec / (NHEAD * NSEC); X *sec = (logsec % NSEC) + 1 + ((bigcyl >> 2) & 0xc0); X *cyl = bigcyl & 0xff; X *hd = (logsec % (NHEAD * NSEC)) / NSEC; X} X X/* X * change partition table X */ X Xchange_table() X{ X struct part_entry *pe; X int i,temp,low_cyl,high_cyl; X char ch; X X pe = (struct part_entry *)&secbuf[TABLEOFFSET]; X for (i = 1 ; i <= 4 ; i++) { X temp = pe->start_sec & 0xc0; X low_cyl = (pe->start_cyl & 0xff) + (temp << 2); X temp = pe->last_sec & 0xc0; X high_cyl = (pe->last_cyl & 0xff) + (temp << 2); X printf("Partition %d from %d to %d. Change? (y/n) ", X i,low_cyl,high_cyl); X ch = get_a_char(); X if (ch == 'y' || ch == 'Y') X get_partition(pe); X pe++; X } X putchar('\n'); X} X X/* X * Get partition info : first & last cylinder X */ X Xget_partition(entry) Xstruct part_entry *entry; X{ X char buf[80]; X int first,last; X long low,high; X char ch; X X printf(" Enter first cylinder: "); X gets(buf); X sscanf(buf,"%d",&first); X printf(" Enter last cylinder: "); X gets(buf); X sscanf(buf,"%d",&last);; X if (first == 0 && last == 0) { X entry->bootind = 0; X entry->start_head = 0; X entry->start_sec = 0; X entry->start_cyl = 0; X entry->sysind = 0; X entry->last_head = 0; X entry->last_sec = 0; X entry->last_cyl = 0; X entry->lowsec = 0L; X entry->size = 0L ; X return; X } X low = first & 0xffff; X low = low * NSEC * NHEAD; X if (low == 0) X low = 1; /* sec0 is master boot record */ X high = last & 0xffff; X high = (high + 1)*NSEC*NHEAD - 1; X entry->lowsec = low; X entry->size = high - low + 1; X sec_to_hst(low, X &entry->start_head, X &entry->start_sec, X &entry->start_cyl); X sec_to_hst(high, X &entry->last_head, X &entry->last_sec, X &entry->last_cyl); X printf(" DOS partition? (y/n) "); X ch = get_a_char(); X if (ch == 'y' || ch == 'Y') X entry->sysind = 1; X else X entry->sysind = 0; X printf(" Active partition? (y/n) "); X ch = get_a_char(); X if (ch == 'y' || ch == 'Y') X entry->bootind = 0x80; X else X entry->bootind = 0; X} X X/* X * Read 1 character and discard rest of line X */ X Xget_a_char() X{ X char ch; X X ch = getchar(); X if (ch != '\n') X while (getchar() != '\n'); X return(ch); X} X Xprint_menu() X{ X printf("\nType a command letter, then a carriage return:\n"); X printf(" c - change a partition\n"); X printf(" w - write changed partition table back to disk and exit\n"); X printf(" q - quit without making any changes\n"); X printf(" s - save boot block (including partition table) on a file\n"); X printf(" l - load boot block (including partition table) from a file\n"); X printf(" p - print partition table\n\n"); X} + END-OF-FILE commands/fdisk.c chmod u=rw,g=r,o=r commands/fdisk.c set `sum commands/fdisk.c` sum=$1 case $sum in 25274) :;; *) echo 'Bad sum in 'commands/fdisk.c >&2 esac exit 0