From 8dbf4a5bc15ce570d15ceb695f952481af2bb6ef Mon Sep 17 00:00:00 2001 From: Ken Thompson Date: Wed, 10 Jan 1979 15:02:03 -0500 Subject: [PATCH] Research V7 development Work on file usr/src/cmd/makekey.c Work on file usr/src/cmd/mkfs.c Work on file usr/src/cmd/mount.c Work on file usr/src/cmd/mknod.c Work on file usr/src/cmd/mv.c Work on file usr/src/cmd/ncheck.c Work on file usr/src/cmd/newgrp.c Work on file usr/src/cmd/nice.c Co-Authored-By: Dennis Ritchie Synthesized-from: v7 --- usr/src/cmd/makekey.c | 19 ++ usr/src/cmd/mkfs.c | 615 ++++++++++++++++++++++++++++++++++++++++++ usr/src/cmd/mknod.c | 42 +++ usr/src/cmd/mount.c | 65 +++++ usr/src/cmd/mv.c | 297 ++++++++++++++++++++ usr/src/cmd/ncheck.c | 322 ++++++++++++++++++++++ usr/src/cmd/newgrp.c | 55 ++++ usr/src/cmd/nice.c | 26 ++ 8 files changed, 1441 insertions(+) create mode 100644 usr/src/cmd/makekey.c create mode 100644 usr/src/cmd/mkfs.c create mode 100644 usr/src/cmd/mknod.c create mode 100644 usr/src/cmd/mount.c create mode 100644 usr/src/cmd/mv.c create mode 100644 usr/src/cmd/ncheck.c create mode 100644 usr/src/cmd/newgrp.c create mode 100644 usr/src/cmd/nice.c diff --git a/usr/src/cmd/makekey.c b/usr/src/cmd/makekey.c new file mode 100644 index 0000000000..1640e51135 --- /dev/null +++ b/usr/src/cmd/makekey.c @@ -0,0 +1,19 @@ +/* + * You send it 10 bytes. + * It sends you 13 bytes. + * The transformation is expensive to perform + * (a significant part of a second). + */ + +char *crypt(); + +main() +{ + char key[8]; + char salt[2]; + + read(0, key, 8); + read(0, salt, 2); + write(1, crypt(key, salt), 13); + return(0); +} diff --git a/usr/src/cmd/mkfs.c b/usr/src/cmd/mkfs.c new file mode 100644 index 0000000000..cf66b7b5cd --- /dev/null +++ b/usr/src/cmd/mkfs.c @@ -0,0 +1,615 @@ +/* + * Make a file system prototype. + * usage: mkfs filsys proto/size [ m n ] + */ +#define NIPB (BSIZE/sizeof(struct dinode)) +#define NINDIR (BSIZE/sizeof(daddr_t)) +#define NDIRECT (BSIZE/sizeof(struct direct)) +#define LADDR 10 +#define MAXFN 500 +#define itoo(x) (int)((x+15)&07) +#ifndef STANDALONE +#include +#include +#endif +#include +#include +#include +#include +#include +#include +time_t utime; +#ifndef STANDALONE +FILE *fin; +#else +int fin; +#endif +int fsi; +int fso; +char *charp; +char buf[BSIZE]; +union { + struct fblk fb; + char pad1[BSIZE]; +} fbuf; +#ifndef STANDALONE +struct exec head; +#endif +char string[50]; +union { + struct filsys fs; + char pad2[BSIZE]; +} filsys; +char *fsys; +char *proto; +int f_n = MAXFN; +int f_m = 3; +int error; +ino_t ino; +long getnum(); +daddr_t alloc(); + +main(argc, argv) +char *argv[]; +{ + int f, c; + long n; + +#ifndef STANDALONE + time(&utime); + if(argc < 3) { + printf("usage: mkfs filsys proto/size [ m n ]\n"); + exit(1); + } + fsys = argv[1]; + proto = argv[2]; +#else + { + static char protos[60]; + + printf("file sys size: "); + gets(protos); + proto = protos; + } +#endif +#ifdef STANDALONE + { + char fsbuf[100]; + + do { + printf("file system: "); + gets(fsbuf); + fso = open(fsbuf, 1); + fsi = open(fsbuf, 0); + } while (fso < 0 || fsi < 0); + } + fin = NULL; + argc = 0; +#else + fso = creat(fsys, 0666); + if(fso < 0) { + printf("%s: cannot create\n", fsys); + exit(1); + } + fsi = open(fsys, 0); + if(fsi < 0) { + printf("%s: cannot open\n", fsys); + exit(1); + } + fin = fopen(proto, "r"); +#endif + if(fin == NULL) { + n = 0; + for(f=0; c=proto[f]; f++) { + if(c<'0' || c>'9') { + printf("%s: cannot open\n", proto); + exit(1); + } + n = n*10 + (c-'0'); + } + filsys.s_fsize = n; + n = n/25; + if(n <= 0) + n = 1; + if(n > 65500/NIPB) + n = 65500/NIPB; + filsys.s_isize = n + 2; + printf("isize = %D\n", n*NIPB); + charp = "d--777 0 0 $ "; + goto f3; + } + +#ifndef STANDALONE + /* + * get name of boot load program + * and read onto block 0 + */ + + getstr(); + f = open(string, 0); + if(f < 0) { + printf("%s: cannot open init\n", string); + goto f2; + } + read(f, (char *)&head, sizeof head); + if(head.a_magic != A_MAGIC1) { + printf("%s: bad format\n", string); + goto f1; + } + c = head.a_text + head.a_data; + if(c > BSIZE) { + printf("%s: too big\n", string); + goto f1; + } + read(f, buf, c); + wtfs((long)0, buf); + +f1: + close(f); + + /* + * get total disk size + * and inode block size + */ + +f2: + filsys.s_fsize = getnum(); + n = getnum(); + n /= NIPB; + filsys.s_isize = n + 3; + +#endif +f3: + if(argc >= 5) { + f_m = atoi(argv[3]); + f_n = atoi(argv[4]); + if(f_n <= 0 || f_n >= MAXFN) + f_n = MAXFN; + if(f_m <= 0 || f_m > f_n) + f_m = 3; + } + filsys.s_m = f_m; + filsys.s_n = f_n; + printf("m/n = %d %d\n", f_m, f_n); + if(filsys.s_isize >= filsys.s_fsize) { + printf("%ld/%ld: bad ratio\n", filsys.s_fsize, filsys.s_isize-2); + exit(1); + } + filsys.s_tfree = 0; + filsys.s_tinode = 0; + for(c=0; c'7') { + printf("%c/%s: bad octal mode digit\n", c, string); + error = 1; + c = 0; + } + in.i_mode |= (c-'0')<<(15-3*i); + } + in.i_uid = getnum(); + in.i_gid = getnum(); + + /* + * general initialization prior to + * switching on format + */ + + ino++; + in.i_number = ino; + for(i=0; i 0) { + in.i_size += i; + newblk(&dbc, db, &ibc, ib); + } + close(f); + break; + + case IFBLK: + case IFCHR: + /* + * special file + * content is maj/min types + */ + + i = getnum() & 0377; + f = getnum() & 0377; + in.i_un.i_addr[0] = (i<<8) | f; + break; + + case IFDIR: + /* + * directory + * put in extra links + * call recursively until + * name of "$" found + */ + + par->i_nlink++; + in.i_nlink++; + entry(in.i_number, ".", &dbc, db, &ibc, ib); + entry(par->i_number, "..", &dbc, db, &ibc, ib); + in.i_size = 2*sizeof(struct direct); + for(;;) { + getstr(); + if(string[0]=='$' && string[1]=='\0') + break; + entry(ino+1, string, &dbc, db, &ibc, ib); + in.i_size += sizeof(struct direct); + cfile(&in); + } + break; + } + if(dbc != 0) + newblk(&dbc, db, &ibc, ib); + iput(&in, &ibc, ib); +} + +gmode(c, s, m0, m1, m2, m3) +char c, *s; +{ + int i; + + for(i=0; s[i]; i++) + if(c == s[i]) + return((&m0)[i]); + printf("%c/%s: bad mode\n", c, string); + error = 1; + return(0); +} + +long +getnum() +{ + int i, c; + long n; + + getstr(); + n = 0; + i = 0; + for(i=0; c=string[i]; i++) { + if(c<'0' || c>'9') { + printf("%s: bad number\n", string); + error = 1; + return((long)0); + } + n = n*10 + (c-'0'); + } + return(n); +} + +getstr() +{ + int i, c; + +loop: + switch(c=getch()) { + + case ' ': + case '\t': + case '\n': + goto loop; + + case '\0': + printf("EOF\n"); + exit(1); + + case ':': + while(getch() != '\n'); + goto loop; + + } + i = 0; + + do { + string[i++] = c; + c = getch(); + } while(c!=' '&&c!='\t'&&c!='\n'&&c!='\0'); + string[i] = '\0'; +} + +rdfs(bno, bf) +daddr_t bno; +char *bf; +{ + int n; + + lseek(fsi, bno*BSIZE, 0); + n = read(fsi, bf, BSIZE); + if(n != BSIZE) { + printf("read error: %ld\n", bno); + exit(1); + } +} + +wtfs(bno, bf) +daddr_t bno; +char *bf; +{ + int n; + + lseek(fso, bno*BSIZE, 0); + n = write(fso, bf, BSIZE); + if(n != BSIZE) { + printf("write error: %D\n", bno); + exit(1); + } +} + +daddr_t +alloc() +{ + int i; + daddr_t bno; + + filsys.s_tfree--; + bno = filsys.s_free[--filsys.s_nfree]; + if(bno == 0) { + printf("out of free space\n"); + exit(1); + } + if(filsys.s_nfree <= 0) { + rdfs(bno, (char *)&fbuf); + filsys.s_nfree = fbuf.df_nfree; + for(i=0; i= NICFREE) { + fbuf.df_nfree = filsys.s_nfree; + for(i=0; id_ino = inum; + for(i=0; id_name[i] = 0; + for(i=0; id_name[i] = str[i]) == 0) + break; + if(*adbc >= NDIRECT) + newblk(adbc, db, aibc, ib); +} + +newblk(adbc, db, aibc, ib) +int *adbc, *aibc; +char *db; +daddr_t *ib; +{ + int i; + daddr_t bno; + + bno = alloc(); + wtfs(bno, db); + for(i=0; i= NINDIR) { + printf("indirect block full\n"); + error = 1; + *aibc = 0; + } +} + +getch() +{ + +#ifndef STANDALONE + if(charp) +#endif + return(*charp++); +#ifndef STANDALONE + return(getc(fin)); +#endif +} + +bflist() +{ + struct inode in; + daddr_t ib[NINDIR]; + int ibc; + char flg[MAXFN]; + int adr[MAXFN]; + int i, j; + daddr_t f, d; + + for(i=0; i 0; d -= f_n) + for(i=0; i= filsys.s_isize) + if(badblk(f)) { + if(ibc >= NINDIR) { + printf("too many bad blocks\n"); + error = 1; + ibc = 0; + } + ib[ibc] = f; + ibc++; + } else + bfree(f); + } + iput(&in, &ibc, ib); +} + +iput(ip, aibc, ib) +struct inode *ip; +int *aibc; +daddr_t *ib; +{ + struct dinode *dp; + daddr_t d; + int i; + + filsys.s_tinode--; + d = itod(ip->i_number); + if(d >= filsys.s_isize) { + if(error == 0) + printf("ilist too small\n"); + error = 1; + return; + } + rdfs(d, buf); + dp = (struct dinode *)buf; + dp += itoo(ip->i_number); + + dp->di_mode = ip->i_mode; + dp->di_nlink = ip->i_nlink; + dp->di_uid = ip->i_uid; + dp->di_gid = ip->i_gid; + dp->di_size = ip->i_size; + dp->di_atime = utime; + dp->di_mtime = utime; + dp->di_ctime = utime; + + switch(ip->i_mode&IFMT) { + + case IFDIR: + case IFREG: + for(i=0; i<*aibc; i++) { + if(i >= LADDR) + break; + ip->i_un.i_addr[i] = ib[i]; + } + if(*aibc >= LADDR) { + ip->i_un.i_addr[LADDR] = alloc(); + for(i=0; ii_un.i_addr[LADDR], (char *)ib); + } + + case IFBLK: + case IFCHR: + ltol3(dp->di_addr, ip->i_un.i_addr, NADDR); + break; + + default: + printf("bad mode %o\n", ip->i_mode); + exit(1); + } + wtfs(d, buf); +} + +badblk(bno) +daddr_t bno; +{ + + return(0); +} diff --git a/usr/src/cmd/mknod.c b/usr/src/cmd/mknod.c new file mode 100644 index 0000000000..4fccc28a4f --- /dev/null +++ b/usr/src/cmd/mknod.c @@ -0,0 +1,42 @@ +main(argc, argv) +int argc; +char **argv; +{ + int m, a, b; + + if(argc != 5) { + printf("arg count\n"); + goto usage; + } + if(*argv[2] == 'b') + m = 060666; else + if(*argv[2] == 'c') + m = 020666; else + goto usage; + a = number(argv[3]); + if(a < 0) + goto usage; + b = number(argv[4]); + if(b < 0) + goto usage; + if(mknod(argv[1], m, (a<<8)|b) < 0) + perror("mknod"); + exit(0); + +usage: + printf("usage: mknod name b/c major minor\n"); +} + +number(s) +char *s; +{ + int n, c; + + n = 0; + while(c = *s++) { + if(c<'0' || c>'9') + return(-1); + n = n*10 + c-'0'; + } + return(n); +} diff --git a/usr/src/cmd/mount.c b/usr/src/cmd/mount.c new file mode 100644 index 0000000000..6ec1d0088b --- /dev/null +++ b/usr/src/cmd/mount.c @@ -0,0 +1,65 @@ +#include + +#define NMOUNT 16 +#define NAMSIZ 32 + +struct mtab { + char file[NAMSIZ]; + char spec[NAMSIZ]; +} mtab[NMOUNT]; + +main(argc, argv) +char **argv; +{ + register int ro; + register struct mtab *mp; + register char *np; + int mf; + + mf = open("/etc/mtab", 0); + read(mf, (char *)mtab, NMOUNT*2*NAMSIZ); + if (argc==1) { + for (mp = mtab; mp < &mtab[NMOUNT]; mp++) + if (mp->file[0]) + printf("%s on %s\n", mp->spec, mp->file); + exit(0); + } + if(argc < 3) { + fprintf(stderr,"arg count\n"); + exit(1); + } + ro = 0; + if(argc > 3) + ro++; + if(mount(argv[1], argv[2], ro) < 0) { + perror("mount"); + exit(1); + } + np = argv[1]; + while(*np++) + ; + np--; + while(*--np == '/') + *np = '\0'; + while(np > argv[1] && *--np != '/') + ; + if(*np == '/') + np++; + argv[1] = np; + for (mp = mtab; mp < &mtab[NMOUNT]; mp++) { + if (mp->file[0] == 0) { + for (np = mp->spec; np < &mp->spec[NAMSIZ-1];) + if ((*np++ = *argv[1]++) == 0) + argv[1]--; + for (np = mp->file; np < &mp->file[NAMSIZ-1];) + if ((*np++ = *argv[2]++) == 0) + argv[2]--; + mp = &mtab[NMOUNT]; + while ((--mp)->file[0] == 0); + mf = creat("/etc/mtab", 0644); + write(mf, (char *)mtab, (mp-mtab+1)*2*NAMSIZ); + exit(0); + } + } + exit(0); +} diff --git a/usr/src/cmd/mv.c b/usr/src/cmd/mv.c new file mode 100644 index 0000000000..0e2b7017a3 --- /dev/null +++ b/usr/src/cmd/mv.c @@ -0,0 +1,297 @@ +/* + * mv file1 file2 + */ + +#include +#include +#include +#include +#include + +#define DOT "." +#define DOTDOT ".." +#define DELIM '/' +#define SDELIM "/" +#define MAXN 100 +#define MODEBITS 07777 +#define ROOTINO 2 + +char *pname(); +char *sprintf(); +char *dname(); +struct stat s1, s2; + +main(argc, argv) +register char *argv[]; +{ + register i, r; + + if (argc < 3) + goto usage; + if (stat(argv[1], &s1) < 0) { + fprintf(stderr, "mv: cannot access %s\n", argv[1]); + return(1); + } + if ((s1.st_mode & S_IFMT) == S_IFDIR) { + if (argc != 3) + goto usage; + return mvdir(argv[1], argv[2]); + } + setuid(getuid()); + if (argc > 3) + if (stat(argv[argc-1], &s2) < 0 || (s2.st_mode & S_IFMT) != S_IFDIR) + goto usage; + r = 0; + for (i=1; i= 0) { + if ((s2.st_mode & S_IFMT) == S_IFDIR) { + sprintf(buf, "%s/%s", target, dname(source)); + target = buf; + } + if (stat(target, &s2) >= 0) { + if ((s2.st_mode & S_IFMT) == S_IFDIR) { + fprintf(stderr, "mv: %s is a directory\n", target); + return(1); + } + if (s1.st_dev==s2.st_dev && s1.st_ino==s2.st_ino) { + fprintf(stderr, "mv: %s and %s are identical\n", + source, target); + return(1); + } + if (access(target, 2) < 0 && isatty(fileno(stdin))) { + fprintf(stderr, "mv: %s: %o mode ", target, + s2.st_mode & MODEBITS); + i = c = getchar(); + while (c != '\n' && c != EOF) + c = getchar(); + if (i != 'y') + return(1); + } + if (unlink(target) < 0) { + fprintf(stderr, "mv: cannot unlink %s\n", target); + return(1); + } + } + } + if (link(source, target) < 0) { + i = fork(); + if (i == -1) { + fprintf(stderr, "mv: try again\n"); + return(1); + } + if (i == 0) { + execl("/bin/cp", "cp", source, target, 0); + fprintf(stderr, "mv: cannot exec cp\n"); + exit(1); + } + while ((c = wait(&status)) != i && c != -1) + ; + if (status != 0) + return(1); + utime(target, &s1.st_atime); + } + if (unlink(source) < 0) { + fprintf(stderr, "mv: cannot unlink %s\n", source); + return(1); + } + return(0); +} + +mvdir(source, target) +char *source, *target; +{ + register char *p; + register i; + char buf[MAXN]; + + if (stat(target, &s2) >= 0) { + if ((s2.st_mode&S_IFMT) != S_IFDIR) { + fprintf(stderr, "mv: %s exists\n", target); + return(1); + } + if (strlen(target) > MAXN-DIRSIZ-2) { + fprintf(stderr, "mv :target name too long\n"); + return(1); + } + strcpy(buf, target); + target = buf; + strcat(buf, SDELIM); + strcat(buf, dname(source)); + if (stat(target, &s2) >= 0) { + fprintf(stderr, "mv: %s exists\n", buf); + return(1); + } + } + if (strcmp(source, target) == 0) { + fprintf(stderr, "mv: ?? source == target, source exists and target doesnt\n"); + return(1); + } + p = dname(source); + if (!strcmp(p, DOT) || !strcmp(p, DOTDOT) || !strcmp(p, "") || p[strlen(p)-1]=='/') { + fprintf(stderr, "mv: cannot rename %s\n", p); + return(1); + } + if (stat(pname(source), &s1) < 0 || stat(pname(target), &s2) < 0) { + fprintf(stderr, "mv: cannot locate parent\n"); + return(1); + } + if (access(pname(target), 2) < 0) { + fprintf(stderr, "mv: no write access to %s\n", pname(target)); + return(1); + } + if (access(pname(source), 2) < 0) { + fprintf(stderr, "mv: no write access to %s\n", pname(source)); + return(1); + } + if (access(source, 2) < 0) { + fprintf(stderr, "mv: no write access to %s\n", source); + return(1); + } + if (s1.st_dev != s2.st_dev) { + fprintf(stderr, "mv: cannot move directories across devices\n"); + return(1); + } + if (s1.st_ino != s2.st_ino) { + char dst[MAXN+5]; + + if (chkdot(source) || chkdot(target)) { + fprintf(stderr, "mv: Sorry, path names including %s aren't allowed\n", DOTDOT); + return(1); + } + stat(source, &s1); + if (check(pname(target), s1.st_ino)) + return(1); + for (i = 1; i <= NSIG; i++) + signal(i, SIG_IGN); + if (link(source, target) < 0) { + fprintf(stderr, "mv: cannot link %s to %s\n", target, source); + return(1); + } + if (unlink(source) < 0) { + fprintf(stderr, "mv: %s: cannot unlink\n", source); + unlink(target); + return(1); + } + strcat(dst, target); + strcat(dst, "/"); + strcat(dst, DOTDOT); + if (unlink(dst) < 0) { + fprintf(stderr, "mv: %s: cannot unlink\n", dst); + if (link(target, source) >= 0) + unlink(target); + return(1); + } + if (link(pname(target), dst) < 0) { + fprintf(stderr, "mv: cannot link %s to %s\n", + dst, pname(target)); + if (link(pname(source), dst) >= 0) + if (link(target, source) >= 0) + unlink(target); + return(1); + } + return(0); + } + if (link(source, target) < 0) { + fprintf(stderr, "mv: cannot link %s and %s\n", + source, target); + return(1); + } + if (unlink(source) < 0) { + fprintf(stderr, "mv: ?? cannot unlink %s\n", source); + return(1); + } + return(0); +} + +char * +pname(name) +register char *name; +{ + register c; + register char *p, *q; + static char buf[MAXN]; + + p = q = buf; + while (c = *p++ = *name++) + if (c == DELIM) + q = p-1; + if (q == buf && *q == DELIM) + q++; + *q = 0; + return buf[0]? buf : DOT; +} + +char * +dname(name) +register char *name; +{ + register char *p; + + p = name; + while (*p) + if (*p++ == DELIM && *p) + name = p; + return name; +} + +check(spth, dinode) +char *spth; +ino_t dinode; +{ + char nspth[MAXN]; + struct stat sbuf; + + sbuf.st_ino = 0; + + strcpy(nspth, spth); + while (sbuf.st_ino != ROOTINO) { + if (stat(nspth, &sbuf) < 0) { + fprintf(stderr, "mv: cannot access %s\n", nspth); + return(1); + } + if (sbuf.st_ino == dinode) { + fprintf(stderr, "mv: cannot move a directory into itself\n"); + return(1); + } + if (strlen(nspth) > MAXN-2-sizeof(DOTDOT)) { + fprintf(stderr, "mv: name too long\n"); + return(1); + } + strcat(nspth, SDELIM); + strcat(nspth, DOTDOT); + } + return(0); +} + +chkdot(s) +register char *s; +{ + do { + if (strcmp(dname(s), DOTDOT) == 0) + return(1); + s = pname(s); + } while (strcmp(s, DOT) != 0 && strcmp(s, SDELIM) != 0); + return(0); +} diff --git a/usr/src/cmd/ncheck.c b/usr/src/cmd/ncheck.c new file mode 100644 index 0000000000..3bbe4a2db4 --- /dev/null +++ b/usr/src/cmd/ncheck.c @@ -0,0 +1,322 @@ +/* + * ncheck -- obtain file names from reading filesystem + */ + +#define NI 16 +#define NB 100 +#define HSIZE 2503 +#define NDIR (BSIZE/sizeof(struct direct)) + +#include +#include +#include +#include +#include +#include +#include + +struct filsys sblock; +struct dinode itab[INOPB*NI]; +daddr_t iaddr[NADDR]; +ino_t ilist[NB]; +struct htab +{ + ino_t h_ino; + ino_t h_pino; + char h_name[DIRSIZ]; +} htab[HSIZE]; + +int aflg; +int sflg; +int fi; +ino_t ino; +int nhent; +int nxfile; + +int nerror; +daddr_t bmap(); +long atol(); +struct htab *lookup(); + +main(argc, argv) +char *argv[]; +{ + register i; + long n; + + while (--argc) { + argv++; + if (**argv=='-') + switch ((*argv)[1]) { + + case 'a': + aflg++; + continue; + + case 'i': + for(i=0; i= mino) + break; + bread((daddr_t)i, (char *)itab, sizeof(itab)); + for(j=0; j= mino) + break; + ino++; + pass1(&itab[j]); + } + } + ilist[nxfile+1] = 0; + ino = 0; + for(i=2;; i+=NI) { + if(ino >= mino) + break; + bread((daddr_t)i, (char *)itab, sizeof(itab)); + for(j=0; j= mino) + break; + ino++; + pass2(&itab[j]); + } + } + ino = 0; + for(i=2;; i+=NI) { + if(ino >= mino) + break; + bread((daddr_t)i, (char *)itab, sizeof(itab)); + for(j=0; j= mino) + break; + ino++; + pass3(&itab[j]); + } + } +} + +pass1(ip) +register struct dinode *ip; +{ + if((ip->di_mode & IFMT) != IFDIR) { + if (sflg==0 || nxfile>=NB) + return; + if ((ip->di_mode&IFMT)==IFBLK || (ip->di_mode&IFMT)==IFCHR + || ip->di_mode&(ISUID|ISGID)) + ilist[nxfile++] = ino; + return; + } + lookup(ino, 1); +} + +pass2(ip) +register struct dinode *ip; +{ + struct direct dbuf[NDIR]; + long doff; + struct direct *dp; + register i, j; + int k; + struct htab *hp; + daddr_t d; + ino_t kno; + + if((ip->di_mode&IFMT) != IFDIR) + return; + l3tol(iaddr, ip->di_addr, NADDR); + doff = 0; + for(i=0;; i++) { + if(doff >= ip->di_size) + break; + d = bmap(i); + if(d == 0) + break; + bread(d, (char *)dbuf, sizeof(dbuf)); + for(j=0; j= ip->di_size) + break; + doff += sizeof(struct direct); + dp = dbuf+j; + kno = dp->d_ino; + if(kno == 0) + continue; + hp = lookup(kno, 0); + if(hp == 0) + continue; + if(dotname(dp)) + continue; + hp->h_pino = ino; + for(k=0; kh_name[k] = dp->d_name[k]; + } + } +} + +pass3(ip) +register struct dinode *ip; +{ + struct direct dbuf[NDIR]; + long doff; + struct direct *dp; + register i, j; + int k; + daddr_t d; + ino_t kno; + + if((ip->di_mode&IFMT) != IFDIR) + return; + l3tol(iaddr, ip->di_addr, NADDR); + doff = 0; + for(i=0;; i++) { + if(doff >= ip->di_size) + break; + d = bmap(i); + if(d == 0) + break; + bread(d, (char *)dbuf, sizeof(dbuf)); + for(j=0; j= ip->di_size) + break; + doff += sizeof(struct direct); + dp = dbuf+j; + kno = dp->d_ino; + if(kno == 0) + continue; + if(aflg==0 && dotname(dp)) + continue; + if(ilist[0] == 0) + goto pr; + for(k=0; ilist[k] != 0; k++) + if(ilist[k] == kno) + goto pr; + continue; + pr: + printf("%u ", kno); + pname(ino, 0); + printf("/%.14s", dp->d_name); + if (lookup(kno, 0)) + printf("/."); + printf("\n"); + } + } +} + +dotname(dp) +register struct direct *dp; +{ + + if (dp->d_name[0]=='.') + if (dp->d_name[1]==0 || (dp->d_name[1]=='.' && dp->d_name[2]==0)) + return(1); + return(0); +} + +pname(i, lev) +ino_t i; +{ + register struct htab *hp; + + if (i==ROOTINO) + return; + if ((hp = lookup(i, 0)) == 0) { + printf("???"); + return; + } + if (lev > 10) { + printf("..."); + return; + } + pname(hp->h_pino, ++lev); + printf("/%.14s", hp->h_name); +} + +struct htab * +lookup(i, ef) +ino_t i; +{ + register struct htab *hp; + + for (hp = &htab[i%HSIZE]; hp->h_ino;) { + if (hp->h_ino==i) + return(hp); + if (++hp >= &htab[HSIZE]) + hp = htab; + } + if (ef==0) + return(0); + if (++nhent >= HSIZE) { + fprintf(stderr, "ncheck: out of core-- increase HSIZE\n"); + exit(1); + } + hp->h_ino = i; + return(hp); +} + +bread(bno, buf, cnt) +daddr_t bno; +char *buf; +{ + register i; + + lseek(fi, bno*BSIZE, 0); + if (read(fi, buf, cnt) != cnt) { + fprintf(stderr, "ncheck: read error %d\n", bno); + for(i=0; i NINDIR) { + fprintf(stderr, "ncheck: %u - huge directory\n", ino); + return((daddr_t)0); + } + bread(iaddr[NADDR-3], (char *)ibuf, sizeof(ibuf)); + return(ibuf[i]); +} diff --git a/usr/src/cmd/newgrp.c b/usr/src/cmd/newgrp.c new file mode 100644 index 0000000000..af49a5e827 --- /dev/null +++ b/usr/src/cmd/newgrp.c @@ -0,0 +1,55 @@ +#include +#include +#include + +struct group *getgrnam(), *grp; +struct passwd *getpwuid(), *pwd; +char *getpass(), *crypt(); + +main(argc,argv) +int argc; +char **argv; +{ + register i; + if(argc != 2) { + printf("usage: newgrp groupname\n"); + done(); + } + if((grp=getgrnam(argv[1])) == NULL) { + printf("%s: no such group\n", argv[1]); + done(); + } + if((pwd=getpwuid(getuid())) == NULL) { + printf("You do not exist!\n"); + done(); + } + for(i=0;grp->gr_mem[i];i++) + if(strcmp(grp->gr_mem[i], pwd->pw_name) == 0) + break; + if(grp->gr_mem[i] == 0 && strcmp(grp->gr_name,"other")) { + printf("Sorry\n"); + done(); + } + + if(grp->gr_passwd[0] != '\0' && pwd->pw_passwd[0] == '\0') { + if(strcmp(grp->gr_passwd, crypt(getpass("Password:"),grp->gr_passwd)) != 0) { + printf("Sorry\n"); + done(); + } + } + if(setgid(grp->gr_gid) < 0) + perror("setgid"); + done(); +} + +done() +{ + register i; + + setuid(getuid()); + for (i=3; i<15; i++) + close(i); + execl("/bin/sh", "sh", 0); + printf("No shell!\n"); + exit(0); +} diff --git a/usr/src/cmd/nice.c b/usr/src/cmd/nice.c new file mode 100644 index 0000000000..ed22a93cec --- /dev/null +++ b/usr/src/cmd/nice.c @@ -0,0 +1,26 @@ +/* nice */ + +#include + +main(argc, argv) +int argc; +char *argv[]; +{ + int nicarg = 10; + extern errno; + extern char *sys_errlist[]; + + if(argc > 1 && argv[1][0] == '-') { + nicarg = atoi(&argv[1][1]); + argc--; + argv++; + } + if(argc < 2) { + fputs("usage: nice [ -n ] command\n", stderr); + exit(1); + } + nice(nicarg); + execvp(argv[1], &argv[1]); + fprintf(stderr, "%s: %s\n", sys_errlist[errno], argv[1]); + exit(1); +} -- 2.20.1