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