enfs1.c ,m# #include "nfs.h" int iflag 0; int xflag 0; struct stk *xsp stack; char *nxt &end; char *last &end; char *terr "snt\0\0"; char *stat1 "f rwxrwxrwx"; char *ng ".\0"; main(argc,argv) int argc; char **argv; { extern fout; int i; int compar(); flush(); fout = 2; sbrk(16); if (argc<2) ex(1); eargv=argv+argc; if((fn = open("/dev/tiu/d1",2)) < 0) { printf("Spider busy\n"); ex(2); } getpw(getuid(),nam); /* get login name */ for(np = nam; *np != ':'; np++); /* find the ':' delimiter */ *np = '\0'; name(nam); /* put login name in buf to send to File Store */ *bp++ = LOGIN; if(sendc(OK))ex(1); argv++; /* interpret command */ if (*argv[0] != '-') { bp = buf; for (; argv != eargv; argv++) { for (tp = *argv; *tp; tp++) { *bp++ = *tp; if (bp == &buf[510]) {printf("too many args\n"); ex(1);} } *bp++ = ' '; } *bp++ = '\n'; ff = 1; rd('r'); qt(0); } /* break out functions and set flags for key args */ for (tp = *argv++ + 1 ; *tp; tp++) switch(*tp) { case 't': case 'l': case 'm': case 'w': case 'u': case 'd': case 'r': case 's': if(op != 0){printf("illegal function\n"); qt(1);} op = *tp; continue; case 'v': vflag++; continue; case 'i': iflag++; continue; case 'x': xflag++; continue; case 'c': /* another directory in File Store is used */ if (argv == eargv) { printf("directory required with 'c' function\n"); qt(1); } np = nam; bp = *argv; while (*np++ = *bp++); name(*argv++); *bp++ = CDIR; if (sendc(OK)) ex(1); argc--; continue; default: printf("illegal function\n"); qt(1); } if (argv == eargv) /* no file is named use current directory */ { argv= &ng; eargv=argv+1;} sp = stack; for (;;) { tp = gen(); if (!tp) /* pick up next arg from cmd line */ { if (argv == eargv) qt(0); tp = *argv++; np = nam; while(*np++ = *tp++); sp[spos] = --np; tp = nam; } fsp = tp; name(fsp); switch(op) { case 'm': if (ask()) break; mdir: *bp++ = UNLESS; *bp++ = DCREATE; *bp++ = FI; goto single; case 'w': case 'u': if (ask()) break; ff = open(tp,0); if (ff<0) goto erf; if (dir()) goto mdir; if(op == 'u') /* test if file has been updated */ { tme[0] = dirbuf[16]; tme[1] = dirbuf[17]; i = gstat(); if (i == 0) { /* file exists */ if(dbcmp(tme,dirbuf->i_modtime) < 0) { close(ff); break;} } else if (i != -1) break; name(fsp); } *bp++ = FCREATE; *bp++ = WRITE; *bp++ = CLOSE; if(sendc(WRITE))break; /* send the command */ sum=0; length=0; do { nchar = read(ff,buf,512); /* sum =+ addup(nchar); length =+ nchar; */ if (nchar==0) code=2; else code=1; if (send(nchar,code) < 0) trouble(); } while(nchar > 0); if(check(OK) < 0) /* error */ { exx(); qt(1); } goto knxt; case 'r': if(xflag ||ask()) break; if(xdir(1)) /* extract a directory */ { /* is it an existing directory */ if(((i = stat(tp,dirbuf)) >= 0))break; if((i = fork()) == 0) execl("/bin/mkdir","mkdir",tp,0); if((i < 0) || ((wait(&i)) < 0) || ((stat(tp,dirbuf)) < 0)) { printf("directory %s cannot be created\n",nam);qt(1); } break; } if((ff = creat(tp,0666)) < 0)goto erf; *bp++ = itype; *bp++ = 0; *bp++ = 0; *bp++ = OPEN; *bp++ = READ; *bp++ = CLOSE; if(rd(op)) /* read data and put in file */ goto cnxt1; /* an error */ knxt: /* bp = buf; *bp++ = 'K'; *bp++ = (sum >> 8); *bp++ = (sum & 0377); *bp++ = (length >> 8); *bp++ = (length & 0377); if(sendc(OK))goto cnxt1; */ cnxt: if(vflag)printf("%c %s\n",op,nam); cnxt1: close(ff); break; case 'd': if (argc < 3) ex(0); xflag = 1; if ((xdir(1) == 1) || (ask())) break; *bp++ = DELETE; single: if((!sendc(OK)) && (vflag)) /* send just a command -no data */ printf("%c %s\n",op,nam); break; case 's': fout = 1; spstat(); /* get status from file store */ fout = 2; break; case 't': case 'l': nxt = &end; i = xdir(0); if ((i == 0) || (i == 2)) { fout = 1; astat(op); fout = 2; break; } if (i > 0) { qsort(&end,(nxt - &end)/14,14,compar); for(tp = &end; tp < nxt; tp =+ 14) { append(tp,sp[spos]);name(fsp); fout = 1; if (op == 't') printf("%s\n",tp); else astat(op); fout = 2; } } break; default: printf("illegal op-code\n"); qt(1); } nxtarg:; } erf: printf("%s : cannot open ",tp); perror(""); printf("\n"); goto nxtarg; } rnfs2.c 1"t# #include "nfs.h" trouble() { snstat(fn,&code,3); printf("timeout\n"); ex(1); } name(p) char *p; { bp = buf; *bp++= ntype; while(*bp++ = *p++); } sendc(c) /* sends command to file store */ char c; { nchar = bp - buf; if (send(nchar,3) < 0) trouble(); if(check(c) == 0)return(0); exx(); return(-1); } check(c) char c; { int r; extern timeout(); signal(14,timeout); alarm(30); if((read(fn,rply,100)) < 0) trouble(); alarm(0); snstat(fn,&r,1); if (r != 3) {printf("Illegal format from file store\n"); ex(1);} if (*rply == c) return(0); return(-1); } send(n,c) char c; int n; { snstat(fn,&c,0); return(write(fn,buf,n)); } /* test for a directory */ dir() { if ((stat(tp,dirbuf) < 0)||((dirbuf[2] & 060000) != 040000)) return(0); sp =+ sz; sp[sff]=ff; return(1); } gen() { up: if(sp != stack) { /* get next entry in the directory */ do { if (read(sp[sff],dirbuf,dsz) < dsz) { close(sp[sff]); sp =- sz; goto up; } } while((dirbuf[0] == 0) || (dirbuf[1] == '.') || (dirbuf[1] == '..')); dirbuf[dsz] = 0; sp[spos] = append(dirbuf+1,sp[sposx]); } else { upx: if(xsp == stack)return(0); /* a list of titles from File Store is being processed */ if(xsp->first == xsp->lst) { xsp--; nxt = xsp->lst; goto upx; } xsp->pos = append(xsp->first,(xsp-1)->pos); xsp->first =+ 14; } return(nam); } append(ps,pd) char *ps,*pd; { if(pd != nam) *pd++ = '/'; /* if at beginning of path name do not want '/' */ while(*pd++ = *ps++); return(--pd); } addup(n) int n; { int k,s; s=0; if (n>0) {for (k=0; ki_modtime); *(np+24)=0; printf("%c %7s %s %s\n",*rply,locv(dirbuf->i_size0,dirbuf->i_size1),np+4,tp); } gstat() /* get status of file or directory in tp */ /* returns form gstat: 0 - file exists; 1 - directory exists; -1 not found; */ { char *p; int t, i; *bp++ = IF; /* if name exists get status - else return */ *bp++ = STATUS; *bp++ = FI; if(send(bp-buf,3) < 0)trouble(); if((check(stype)) < 0) { if((*rply & 0377) == OK)return(-1); /* not found */ exx(); return(-2); } p = &rply[2]; for( i = 0;i < 34; i++) { dirbuf[i] = *p++; dirbuf[i] = (dirbuf[i] << 8) | (*p++ & 0377); } t = rply[1]; p = stat1; bp = rply; while(*bp++ = *p++); /* if a directory mark it */ if (t == dtype) rply[0] = 'd'; else if (t == atype) rply[0] = 'a'; /* set permissions */ for( bp = bp-2; *bp != ' '; bp--) { if((dirbuf->i_mode & 1) == 0) *bp = '-'; dirbuf->i_mode =>> 1; } return((t == dtype) ? 1 : 0); } compar(ap1,ap2) char *ap1,*ap2; { register char *p1,*p2; register int k; int j; p1 = ap1; p2 =ap2; for(k = 0;k<14; k++) if((j = *p1 - *p2++) || *p1++ ==0) return(j); return(0); } rd(op1) char op1; /* read data from spider put on file for 'r' or 'u' and build list for 't' */ { int j, i; extern timeout(); char *ps; if(sendc(READ))return(-1); sum = 0; length = 0; do { signal(14,timeout); alarm(30); if((nchar = read(fn,buf,512)) < 0) trouble(); alarm(0); /* sum =+ addup(nchar); length =+ nchar; */ if (nchar != 0) { if (op1 == 't') { for(i =0; i< nchar; i=+ 16) { if (buf[4] == '.') continue; /* get more space if necessary */ if(nxt >= last){sbrk(512); last =+ 512;} ps = &buf[i+4]; for(j =0; j <12; j++)*nxt++ = *ps++; *nxt++ = 0; *nxt++ = 0; } } else wchar = write(ff,buf,nchar); } snstat(fn,&code,1); } while((nchar != 0)&&(code < 2)); if ((code != 2) && (code != 4)) { printf("Illegal format from file store\n");qt(1); } if(check(OK) < 0) {exx(); return(-1);} return(0); } /* determine if directory. arg true if to put contents on stack. * return -1 if not define, 0 if file, 1 if directory, 2 if xflag and directory. */ xdir(m) int m; /* determine if file or directory in file store */ { char a; int i; i = gstat(); /* get status */ name(fsp); if(i != 1)return(0); /* not a directory */ if (xflag) return(2); xsp++; xsp->first = nxt; /* keep first name in stack */ *bp++ = LIST; /* get list of tiles */ if(rd('t')) {xsp--; return(-1);} if (m) xsp->lst = nxt; /* get end of list */ else xsp--; return(1); } grply() /* routine to return first non-blank character reply */ { char *ip; if(read(0,rply,64) <=0)return(1); ip = rply; while(*ip == ' ')ip++; return(*ip); } spstat() { int i; append(".a",sp[spos]); name(fsp); if (i = gstat()) { if (i != -1) exx(); printf("%s is not an account\n",tp); return; } printf("limit %5s ",locv(dirbuf->i_addr[4],dirbuf->i_addr[5])); dpsub(&dirbuf->i_addr[4],&dirbuf->i_addr[2]); printf("used %5s ",locv(dirbuf->i_addr[4],dirbuf->i_addr[5])); printf("%s\n",tp); } /*trap on alarm*/ timeout() {;} nfs3.c 0"_# #include "nfs.h" int s_nerr 36; char *s_err[] { /* 0 */ "Error 0", /* 1 */ "Not super-user", /* 2 */ "No such file or directory", /* 3 */ "No such process", /* 4 */ "Error 4", /* 5 */ "I/O error", /* 6 */ "No such device or address", /* 7 */ "Arg list too long", /* 8 */ "Exec format error", /* 9 */ "Bad file number", /* 10 */ "No children", /* 11 */ "No more processes", /* 12 */ "Not enough core", /* 13 */ "Permission denied", /* 14 */ "Error 14", /* 15 */ "Block device required", /* 16 */ "Mount device busy", /* 17 */ "File exists", /* 18 */ "Cross-device link", /* 19 */ "No such device", /* 20 */ "Not a directory", /* 21 */ "Is a directory", /* 22 */ "Invalid argument", /* 23 */ "File table overflow", /* 24 */ "Too many open files", /* 25 */ "Not a typewriter", /* 26 */ "Text file busy", /* 27 */ "File too large", /* 28 */ "No space left on device", /* 29 */ "Illegal seek", /* 30 */ "wanted file system not mounted", /* 31 */ "illegal i-number", /* 32 */ "illegal character in name", /* 33 */ "not an account", /* 34 */ "space allocation exhausted", /* 35 */ "device turned off", }; char *f_err[] { /* 100 */ "illegal signal", /* 101 */ "fell off end of message", /* 102 */ "illegal op code", /* 103 */ "illegal arg type", /* 104 */ "illegal w-store addr", /* 105 */ "already exists", /* 106 */ "does not exist", /* 107 */ "file ref not open file", /* 108 */ "unknown user", /* 109 */ "failed", /* 110 */ "illegal use of account", /* 111 */ "fstore unavailable", }; int f_nerr 12; exx() { int n; if (*rply != etype) {printf("Illegal format from file store\n"); exit(1);} printf("%s :",nam); n = rply[3]; if ((n < s_nerr) && (n > 0)) printf("%s\n",s_err[n]); else if ((n >= 100) && (n < (100+f_nerr))) printf("%s\n",f_err[n-100]); else printf("error %d\n",n); } enfs.hr" #define snchan 0 /*Spider channel to file system*/ #define sff 0 #define spos 1 #define sposx -1 #define sz 2 #define dsz 16 /*directory entry size*/ int vflag; /* flag for key arguments */ int iflag; int xflag; int tme[2]; /* modified time of file */ char buf[512]; char rply [128]; char nam[100]; int stack[45]; struct stk /* stack for extracting or deleting directory */ { char *first; /* pointer to first title for direct. */ char *pos; char *lst; /* pter to last \*/ }; struct stk *xsp; int dirbuf[40]; struct istat { int i_dev; int i_number; int i_mode; char i_nlink; char i_uid; char i_state; char i_size0; char *i_size1; char i_seq; char i_vol; int i_accnt[2]; int i_perm[3]; int i_addr[8]; int i_spare[8]; int i_dmp[2]; int i_actime[2]; int i_modtime[2]; }; int nchar; int fn; /*Spider network file id*/ char *terr ; char op /*op code*/; char **eargv; char *np; /*pointer into nam[]*/ char *bp /*pointer into buf[]*/; char *tp /*pointer into *argv[]*/; char *fsp; /* pointer to arg-modified for the filestore */ int *sp; /*pointer into stack[]*/ int ff; /*file being processed*/ int code; /*dev/tiu parameter*/ int wchar; int sum; /*check sum of data bytes*/ int length; /*number of bytes transmitted*/ char *stat1 ; char *ng ; char *nxt ; char *last ; # define ntype 1 /* vtype for name item */ # define wtype 2 /* vtype for w-store reference */ # define etype 4 /* vtype for 2-word error code */ # define rtype 5 /* vtype for file reference */ # define xtype 6 /* default operand */ # define stype 7 /* vtype for status item */ # define dtype 8 /* vtype for directory entry */ # define ftype 9 /* vtype for file entry */ # define iitype 10 /* vtype for 2-word integer entry */ # define itype 11 /* vtype of 1-word integer */ # define ltype 14 /* vtype for skip label */ # define atype 15 /* vtype for account */ # define maxtype 15 /* maximum value of vtype */ /* values of user op codes */ # define OK 128 # define DEFINE 129 # define REDEFINE 130 # define DELETE 131 # define EOM 133 # define XMT 135 # define POP 137 # define CDIR 138 # define OPEN 140 # define CLOSE 141 # define SEEK 142 # define READ 143 # define WRITE 144 # define TRUNCATE 145 # define LOGIN 146 # define QUIT 147 # define LIST 148 # define STATUS 149 # define ASSIGN 154 # define FCREATE 155 # define IF 156 # define FI 157 # define SKIP 158 # define DCREATE 159 # define UNLESS 161 # define opnum 33 /* number of legal op codes */ dpsub.s4 |"/ C library - double length addition / dpsub(x,y) does x =- y .globl _dpsub _dpsub: mov r5,-(sp) mov sp,r5 mov 4(sp),r0 mov 6(sp),r1 sub (r1)+,(r0) sub (r1),2(r0) sbc (r0) mov (sp)+,r5 rts pc dbcmp.s4 |"P/ C library - double length comparison / dbcmp(x,y) returns a value that has the same sign as x - y .globl _dbcmp _dbcmp: mov r5,-(sp) mov sp,r5 mov r2,-(sp) mov 6(sp),r2 mov (r2)+,r0 mov (r2),r1 mov 8(sp),r2 sub (r2)+,r0 sub (r2),r1 sbc r0 tst r0 bne 1f tst r1 beq 1f mov $1,r0 1: mov (sp)+,r2 mov (sp)+,r5 rts pc