X-Git-Url: https://git.subgeniuskitty.com/unix-history/.git/blobdiff_plain/772118f531141266f645b764cd411056286d01e1..bc41db65325a39b6a6209a25eeddef8a68e91c77:/usr/src/old/arff/arff.c diff --git a/usr/src/old/arff/arff.c b/usr/src/old/arff/arff.c index b7199f7130..3aca7a5604 100644 --- a/usr/src/old/arff/arff.c +++ b/usr/src/old/arff/arff.c @@ -1,10 +1,25 @@ -static char *sccsid = "@(#)arff.c 4.11 (Berkeley) 82/06/27"; +/* + * Copyright (c) 1980 Regents of the University of California. + * All rights reserved. The Berkeley software License Agreement + * specifies the terms and conditions for redistribution. + */ + +#ifndef lint +char copyright[] = +"@(#) Copyright (c) 1980 Regents of the University of California.\n\ + All rights reserved.\n"; +#endif not lint + +#ifndef lint +static char sccsid[] = "@(#)arff.c 5.6 (Berkeley) %G%"; +#endif not lint #include #include -#include +#include #include #include +#include #define dbprintf printf @@ -20,17 +35,18 @@ struct rt_axent { struct rt_ent { char rt_pad; /* unusued */ - char rt_stat; /* type of entry, or end of seg */ + u_char rt_stat; /* type of entry, or end of seg */ u_short rt_name[3]; /* name, 3 words in rad50 form */ u_short rt_len; /* length of file */ - char rt_chan; /* only used in temporary files */ + u_char rt_chan; /* only used in temporary files */ char rt_job; /* only used in temporary files */ - struct rt_dat rt_date; /* creation date */ + struct rt_dat rt_date; /* creation date */ }; #define RT_TEMP 1 #define RT_NULL 2 #define RT_FILE 4 +#define RT_PFILE (0200|RT_FILE) /* protected file */ #define RT_ESEG 8 #define RT_BLOCK 512 /* block size */ @@ -50,10 +66,11 @@ struct rt_dir { char _dirpad[6]; }; -extern struct rt_dir rt_dir[RT_DIRSIZE]; -extern int rt_entsiz; -extern int floppydes; -extern char *rt_last; +#define rd_numseg rt_axhead.rt_numseg +#define rd_nxtseg rt_axhead.rt_nxtseg +#define rd_lstseg rt_axhead.rt_lstseg +#define rd_entpad rt_axhead.rt_entpad +#define rd_stfile rt_axhead.rt_stfile typedef struct fldope { int startad; @@ -63,19 +80,28 @@ struct rt_ent *rtdope; FLDOPE *lookup(); -#define rt(p) ((struct rt_ent *) p ) -#define Ain1 03100 -#define Ain2 050 -#define flag(c) (flg[('c') - 'a']) +#define rt(p) ((struct rt_ent *) p ) +#define Ain1 03100 +#define Ain2 050 +#define flag(c) (flg[('c') - 'a']) -char *man = "rxtd"; -char zeroes[512]; +char *man = "rxtd"; +char zeroes[512]; extern char *val; extern char table[256]; struct rt_dir rt_dir[RT_DIRSIZE] = { - {4, 0, 1, 0, 14}, - { {0, RT_NULL, {0, 0, 0}, 494, 0}, {0, RT_ESEG} } + { + { 4, 0, 1, 0, 14 }, + { { 0, RT_NULL, { 0, 0, 0 }, 486, 0 }, + { 0, RT_ESEG } } + } +}; + +struct rt_dir rt_nulldir = { + { 0, 0, 0, 0, 0 }, + { { 0, RT_NULL, { 0, 0, 0 }, 0, 0 }, + { 0, RT_ESEG } } }; int rt_entsiz; @@ -86,9 +112,8 @@ int dirdirty; char *rt_last; char *defdev = "/dev/floppy"; -char *opt = "vf"; +char *opt = "vfbcm"; -int signum[] = {SIGHUP, SIGINT, SIGQUIT, 0}; extern long lseek(); int rcmd(), dcmd(), xcmd(), tcmd(); @@ -96,7 +121,6 @@ int (*comfun)(); char flg[26]; char **namv; int namc; -int file; main(argc, argv) char *argv[]; @@ -105,7 +129,6 @@ main(argc, argv) if (argc < 2) usage(); - cp = argv[1]; for (cp = argv[1]; *cp; cp++) switch (*cp) { @@ -113,22 +136,11 @@ main(argc, argv) case 'v': case 'u': case 'w': + case 'b': flg[*cp-'a']++; continue; case 'c': - { -#define SURE "Last chance before clobbering floppy?" - int tty; - char response[128]; - - tty = open("/dev/tty", 2); - write(tty, SURE, sizeof(SURE)); - read(tty, response, sizeof(response)); - if (*response != 'y') - exit(50); - flag(c)++; - close(tty); - } + flag(c)++; dirdirty++; continue; @@ -200,14 +212,7 @@ notfound() fprintf(stderr, "arff: %s not found\n", namv[i]); n++; } - return(n); -} - -mesg(c) -{ - if (flag(v)) - if (c != 'c' || flag(v) > 1) - printf("%c - %s\n", c, file); + return (n); } tcmd() @@ -219,27 +224,27 @@ tcmd() register struct rt_ent *rde; rt_init(); - if (namc == 0) - for (segnum = 0; segnum != -1; - segnum = rt_dir[segnum].rt_axhead.rt_nxtseg - 1) - { - last = rt_last + segnum*2*RT_BLOCK; - for (de = ((char *)&rt_dir[segnum])+10; de <= last; - de += rt_entsiz) - if (rtls(rt(de))) { - nleft = (last-de)/rt_entsiz; -#define ENTRIES "\n%d entries remaining in directory segment %d.\n" - printf(ENTRIES, nleft, segnum+1); - break; - } - } - else + if (namc != 0) { for (i = 0; i < namc; i++) if (dope = lookup(namv[i])) { rde = dope->rtdope; - rtls(rde); + (void) rtls(rde); namv[i] = 0; } + return; + } + for (segnum = 0; segnum != -1; + segnum = rt_dir[segnum].rd_nxtseg - 1) { + last = rt_last + segnum*2*RT_BLOCK; + for (de = ((char *)&rt_dir[segnum])+10; de <= last; + de += rt_entsiz) + if (rtls(rt(de))) { + nleft = (last-de)/rt_entsiz; +#define ENTRIES "\n%d entries remaining in directory segment %d.\n" + printf(ENTRIES, nleft, segnum+1); + break; + } + } } rtls(de) @@ -256,6 +261,7 @@ rtls(de) /* fall thru...*/ case RT_FILE: + case RT_PFILE: if (!flag(v)) { sunrad50(name, de->rt_name); printf("%s\n", name); @@ -275,9 +281,9 @@ rtls(de) break; case RT_ESEG: - return(1); + return (1); } - return(0); + return (0); } xcmd() @@ -288,26 +294,34 @@ xcmd() register int i; rt_init(); - if (namc == 0) { - for (segnum = 0; segnum != -1; - segnum = rt_dir[segnum].rt_axhead.rt_nxtseg-1) - for (last = rt_last+(segnum*2*RT_BLOCK), - de = ((char *)&rt_dir[segnum])+10; de <= last; - de += rt_entsiz) - switch (rt(de)->rt_stat) { - case RT_ESEG: - return; - case RT_TEMP: - case RT_FILE: - sunrad50(name,rt(de)->rt_name); - rtx(name); - case RT_NULL: - ; - } - } else + if (namc != 0) { for (i = 0; i < namc; i++) if (rtx(namv[i]) == 0) namv[i] = 0; + return; + } + for (segnum = 0; segnum != -1; + segnum = rt_dir[segnum].rd_nxtseg-1) + for (last = rt_last+(segnum*2*RT_BLOCK), + de = ((char *)&rt_dir[segnum])+10; de <= last; + de += rt_entsiz) { + switch (rt(de)->rt_stat) { + + case RT_ESEG: + break; /* exit loop and try next segment */ + + case RT_TEMP: + case RT_FILE: + case RT_PFILE: + sunrad50(name,rt(de)->rt_name); + (void) rtx(name); + + case RT_NULL: + default: + continue; + } + break; + } } rtx(name) @@ -322,23 +336,23 @@ rtx(name) if (dope = lookup(name)) { if (flag(v)) - rtls(dope->rtdope); + (void) rtls(dope->rtdope); else printf("x - %s\n",name); if ((file = creat(name, 0666)) < 0) - return(1); + return (1); count = dope->count; startad = dope->startad; for( ; count > 0 ; count -= 512) { - lread(startad, 512, buff); - write(file, buff, 512); + (void) lread(startad, 512, buff); + (void) write(file, buff, 512); startad += 512; } - close(file); - return(0); + (void) close(file); + return (0); } - return(1); + return (1); } rt_init() @@ -353,6 +367,23 @@ rt_init() if (initized) return; initized = 1; + if (flag(c)) { + struct stat sb; + char response[128]; + int tty; + + if (stat(defdev, &sb) >= 0 && (sb.st_mode & S_IFMT) == S_IFREG) + goto ignore; + tty = open("/dev/tty", O_RDWR); +#define SURE "Are you sure you want to clobber the floppy? " + (void) write(tty, SURE, sizeof (SURE)); + (void) read(tty, response, sizeof (response)); + if (*response != 'y') + exit(50); + (void) close(tty); +ignore: + ; + } if (flag(c) || flag(d) || flag(r)) mode = "r+"; else @@ -363,19 +394,38 @@ rt_init() } else floppydes = fileno(temp_floppydes); if (!flag(c)) { - lread(6*RT_BLOCK, 2*RT_BLOCK, (char *)&rt_dir[0]); - dirnum = rt_dir[0].rt_axhead.rt_numseg; + if (lread(6*RT_BLOCK, 2*RT_BLOCK, (char *)&rt_dir[0])) + exit(2); + dirnum = rt_dir[0].rd_numseg; + /* check for blank/uninitialized diskette */ + if (dirnum <= 0) { + fprintf(stderr,"arff: bad directory format\n"); + exit(1); + } if (dirnum > RT_DIRSIZE) { fprintf(stderr,"arff: too many directory segments\n"); exit(1); } for (i = 1; i < dirnum; i++) - lread((6+2*i)*RT_BLOCK, 2*RT_BLOCK, (char *)&rt_dir[i]); - } else + if (lread((6+2*i)*RT_BLOCK, 2*RT_BLOCK, (char *)&rt_dir[i])) + exit(1); + } else { dirnum = 1; + if (flag(b)) { + rt_dir[0].rd_numseg = 31; + rt_dir[0].rd_stfile = 68; + rt_dir[0].rt_ents[0].rt_len = 20480 - 68; + } + } - rt_entsiz = 2*rt_dir[0].rt_axhead.rt_entpad + 14; - rt_entsiz = 14; /* assume rt_entpad = 0 ??? */ + rt_entsiz = 2*rt_dir[0].rd_entpad + 14; + /* + * We assume that the directory entries have no padding. This + * may not be a valid assumption, but there are numerous point + * in the code where it assumes it is an rt_ent structure and + * not an rt_entsiz sized structure. + */ + rt_entsiz = 14; rt_last = ((char *) &rt_dir[0]) + 10 + 1014/rt_entsiz*rt_entsiz; rt_nleft = 0; @@ -396,7 +446,7 @@ lookup(name) char *name; { unsigned short rname[3]; - register char *de, *last; + register char *de; int segnum; register index; @@ -407,29 +457,29 @@ lookup(name) */ rt_init(); for (segnum = 0; segnum != -1; - segnum = rt_dir[segnum].rt_axhead.rt_nxtseg - 1) + segnum = rt_dir[segnum].rd_nxtseg - 1) { index = 0; - last = rt_last + segnum*2*RT_BLOCK; for (de=((char *)&rt_dir[segnum])+10; rt(de)->rt_stat != RT_ESEG; de += rt_entsiz) switch(rt(de)->rt_stat) { case RT_FILE: + case RT_PFILE: case RT_TEMP: if(samename(rname,rt(de)->rt_name)) { result.count = rt(de)->rt_len * 512; result.startad = 512* - (rt_dir[segnum].rt_axhead.rt_stfile + index); + (rt_dir[segnum].rd_stfile + index); result.rtdope = (struct rt_ent *) de; - return(&result); + return (&result); } case RT_NULL: index += rt(de)->rt_len; } } - return((FLDOPE *) 0); + return ((FLDOPE *) 0); } @@ -437,7 +487,7 @@ static samename(a, b) u_short a[], b[]; { - return(*a == *b && a[1] == b[1] && a[2] == b[2] ); + return (*a == *b && a[1] == b[1] && a[2] == b[2] ); } rad50(cp, out) @@ -543,7 +593,6 @@ sunrad50(name, rname) cp[-1] = 0; } -static char *oval = " ABCDEFGHIJKLMNOPQRSTUVWXYZ$.@0123456789"; static char *val = " abcdefghijklmnopqrstuvwxyz$.@0123456789"; static char table[256] = { @@ -583,7 +632,7 @@ trans(logical) sector *= 2; sector += 26 + ((track = (logical/26))-1)*6; sector %= 26; - return((((track*26)+sector) << 7) + bytes); + return ((((track*26)+sector) << 7) + bytes); } lread(startad, count, obuff) @@ -593,17 +642,24 @@ lread(startad, count, obuff) long trans(); extern floppydes; register int size = flag(m) ? 512 : 128; + int error = 0; + extern int errno; rt_init(); while ((count -= size) >= 0) { - lseek(floppydes, flag(m) ? + (void) lseek(floppydes, flag(m) ? (long)startad : trans(startad), 0); - if (read(floppydes, obuff, size) != size) - fprintf(stderr, "arff: read error block %d\n", + if (read(floppydes, obuff, size) != size) { + error = errno; + fprintf(stderr, "arff: read error block %d: ", startad/size); + errno = error; + perror(""); + } obuff += size; startad += size; } + return (error); } lwrite(startad, count, obuff) @@ -616,7 +672,7 @@ lwrite(startad, count, obuff) rt_init(); while ((count -= size) >= 0) { - lseek(floppydes, flag(m) ? + (void) lseek(floppydes, flag(m) ? (long)startad : trans(startad), 0); if (write(floppydes, obuff, size) != size) fprintf(stderr, "arff: write error block %d\n", @@ -645,42 +701,53 @@ rtr(name) struct stat buf; register struct stat *bufp = &buf; int segnum; - register char *last; + char type; if (stat(name, bufp) < 0) { perror(name); - return(-1); + return (-1); } + type = 'a'; if (dope = lookup(name)) { /* can replace, no problem */ de = dope->rtdope; - if (bufp->st_size <= (de->rt_len * 512)) - printf("r - %s\n",name), + if (bufp->st_size <= (de->rt_len * 512)) { + printf("r - %s\n",name); toflop(name, bufp->st_size, dope); - else { - fprintf(stderr, "%s will not fit in currently used file on floppy\n",name); - return(-1); + goto found; + } else { + de = dope->rtdope; + type = 'r'; + de->rt_stat = RT_NULL; + de->rt_name[0] = 0; + de->rt_name[1] = 0; + de->rt_name[2] = 0; + *((u_short *)&(de->rt_date)) = 0; + scrunch(); } - } else { - /* Search for vacant spot */ - for (segnum = 0; segnum != -1; - segnum = rt_dir[segnum].rt_axhead.rt_nxtseg - 1) - { - last = rt_last + segnum*2*RT_BLOCK; - for (de = rt_dir[segnum].rt_ents; - rt(de)->rt_stat != RT_ESEG; de++) - if ((de)->rt_stat == RT_NULL) { - if (bufp->st_size <= (de->rt_len*512)) { - printf("a - %s\n",name), - mkent(de, segnum, bufp,name); - goto found; - } - continue; + } + /* + * Search for vacant spot + */ + for (segnum = 0; segnum != -1; + segnum = rt_dir[segnum].rd_nxtseg - 1) + { + for (de = rt_dir[segnum].rt_ents; + rt(de)->rt_stat != RT_ESEG; de++) + if ((de)->rt_stat == RT_NULL) { + if (bufp->st_size <= (de->rt_len*512)) { + printf("%c - %s\n", type, name), + mkent(de, segnum, bufp,name); + goto found; } - } - printf("%s: no slot for file\n", name); - return (-1); + continue; + } } + if (type == 'r') + printf("%s: no slot for file, file deleted\n",name); + else + printf("%s: no slot for file\n", name); + return (-1); found: if (dope = lookup(name)) { @@ -707,12 +774,54 @@ mkent(de, segnum, bufp, name) if (de->rt_len == count) goto overwrite; if ((char *)rt_curend[segnum] == (rt_last + (segnum*2*RT_BLOCK))) { - /* no entries left on segment */ - if (flag(o)) - goto overwrite; - fprintf(stderr,"Directory segment #%d full on %s\n",segnum+1, - defdev); - exit(1); + /* no entries left on segment, trying adding new segment */ + if (rt_dir[0].rd_numseg > rt_dir[0].rd_lstseg) { + short newseg; + register int i; + int maxseg; + short size; + + newseg = rt_dir[0].rd_lstseg++; + rt_dir[newseg] = rt_nulldir; + rt_dir[newseg].rd_nxtseg = rt_dir[segnum].rd_nxtseg; + rt_dir[segnum].rd_nxtseg = newseg + 1; + rt_dir[newseg].rd_entpad = rt_dir[0].rd_entpad; + rt_dir[newseg].rd_numseg = rt_dir[0].rd_numseg; + size = 0; + maxseg = 0; + for(i = newseg - 1; i >= 0; i--) { + workp = rt_curend[i] - 1; + if (workp->rt_stat != RT_NULL) + continue; + if (workp->rt_len < size) + continue; + size = workp->rt_len; + maxseg = i; + } + size = 0; + for (workp = &rt_dir[maxseg].rt_ents[0]; + workp->rt_stat != RT_ESEG; workp++) { + size += workp->rt_len; + } + workp--; + rt_dir[newseg].rt_ents[0].rt_len = workp->rt_len; + rt_dir[newseg].rd_stfile = + rt_dir[maxseg].rd_stfile + size - workp->rt_len; + workp->rt_len = 0; + rt_curend[newseg] = &rt_dir[newseg].rt_ents[1]; + lwrite(6*RT_BLOCK, 2*RT_BLOCK, (char *)&rt_dir[0]); + if (segnum != 0) + lwrite((6+segnum*2)*RT_BLOCK, 2*RT_BLOCK, + (char *)&rt_dir[segnum]); + lwrite((6+newseg*2)*RT_BLOCK, 2*RT_BLOCK, + (char *)&rt_dir[newseg]); + segnum = newseg; + de = &rt_dir[newseg].rt_ents[0]; + } else { + fprintf(stderr, "All directory segments full on %s\n", + defdev); + exit(1); + } } /* copy directory entries up */ for (workp = rt_curend[segnum]+1; workp > de; workp--) @@ -749,12 +858,12 @@ toflop(name, ocount, dope) exit(1); } for( ; count >= 512; count -= 512) { - read(file, buff, 512); + (void) read(file, buff, 512); lwrite(startad, 512, buff); startad += 512; } - read(file, buff, count); - close(file); + (void) read(file, buff, count); + (void) close(file); if (count <= 0) return; for (n = count; n < 512; n ++) @@ -796,11 +905,11 @@ rtk(name) de->rt_name[0] = 0; de->rt_name[1] = 0; de->rt_name[2] = 0; - * ((u_short *)&(de->rt_date)) = 0; + *((u_short *)&(de->rt_date)) = 0; dirdirty = 1; - return(0); + return (0); } - return(1); + return (1); } scrunch() @@ -809,20 +918,19 @@ scrunch() register segnum; for (segnum = 0; segnum != -1; - segnum = rt_dir[segnum].rt_axhead.rt_nxtseg - 1) { - dirdirty = 0; + segnum = rt_dir[segnum].rd_nxtseg - 1) { for (de = rt_dir[segnum].rt_ents; de <= rt_curend[segnum]; de++) - if (de->rt_stat == RT_NULL && de[1].rt_stat == RT_NULL) { + if (de->rt_stat == RT_NULL && + (de+1)->rt_stat == RT_NULL) { (de+1)->rt_len += de->rt_len; - for (workp = de; workp < rt_curend[segnum]; workp++) + for (workp=de; workp