From b4e2e3550fea46398e1d9071f1128e59f780b9c2 Mon Sep 17 00:00:00 2001 From: Ken Thompson Date: Wed, 10 Jan 1979 15:02:16 -0500 Subject: [PATCH] Research V7 development Work on file usr/src/cmd/od.c Work on file usr/src/cmd/passwd.c Work on file usr/src/cmd/ps.c Work on file usr/src/cmd/ptx.c Work on file usr/src/cmd/pwd.c Work on file usr/src/cmd/quot.c Work on file usr/src/cmd/random.c Work on file usr/src/cmd/rev.c Work on file usr/src/cmd/rm.c Work on file usr/src/cmd/rmdir.c Work on file usr/src/cmd/size.c Work on file usr/src/cmd/sleep.c Co-Authored-By: Dennis Ritchie Synthesized-from: v7 --- usr/src/cmd/od.c | 250 ++++++++++++++++++++ usr/src/cmd/passwd.c | 170 +++++++++++++ usr/src/cmd/ps.c | 400 +++++++++++++++++++++++++++++++ usr/src/cmd/ptx.c | 551 +++++++++++++++++++++++++++++++++++++++++++ usr/src/cmd/pwd.c | 80 +++++++ usr/src/cmd/quot.c | 235 ++++++++++++++++++ usr/src/cmd/random.c | 31 +++ usr/src/cmd/rev.c | 44 ++++ usr/src/cmd/rm.c | 162 +++++++++++++ usr/src/cmd/rmdir.c | 104 ++++++++ usr/src/cmd/size.c | 46 ++++ usr/src/cmd/sleep.c | 21 ++ 12 files changed, 2094 insertions(+) create mode 100644 usr/src/cmd/od.c create mode 100644 usr/src/cmd/passwd.c create mode 100644 usr/src/cmd/ps.c create mode 100644 usr/src/cmd/ptx.c create mode 100644 usr/src/cmd/pwd.c create mode 100644 usr/src/cmd/quot.c create mode 100644 usr/src/cmd/random.c create mode 100644 usr/src/cmd/rev.c create mode 100644 usr/src/cmd/rm.c create mode 100644 usr/src/cmd/rmdir.c create mode 100644 usr/src/cmd/size.c create mode 100644 usr/src/cmd/sleep.c diff --git a/usr/src/cmd/od.c b/usr/src/cmd/od.c new file mode 100644 index 0000000000..f0809c9338 --- /dev/null +++ b/usr/src/cmd/od.c @@ -0,0 +1,250 @@ +/* + * od -- octal (also hex, decimal, and character) dump + */ + +#include + +unsigned short word[8]; +unsigned short lastword[8]; +int conv; +int base = 010; +int max; +long addr; + +main(argc, argv) +char **argv; +{ + register char *p; + register n, f, same; + + + argv++; + f = 0; + if(argc > 1) { + p = *argv; + if(*p == '-') { + while(*p != '\0') { + switch(*p++) { + case 'o': + conv |= 001; + f = 6; + break; + case 'd': + conv |= 002; + f = 5; + break; + case 'x': + case 'h': + conv |= 010; + f = 4; + break; + case 'c': + conv |= 020; + f = 7; + break; + case 'b': + conv |= 040; + f = 7; + break; + } + if(f > max) + max = f; + } + argc--; + argv++; + } + } + if(!conv) { + max = 6; + conv = 1; + } + if(argc > 1) + if(**argv != '+') { + if (freopen(*argv, "r", stdin) == NULL) { + printf("cannot open %s\n", *argv); + exit(1); + } + argv++; + argc--; + } + if(argc > 1) + offset(*argv); + + same = -1; + for ( ; (n = fread((char *)word, 1, sizeof(word), stdin)) > 0; addr += n) { + if (same>=0) { + for (f=0; f<8; f++) + if (lastword[f] != word[f]) + goto notsame; + if (same==0) { + printf("*\n"); + same = 1; + } + continue; + } + notsame: + line(addr, word, (n+sizeof(word[0])-1)/sizeof(word[0])); + same = 0; + for (f=0; f<8; f++) + lastword[f] = word[f]; + for (f=0; f<8; f++) + word[f] = 0; + } + putn(addr, base, 7); + putchar('\n'); +} + +line(a, w, n) +long a; +unsigned short *w; +{ + register i, f, c; + + f = 1; + for(c=1; c; c<<=1) { + if((c&conv) == 0) + continue; + if(f) { + putn(a, base, 7); + putchar(' '); + f = 0; + } else + putchar('\t'); + for (i=0; i037 && c<0177) { + printf(" "); + putchar(c); + return; + } + switch(c) { + case '\0': + printf(" \\0"); + break; + case '\b': + printf(" \\b"); + break; + case '\f': + printf(" \\f"); + break; + case '\n': + printf(" \\n"); + break; + case '\r': + printf(" \\r"); + break; + case '\t': + printf(" \\t"); + break; + default: + putn((long)c, 8, 3); + } +} + +putn(n, b, c) +long n; +{ + register d; + + if(!c) + return; + putn(n/b, b, c-1); + d = n%b; + if (d > 9) + putchar(d-10+'a'); + else + putchar(d+'0'); +} + +pre(n) +{ + int i; + + for(i=n; i='0' && d<='9') + a = a*base + d - '0'; + else if (d>='a' && d<='f' && base==16) + a = a*base + d + 10 - 'a'; + else + break; + } + if (*s == '.') + s++; + if(*s=='b' || *s=='B') + a *= 512; + fseek(stdin, a, 0); + addr = a; +} diff --git a/usr/src/cmd/passwd.c b/usr/src/cmd/passwd.c new file mode 100644 index 0000000000..2ecf762f5f --- /dev/null +++ b/usr/src/cmd/passwd.c @@ -0,0 +1,170 @@ +/* + * enter a password in the password file + * this program should be suid with owner + * with an owner with write permission on /etc/passwd + */ +#include +#include +#include + +char passwd[] = "/etc/passwd"; +char temp[] = "/etc/ptmp"; +struct passwd *pwd; +struct passwd *getpwent(); +int endpwent(); +char *strcpy(); +char *crypt(); +char *getpass(); +char *getlogin(); +char *pw; +char pwbuf[10]; +char buf[512]; + +main(argc, argv) +char *argv[]; +{ + char *p; + int i; + char saltc[2]; + long salt; + int u,fi,fo; + int insist; + int ok, flags; + int c; + int pwlen; + FILE *tf; + char *uname; + + insist = 0; + if(argc < 2) { + if ((uname = getlogin()) == NULL) { + printf ("Usage: passwd user\n"); + goto bex; + } else { + printf("Changing password for %s\n", uname); + } + } else { + uname = argv[1]; + } + while(((pwd=getpwent()) != NULL)&&(strcmp(pwd->pw_name,uname)!=0)); + u = getuid(); + if((pwd==NULL) || (u!=0 && u != pwd->pw_uid)) + { + printf("Permission denied.\n"); + goto bex; + } + endpwent(); + if (pwd->pw_passwd[0] && u != 0) { + strcpy(pwbuf, getpass("Old password:")); + pw = crypt(pwbuf, pwd->pw_passwd); + if(strcmp(pw, pwd->pw_passwd) != 0) { + printf("Sorry.\n"); + goto bex; + } + } +tryagn: + strcpy(pwbuf, getpass("New password:")); + pwlen = strlen(pwbuf); + if (pwlen == 0) { + printf("Password unchanged.\n"); + goto bex; + } + ok = 0; + flags = 0; + p = pwbuf; + while(c = *p++){ + if(c>='a' && c<='z') flags |= 2; + else if(c>='A' && c<='Z') flags |= 4; + else if(c>='0' && c<='9') flags |= 1; + else flags |= 8; + } + if(flags >=7 && pwlen>= 4) ok = 1; + if(((flags==2)||(flags==4)) && pwlen>=6) ok = 1; + if(((flags==3)||(flags==5)||(flags==6))&&pwlen>=5) ok = 1; + + if((ok==0) && (insist<2)){ + if(flags==1) + printf("Please use at least one non-numeric character.\n"); + else + printf("Please use a longer password.\n"); + insist++; + goto tryagn; + } + + if (strcmp(pwbuf,getpass("Retype new password:")) != 0) { + printf ("Mismatch - password unchanged.\n"); + goto bex; + } + + time(&salt); + salt += getpid(); + + saltc[0] = salt & 077; + saltc[1] = (salt>>6) & 077; + for(i=0;i<2;i++){ + c = saltc[i] + '.'; + if(c>'9') c += 7; + if(c>'Z') c += 6; + saltc[i] = c; + } + pw = crypt(pwbuf, saltc); + signal(SIGHUP, SIG_IGN); + signal(SIGINT, SIG_IGN); + signal(SIGQUIT, SIG_IGN); + + if(access(temp, 0) >= 0) { + printf("Temporary file busy -- try again\n"); + goto bex; + } + close(creat(temp,0600)); + if((tf=fopen(temp,"w")) == NULL) { + printf("Cannot create temporary file\n"); + goto bex; + } + +/* + * copy passwd to temp, replacing matching lines + * with new password. + */ + + while((pwd=getpwent()) != NULL) { + if(strcmp(pwd->pw_name,uname) == 0) { + u = getuid(); + if(u != 0 && u != pwd->pw_uid) { + printf("Permission denied.\n"); + goto out; + } + pwd->pw_passwd = pw; + } + fprintf(tf,"%s:%s:%d:%d:%s:%s:%s\n", + pwd->pw_name, + pwd->pw_passwd, + pwd->pw_uid, + pwd->pw_gid, + pwd->pw_gecos, + pwd->pw_dir, + pwd->pw_shell); + } + endpwent(); + fclose(tf); + +/* + * copy temp back to passwd file + */ + + if((fi=open(temp,0)) < 0) { + printf("Temp file disappeared!\n"); + goto out; + } + if((fo=creat(passwd, 0644)) < 0) { + printf("Cannot recreat passwd file.\n"); + goto out; + } + while((u=read(fi,buf,sizeof(buf))) > 0) write(fo,buf,u); + +out: + unlink(temp); + +bex: + exit(1); +} diff --git a/usr/src/cmd/ps.c b/usr/src/cmd/ps.c new file mode 100644 index 0000000000..a5e2bb756f --- /dev/null +++ b/usr/src/cmd/ps.c @@ -0,0 +1,400 @@ +/* + * ps - process status + * examine and print certain things about processes + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +struct nlist nl[] = { + { "_proc" }, + { "_swapdev" }, + { "_swplo" }, + { "" }, +}; + +struct proc mproc; + +struct user u; +int chkpid; +int retcode=1; +int lflg; +int vflg; +int kflg; +int xflg; +char *tptr; +long lseek(); +char *gettty(); +char *getptr(); +char *strncmp(); +int aflg; +int mem; +int swmem; +int swap; +daddr_t swplo; + +int ndev; +struct devl { + char dname[DIRSIZ]; + dev_t dev; +} devl[256]; + +char *coref; + +main(argc, argv) +char **argv; +{ + int i; + char *ap; + int uid, puid; + + if (argc>1) { + ap = argv[1]; + while (*ap) switch (*ap++) { + + case 'v': + vflg++; + break; + + case 'a': + aflg++; + break; + + case 't': + if(*ap) + tptr = ap; + aflg++; + if (*tptr == '?') + xflg++; + goto bbreak; + + case 'x': + xflg++; + break; + + case '-': + break; + + case 'l': + lflg++; + break; + + case 'k': + kflg++; + break; + + default: + chkpid = atoi(ap-1); + goto bbreak; + break; + } + } + +bbreak: + if(chdir("/dev") < 0) { + fprintf(stderr, "Can't change to /dev\n"); + exit(1); + } + nlist(argc>2? argv[2]:"/unix", nl); + if (nl[0].n_type==0) { + fprintf(stderr, "No namelist\n"); + exit(1); + } + coref = "/dev/mem"; + if(kflg) + coref = "/usr/sys/core"; + if ((mem = open(coref, 0)) < 0) { + fprintf(stderr, "No mem\n"); + exit(1); + } + swmem = open(coref, 0); + /* + * read mem to find swap dev. + */ + lseek(mem, (long)nl[1].n_value, 0); + read(mem, (char *)&nl[1].n_value, sizeof(nl[1].n_value)); + /* + * Find base of swap + */ + lseek(mem, (long)nl[2].n_value, 0); + read(mem, (char *)&swplo, sizeof(swplo)); + /* + * Locate proc table + */ + lseek(mem, (long)nl[0].n_value, 0); + getdev(); + uid = getuid(); + if (lflg) + printf(" F S UID PID PPID CPU PRI NICE ADDR SZ WCHAN TTY TIME CMD\n"); else + if (chkpid==0) printf(" PID TTY TIME CMD\n"); + for (i=0; i + register FILE *df; + struct stat sbuf; + struct direct dbuf; + + if ((df = fopen("/dev", "r")) == NULL) { + fprintf(stderr, "Can't open /dev\n"); + exit(1); + } + ndev = 0; + while (fread((char *)&dbuf, sizeof(dbuf), 1, df) == 1) { + if(dbuf.d_ino == 0) + continue; + if(stat(dbuf.d_name, &sbuf) < 0) + continue; + if ((sbuf.st_mode&S_IFMT) != S_IFCHR) + continue; + strcpy(devl[ndev].dname, dbuf.d_name); + devl[ndev].dev = sbuf.st_rdev; + ndev++; + } + fclose(df); + if ((swap = open("/dev/swap", 0)) < 0) { + fprintf(stderr, "Can't open /dev/swap\n"); + exit(1); + } +} + +long +round(a, b) + long a, b; +{ + long w = ((a+b-1)/b)*b; + + return(w); +} + +struct map { + long b1, e1; long f1; + long b2, e2; long f2; +}; +struct map datmap; +int file; +prcom(puid) +{ + char abuf[512]; + long addr; + register int *ip; + register char *cp, *cp1; + long tm; + int c, nbad; + register char *tp; + long txtsiz, datsiz, stksiz; + int septxt; + int lw=(lflg?35:80); + char **ap; + + if (mproc.p_flag&SLOAD) { + addr = ctob((long)mproc.p_addr); + file = swmem; + } else { + addr = (mproc.p_addr+swplo)<<9; + file = swap; + } + lseek(file, addr, 0); + if (read(file, (char *)&u, sizeof(u)) != sizeof(u)) + return(0); + + /* set up address maps for user pcs */ + txtsiz = ctob(u.u_tsize); + datsiz = ctob(u.u_dsize); + stksiz = ctob(u.u_ssize); + septxt = u.u_sep; + datmap.b1 = (septxt ? 0 : round(txtsiz,TXTRNDSIZ)); + datmap.e1 = datmap.b1+datsiz; + datmap.f1 = ctob(USIZE)+addr; + datmap.b2 = stackbas(stksiz); + datmap.e2 = stacktop(stksiz); + datmap.f2 = ctob(USIZE)+(datmap.e1-datmap.b1)+addr; + + tp = gettty(); + if (tptr && strncmp(tptr, tp, 2)) + return(0); + if (lflg) { + printf("%2o %c%4d", mproc.p_flag, + "0SWRIZT"[mproc.p_stat], puid); + } + printf("%6u", mproc.p_pid); + if (lflg) { + printf("%6u%4d%4d%5d%6o%4d", mproc.p_ppid, mproc.p_cpu&0377, + mproc.p_pri, + mproc.p_nice, + mproc.p_addr, (mproc.p_size+7)>>3); + if (mproc.p_wchan) + printf("%7o", mproc.p_wchan); + else + printf(" "); + } + printf(" %-2.2s", tp); + if (mproc.p_stat==SZOMB) { + printf(" "); + return(1); + } + tm = (u.u_utime + u.u_stime + 30)/60; + printf(" %2ld:", tm/60); + tm %= 60; + printf(tm<10?"0%ld":"%ld", tm); + if (vflg && lflg==0) { /* 0 == old tflg (print long times) */ + tm = (u.u_cstime + 30)/60; + printf(" %2ld:", tm/60); + tm %= 60; + printf(tm<10?"0%ld":"%ld", tm); + tm = (u.u_cutime + 30)/60; + printf(" %2ld:", tm/60); + tm %= 60; + printf(tm<10?"0%ld":"%ld", tm); + } + if (mproc.p_pid == 0) { + printf(" swapper"); + return(1); + } + addr += ctob((long)mproc.p_size) - 512; + + /* look for sh special */ + lseek(file, addr+512-sizeof(char **), 0); + if (read(file, (char *)&ap, sizeof(char *)) != sizeof(char *)) + return(1); + if (ap) { + char b[82]; + char *bp = b; + while((cp=getptr(ap++)) && cp && (bp'~') { + if (nbad++>3) + break; + continue; + } + *bp++ = c; + } + *bp++ = ' '; + } + *bp++ = 0; + printf(lflg?" %.30s":" %.60s", b); + return(1); + } + + lseek(file, addr, 0); + if (read(file, abuf, sizeof(abuf)) != sizeof(abuf)) + return(1); + for (ip = (int *)&abuf[512]-2; ip > (int *)abuf; ) { + if (*--ip == -1 || *ip==0) { + cp = (char *)(ip+1); + if (*cp==0) + cp++; + nbad = 0; + for (cp1 = cp; cp1 < &abuf[512]; cp1++) { + c = *cp1&0177; + if (c==0) + *cp1 = ' '; + else if (c < ' ' || c > 0176) { + if (++nbad >= 5) { + *cp1++ = ' '; + break; + } + *cp1 = '?'; + } else if (c=='=') { + *cp1 = 0; + while (cp1>cp && *--cp1!=' ') + *cp1 = 0; + break; + } + } + while (*--cp1==' ') + *cp1 = 0; + printf(lflg?" %.30s":" %.60s", cp); + return(1); + } + } + return(1); +} + +char * +gettty() +{ + register i; + register char *p; + + if (u.u_ttyp==0) + return("?"); + for (i=0; ib1, amap->e1)) { + if(within(adr, amap->b2, amap->e2)) { + saddr = (unsigned)adr + amap->f2 - amap->b2; + } else + return(0); + } else + saddr = (unsigned)adr + amap->f1 - amap->b1; + if(lseek(file, saddr, 0)==-1 + || read(file, &b, 1)<1) { + return(0); + } + return((unsigned)b); +} + + +within(adr,lbd,ubd) +char *adr; +long lbd, ubd; +{ + return((unsigned)adr>=lbd && (unsigned)adr +#include +#include +#define DEFLTX "/usr/lib/eign" +#define TILDE 0177 +#define SORT "/bin/sort" +#define N 30 +#define MAX N*BUFSIZ +#define LMAX 200 +#define MAXT 2048 +#define MASK 03777 +#define SET 1 + +#define isabreak(c) (btable[c]) + +extern char *calloc(), *mktemp(); +extern char *getline(); +int status; + + +char *hasht[MAXT]; +char line[LMAX]; +char btable[128]; +int ignore; +int only; +int llen = 72; +int gap = 3; +int gutter = 3; +int mlen = LMAX; +int wlen; +int rflag; +int halflen; +char *strtbufp, *endbufp; +char *empty = ""; + +char *infile; +FILE *inptr = stdin; + +char *outfile; +FILE *outptr = stdout; + +char *sortfile; /* output of sort program */ +char nofold[] = {'-', 'd', 't', TILDE, 0}; +char fold[] = {'-', 'd', 'f', 't', TILDE, 0}; +char *sortopt = nofold; +FILE *sortptr; + +char *bfile; /*contains user supplied break chars */ +FILE *bptr; + +main(argc,argv) +int argc; +char **argv; +{ + register int c; + register char *bufp; + int pid; + char *pend; + extern onintr(); + + char *xfile; + FILE *xptr; + + if(signal(SIGHUP,onintr)==SIG_IGN) + signal(SIGHUP,SIG_IGN); + if(signal(SIGINT,onintr)==SIG_IGN) + signal(SIGINT,SIG_IGN); + signal(SIGPIPE,onintr); + signal(SIGTERM,onintr); + +/* argument decoding */ + + xfile = DEFLTX; + argv++; + while(argc>1 && **argv == '-') { + switch (*++*argv){ + + case 'r': + rflag++; + break; + case 'f': + sortopt = fold; + break; + + case 'w': + if(argc >= 2) { + argc--; + wlen++; + llen = atoi(*++argv); + if(llen == 0) + diag("Wrong width:",*argv); + if(llen > LMAX) { + llen = LMAX; + msg("Lines truncated to 200 chars.",empty); + } + break; + } + + case 't': + if(wlen == 0) + llen = 100; + break; + case 'g': + if(argc >=2) { + argc--; + gap = gutter = atoi(*++argv); + } + break; + + case 'i': + if(only) + diag("Only file already given.",empty); + if (argc>=2){ + argc--; + ignore++; + xfile = *++argv; + } + break; + + case 'o': + if(ignore) + diag("Ignore file already given",empty); + if (argc>=2){ + only++; + argc--; + xfile = *++argv; + } + break; + + case 'b': + if(argc>=2) { + argc--; + bfile = *++argv; + } + break; + + default: + msg("Illegal argument:",*argv); + } + argc--; + argv++; + } + + if(argc>3) + diag("Too many filenames",empty); + else if(argc==3){ + infile = *argv++; + outfile = *argv; + if((outptr = fopen(outfile,"w")) == NULL) + diag("Cannot open output file:",outfile); + } else if(argc==2) { + infile = *argv; + outfile = 0; + } + + + /* Default breaks of blank, tab and newline */ + btable[' '] = SET; + btable['\t'] = SET; + btable['\n'] = SET; + if(bfile) { + if((bptr = fopen(bfile,"r")) == NULL) + diag("Cannot open break char file",bfile); + + while((c = getc(bptr)) != EOF) + btable[c] = SET; + } + +/* Allocate space for a buffer. If only or ignore file present + read it into buffer. Else read in default ignore file + and put resulting words in buffer. + */ + + + if((strtbufp = calloc(N,BUFSIZ)) == NULL) + diag("Out of memory space",empty); + bufp = strtbufp; + endbufp = strtbufp+MAX; + + if((xptr = fopen(xfile,"r")) == NULL) + diag("Cannot open file",xfile); + + while(bufp < endbufp && (c = getc(xptr)) != EOF) { + if(isabreak(c)) { + if(storeh(hash(strtbufp,bufp),strtbufp)) + diag("Too many words",xfile); + *bufp++ = '\0'; + strtbufp = bufp; + } + else { + *bufp++ = (isupper(c)?tolower(c):c); + } + } + if (bufp >= endbufp) + diag("Too many words in file",xfile); + endbufp = --bufp; + + /* open output file for sorting */ + + sortfile = mktemp("/tmp/ptxsXXXXX"); + if((sortptr = fopen(sortfile, "w")) == NULL) + diag("Cannot open output for sorting:",sortfile); + +/* get a line of data and compare each word for + inclusion or exclusion in the sort phase +*/ + + if (infile!=0 && (inptr = fopen(infile,"r")) == NULL) + diag("Cannot open data: ",infile); + while(pend=getline()) + cmpline(pend); + fclose(sortptr); + + switch (pid = fork()){ + + case -1: /* cannot fork */ + diag("Cannot fork",empty); + + case 0: /* child */ + execl(SORT, SORT, sortopt, "+0", "-1", "+1", + sortfile, "-o", sortfile, 0); + + default: /* parent */ + while(wait(&status) != pid); + } + + + getsort(); + onintr(); +} + +msg(s,arg) +char *s; +char *arg; +{ + fprintf(stderr,"%s %s\n",s,arg); + return; +} +diag(s,arg) +char *s, *arg; +{ + + msg(s,arg); + exit(1); +} + + +char *getline() +{ + + register c; + register char *linep; + char *endlinep; + + + endlinep= line + mlen; + linep = line; + /* Throw away leading white space */ + + while(isspace(c=getc(inptr))) + ; + if(c==EOF) + return(0); + ungetc(c,inptr); + while(( c=getc(inptr)) != EOF) { + switch (c) { + + case '\t': + if(linephalflen-1) + p3b = p3a+halflen-1; + p2a = ltrim(ref,p2b=linep,halflen-1); + if(p2b-p2a>halflen-1) + p2a = p2b-halflen-1; + p1b = rtrim(p1a=p3b+(isspace(p3b[0])!=0),tilde, + w=halflen-(p2b-p2a)-gap); + if(p1b-p1a>w) + p1b = p1a; + p4a = ltrim(ref,p4b=p2a-(isspace(p2a[-1])!=0), + w=halflen-(p3b-p3a)-gap); + if(p4b-p4a>w) + p4a = p4b; + fprintf(outptr,".xx \""); + putout(p1a,p1b); + /* tilde-1 to account for extra space before TILDE */ + if(p1b!=(tilde-1) && p1a!=p1b) + fprintf(outptr,"/"); + fprintf(outptr,"\" \""); + if(p4a==p4b && p2a!=ref && p2a!=p2b) + fprintf(outptr,"/"); + putout(p2a,p2b); + fprintf(outptr,"\" \""); + putout(p3a,p3b); + /* ++p3b to account for extra blank after TILDE */ + /* ++p3b to account for extra space before TILDE */ + if(p1a==p1b && ++p3b!=tilde) + fprintf(outptr,"/"); + fprintf(outptr,"\" \""); + if(p1a==p1b && p4a!=ref && p4a!=p4b) + fprintf(outptr,"/"); + putout(p4a,p4b); + if(rflag) + fprintf(outptr,"\" %s\n",tilde); + else + fprintf(outptr,"\"\n"); + linep = line; + break; + + case '"': + /* put double " for " */ + *linep++ = c; + default: + *linep++ = c; + } + } +} + +char *rtrim(a,c,d) +char *a,*c; +{ + char *b,*x; + b = c; + for(x=a+1; x<=c&&x-a<=d; x++) + if((x==c||isspace(x[0]))&&!isspace(x[-1])) + b = x; + if(b=c&&b-x<=d; x--) + if(!isspace(x[0])&&(x==c||isspace(x[-1]))) + a = x; + if(a>c&&!isspace(a[-1])) + a--; + return(a); +} + +putout(strt,end) +char *strt, *end; +{ + char *cp; + + cp = strt; + + for(cp=strt; cp>2)) & MASK; + return(k); +} + +storeh(num,strtp) +int num; +char *strtp; +{ + int i; + + for(i=num; i +#include +#include +#include + +char dot[] = "."; +char dotdot[] = ".."; +char name[512]; +int file; +int off = -1; +struct stat d, dd; +struct direct dir; + +main() +{ + int rdev, rino; + + stat("/", &d); + rdev = d.st_dev; + rino = d.st_ino; + for (;;) { + stat(dot, &d); + if (d.st_ino==rino && d.st_dev==rdev) + prname(); + if ((file = open(dotdot,0)) < 0) { + fprintf(stderr,"pwd: cannot open ..\n"); + exit(1); + } + fstat(file, &dd); + chdir(dotdot); + if(d.st_dev == dd.st_dev) { + if(d.st_ino == dd.st_ino) + prname(); + do + if (read(file, (char *)&dir, sizeof(dir)) < sizeof(dir)) { + fprintf(stderr,"read error in ..\n"); + exit(1); + } + while (dir.d_ino != d.st_ino); + } + else do { + if(read(file, (char *)&dir, sizeof(dir)) < sizeof(dir)) { + fprintf(stderr,"read error in ..\n"); + exit(1); + } + stat(dir.d_name, &dd); + } while(dd.st_ino != d.st_ino || dd.st_dev != d.st_dev); + close(file); + cat(); + } +} + +prname() +{ + write(1, "/", 1); + if (off<0) + off = 0; + name[off] = '\n'; + write(1, name, off+1); + exit(0); +} + +cat() +{ + register i, j; + + i = -1; + while (dir.d_name[++i] != 0); + if ((off+i+2) > 511) + prname(); + for(j=off+1; j>=0; --j) + name[j+i+1] = name[j]; + off=i+off+1; + name[i] = '/'; + for(--i; i>=0; --i) + name[i] = dir.d_name[i]; +} diff --git a/usr/src/cmd/quot.c b/usr/src/cmd/quot.c new file mode 100644 index 0000000000..984102a8f5 --- /dev/null +++ b/usr/src/cmd/quot.c @@ -0,0 +1,235 @@ +/* + * Disk usage by user + */ + +char *dargv[] = { + "/dev/rrp3", + 0 +}; + +#include +#include +#include +#include +#include +#include +#include + +#define ITABSZ 256 +#define ISIZ (BSIZE/sizeof(struct dinode)) +#define NUID 300 +struct filsys sblock; +struct dinode itab[ITABSZ]; +struct du +{ + long blocks; + long nfiles; + int uid; + char *name; +} du[NUID]; +#define TSIZE 500 +int sizes[TSIZE]; +long overflow; + +int nflg; +int fflg; +int cflg; + +int fi; +unsigned ino; +unsigned nfiles; + +struct passwd *getpwent(); +char *malloc(); +char *copy(); + +main(argc, argv) +char **argv; +{ + register int n; + register struct passwd *lp; + register char **p; + + for(n=0; npw_uid; + if (n>NUID) + continue; + if(du[n].name) + continue; + du[n].name = copy(lp->pw_name); + } + if (argc == 1) { + for (p = dargv; *p;) { + check(*p++); + report(); + } + return(0); + } + while (--argc) { + argv++; + if (argv[0][0]=='-') { + if (argv[0][1]=='n') + nflg++; + else if (argv[0][1]=='f') + fflg++; + else if (argv[0][1]=='c') + cflg++; + } else { + check(*argv); + report(); + } + } + return(0); +} + +check(file) +char *file; +{ + register unsigned i, j; + register c; + + fi = open(file, 0); + if (fi < 0) { + printf("cannot open %s\n", file); + return; + } + printf("%s:\n", file); + sync(); + bread(1, (char *)&sblock, sizeof sblock); + nfiles = (sblock.s_isize-2)*(BSIZE/sizeof(struct dinode)); + ino = 0; + if (nflg) { + if (isdigit(c = getchar())) + ungetc(c, stdin); + else while (c!='\n' && c != EOF) + c = getchar(); + } + for(i=2; inodi_mode&IFMT) == 0) + return; + if (cflg) { + if ((ip->di_mode&IFMT)!=IFDIR && (ip->di_mode&IFMT)!=IFREG) + return; + n = (ip->di_size+BSIZE-1)/BSIZE; + if (n >= TSIZE) { + overflow += n; + n = TSIZE-1; + } + sizes[n]++; + return; + } + if (ip->di_uid >= NUID) + return; + du[ip->di_uid].blocks += (ip->di_size+BSIZE-1)/BSIZE; + du[ip->di_uid].nfiles++; + if (nflg) { + tryagain: + if (fino==0) + if (scanf("%d", &fino)<=0) + return; + if (fino > ino) + return; + if (finodi_uid].name) + printf("%.7s ", np); + else + printf("%d ", ip->di_uid); + while ((n = getchar())==' ' || n=='\t') + ; + putchar(n); + while (n!=EOF && n!='\n') { + n = getchar(); + putchar(n); + } + fino = 0; + } +} + +bread(bno, buf, cnt) +unsigned bno; +char *buf; +{ + + lseek(fi, (long)bno*BSIZE, 0); + if (read(fi, buf, cnt) != cnt) { + printf("read error %u\n", bno); + exit(1); + } +} + +qcmp(p1, p2) +register struct du *p1, *p2; +{ + if (p1->blocks > p2->blocks) + return(-1); + if (p1->blocks < p2->blocks) + return(1); + return(strcmp(p1->name, p2->name)); +} + +report() +{ + register i; + + if (nflg) + return; + if (cflg) { + long t = 0; + for (i=0; i +#define MAXINT 32768. +float fract = 2; +double atof(); +char rflag,eflag,c; +char ibuf[BUFSIZ],obuf[BUFSIZ],line[BUFSIZ]; +main(argc,argv) char **argv; +{ + long tvec; + int i; + for(i=1;i + +/* reverse lines of a file */ + +#define N 256 +char line[N]; +FILE *input; + +main(argc,argv) +char **argv; +{ + register i,c; + input = stdin; + do { + if(argc>1) { + if((input=fopen(argv[1],"r"))==NULL) { + fprintf(stderr,"rev: cannot open %s\n", + argv[1]); + exit(1); + } + } + for(;;){ + for(i=0;i=0) + putc(line[i],stdout); + putc('\n',stdout); + } +eof: + fclose(input); + argc--; + argv++; + } while(argc>1); +} diff --git a/usr/src/cmd/rm.c b/usr/src/cmd/rm.c new file mode 100644 index 0000000000..fcab28cb44 --- /dev/null +++ b/usr/src/cmd/rm.c @@ -0,0 +1,162 @@ +int errcode; + +#include +#include +#include +#include + +char *sprintf(); + +main(argc, argv) +char *argv[]; +{ + register char *arg; + int fflg, iflg, rflg; + + fflg = 0; + if (isatty(0) == 0) + fflg++; + iflg = 0; + rflg = 0; + if(argc>1 && argv[1][0]=='-') { + arg = *++argv; + argc--; + while(*++arg != '\0') + switch(*arg) { + case 'f': + fflg++; + break; + case 'i': + iflg++; + break; + case 'r': + rflg++; + break; + default: + printf("rm: unknown option %s\n", *argv); + exit(1); + } + } + while(--argc > 0) { + if(!strcmp(*++argv, "..")) { + fprintf(stderr, "rm: cannot remove `..'\n"); + continue; + } + rm(*argv, fflg, rflg, iflg, 0); + } + + exit(errcode); +} + +rm(arg, fflg, rflg, iflg, level) +char arg[]; +{ + struct stat buf; + struct direct direct; + char name[100]; + int d; + + if(stat(arg, &buf)) { + if (fflg==0) { + printf("rm: %s nonexistent\n", arg); + ++errcode; + } + return; + } + if ((buf.st_mode&S_IFMT) == S_IFDIR) { + if(rflg) { + if (access(arg, 02) < 0) { + if (fflg==0) + printf("%s not changed\n", arg); + errcode++; + return; + } + if(iflg && level!=0) { + printf("directory %s: ", arg); + if(!yes()) + return; + } + if((d=open(arg, 0)) < 0) { + printf("rm: %s: cannot read\n", arg); + exit(1); + } + while(read(d, (char *)&direct, sizeof(direct)) == sizeof(direct)) { + if(direct.d_ino != 0 && !dotname(direct.d_name)) { + sprintf(name, "%s/%.14s", arg, direct.d_name); + rm(name, fflg, rflg, iflg, level+1); + } + } + close(d); + errcode += rmdir(arg, iflg); + return; + } + printf("rm: %s directory\n", arg); + ++errcode; + return; + } + + if(iflg) { + printf("%s: ", arg); + if(!yes()) + return; + } + else if(!fflg) { + if (access(arg, 02)<0) { + printf("rm: %s %o mode ", arg, buf.st_mode&0777); + if(!yes()) + return; + } + } + if(unlink(arg) && (fflg==0 || iflg)) { + printf("rm: %s not removed\n", arg); + ++errcode; + } +} + +dotname(s) +char *s; +{ + if(s[0] == '.') + if(s[1] == '.') + if(s[2] == '\0') + return(1); + else + return(0); + else if(s[1] == '\0') + return(1); + return(0); +} + +rmdir(f, iflg) +char *f; +{ + int status, i; + + if(dotname(f)) + return(0); + if(iflg) { + printf("%s: ", f); + if(!yes()) + return(0); + } + while((i=fork()) == -1) + sleep(3); + if(i) { + wait(&status); + return(status); + } + execl("/bin/rmdir", "rmdir", f, 0); + execl("/usr/bin/rmdir", "rmdir", f, 0); + printf("rm: can't find rmdir\n"); + exit(1); +} + +yes() +{ + int i, b; + + i = b = getchar(); + while(b != '\n' && b != EOF) + b = getchar(); + return(i == 'y'); +} diff --git a/usr/src/cmd/rmdir.c b/usr/src/cmd/rmdir.c new file mode 100644 index 0000000000..5b896c43ee --- /dev/null +++ b/usr/src/cmd/rmdir.c @@ -0,0 +1,104 @@ +/* + * Remove directory + */ + +#include +#include +#include +#include + +int Errors = 0; +char *rindex(); +char *strcat(); +char *strcpy(); + +main(argc,argv) +int argc; +char **argv; +{ + + if(argc < 2) { + fprintf(stderr, "rmdir: arg count\n"); + exit(1); + } + while(--argc) + rmdir(*++argv); + exit(Errors!=0); +} + +rmdir(d) +char *d; +{ + int fd; + char *np, name[500]; + struct stat st, cst; + struct direct dir; + + strcpy(name, d); + if((np = rindex(name, '/')) == NULL) + np = name; + if(stat(name,&st) < 0) { + fprintf(stderr, "rmdir: %s non-existent\n", name); + ++Errors; + return; + } + if (stat("", &cst) < 0) { + fprintf(stderr, "rmdir: cannot stat \"\""); + ++Errors; + exit(1); + } + if((st.st_mode & S_IFMT) != S_IFDIR) { + fprintf(stderr, "rmdir: %s not a directory\n", name); + ++Errors; + return; + } + if(st.st_ino==cst.st_ino &&st.st_dev==cst.st_dev) { + fprintf(stderr, "rmdir: cannot remove current directory\n"); + ++Errors; + return; + } + if((fd = open(name,0)) < 0) { + fprintf(stderr, "rmdir: %s unreadable\n", name); + ++Errors; + return; + } + while(read(fd, (char *)&dir, sizeof dir) == sizeof dir) { + if(dir.d_ino == 0) continue; + if(!strcmp(dir.d_name, ".") || !strcmp(dir.d_name, "..")) + continue; + fprintf(stderr, "rmdir: %s not empty\n", name); + ++Errors; + close(fd); + return; + } + close(fd); + if(!strcmp(np, ".") || !strcmp(np, "..")) { + fprintf(stderr, "rmdir: cannot remove . or ..\n"); + ++Errors; + return; + } + strcat(name, "/."); + if((access(name, 0)) < 0) { /* name/. non-existent */ + strcat(name, "."); + goto unl; + } + strcat(name, "."); + if((access(name, 0)) < 0) /* name/.. non-existent */ + goto unl2; + if(access(name, 02)) { + name[strlen(name)-3] = '\0'; + fprintf(stderr, "rmdir: %s: no permission\n", name); + ++Errors; + return; + } +unl: + unlink(name); /* unlink name/.. */ +unl2: + name[strlen(name)-1] = '\0'; + unlink(name); /* unlink name/. */ + name[strlen(name)-2] = '\0'; + if (unlink(name) < 0) { + fprintf(stderr, "rmdir: %s not removed\n", name); + ++Errors; + } +} diff --git a/usr/src/cmd/size.c b/usr/src/cmd/size.c new file mode 100644 index 0000000000..7a3d75f303 --- /dev/null +++ b/usr/src/cmd/size.c @@ -0,0 +1,46 @@ +#include +#include + +/* + size -- determine object size + +*/ + +int a_magic[] = {A_MAGIC1,A_MAGIC2,A_MAGIC3,A_MAGIC4,0}; + +main(argc, argv) +char **argv; +{ + struct exec buf; + long sum; + int gorp,i; + FILE *f; + + if (argc==1) { + *argv = "a.out"; + argc++; + --argv; + } + gorp = argc; + while(--argc) { + ++argv; + if ((f = fopen(*argv, "r"))==NULL) { + printf("size: %s not found\n", *argv); + continue; + } + fread((char *)&buf, sizeof(buf), 1, f); + for(i=0;a_magic[i];i++) + if(a_magic[i] == buf.a_magic) break; + if(a_magic[i] == 0) { + printf("size: %s not an object file\n", *argv); + fclose(f); + continue; + } + if (gorp>2) + printf("%s: ", *argv); + printf("%u+%u+%u = ", buf.a_text,buf.a_data,buf.a_bss); + sum = (long) buf.a_text + (long) buf.a_data + (long) buf.a_bss; + printf("%Db = 0%Ob\n", sum, sum); + fclose(f); + } +} diff --git a/usr/src/cmd/sleep.c b/usr/src/cmd/sleep.c new file mode 100644 index 0000000000..a52bc3d3c0 --- /dev/null +++ b/usr/src/cmd/sleep.c @@ -0,0 +1,21 @@ +main(argc, argv) +char **argv; +{ + int c, n; + char *s; + + n = 0; + if(argc < 2) { + printf("arg count\n"); + exit(0); + } + s = argv[1]; + while(c = *s++) { + if(c<'0' || c>'9') { + printf("bad character\n"); + exit(0); + } + n = n*10 + c - '0'; + } + sleep(n); +} -- 2.20.1