spf@clyde.UUCP (03/03/87)
/* Several people have asked for the source to rmfile (though it apparently won't solve the null problem being discussed). Since all requestors were *.xenix folks, and it's small, I'm posting it here... Steve */ /* rmfile, written by Mike Demoney, sometime before June 1982. * hacked some more by Stephen Uitti, March 1983. * cleaned up code for UNIX5.0 John Chmielewski, Apr 1983. * rmfile is public domain, written as a local hack at pur-phy. * Please send updates/comments to * ...pur-ee!physics:suitti or * ...pur-ee!pur-phy!suitti or * * Stephen Uitti * Box 308 * Dept of Physics, Purdue University * W. Lafayette, IN. 47907 * * usage: rmfile * Gasp!, it's interactive!, and runs under UNIX too! * "Gee, I thought that that was against the law, or impossible..." * * Note to super-users: This prog contains no checks for the super-user. * Thus, the super-user can do enormous damage to directories with it. */ static char *Rcsid = "$Header: /src/usrlocal/rmfile.c,v 1.2 83/03/19 13:55:21 suitti Exp $"; /* * $Log: /src/usrlocal/rmfile.c,v $ * Revision 1.2 83/03/19 13:55:21 suitti * Added simple pagenation to listing. * * Revision 1.1 83/03/18 11:23:27 suitti * Initial revision * */ #include <stdio.h> #include <sys/types.h> #include <sys/stat.h> #include <sys/dir.h> #include <signal.h> #define SPC 040 /* a space character */ #define FALSE 0 #define TRUE 1 #define MXCOL 4 /* number of columns across for dir */ #define MXLIN 23 /* number of lines of dir per wait */ #define FIXED 0 /* arg to pfilen */ #define MAXED 1 /* max of 15 chars */ #define VAR 2 /* Variable length printing */ char *strchr(); /* reverse index function */ char *prgnm; /* program name pointer */ long highest = 0; /* highest directory #, set by list() */ int fd; /* file descriptor */ struct direct d_ent; /* directory lookup structure */ char buf[80]; /* input buffer */ main(argc, argv) char **argv; int argc; /* unused, but needed */ { /* point prgnm to program name */ if ((prgnm = strchr(argv[0], '/')) == NULL) prgnm = argv[0]; else prgnm++; if ((fd = open(".",0)) < 0) { /* open "." */ fprintf(stderr,"%s: can't open directory\n", prgnm); exit(1); } list(); while (TRUE) { printf("file #: delete, q: quit, l: list, r: rename: "); if (gets(buf) != NULL) { if (buf[0] > 'A' && buf[0] < 'Z') /* command to lowercase */ buf[0] += 'a' - 'A'; if (buf[0] == 'q') /* quit */ exit(0); else if (buf[0] == 'l') /* list the directory */ list(); else if (buf[0] == 'r') /* rename a file */ ren(); else { /* Delete a file */ if (getfile(buf)) { if (unlink(d_ent.d_name) != 0) fprintf(stderr, "%s: can't unlink file.\n", prgnm); } /* if getfile */ } /* if buf[0] == */ } /* if gets */ } /* while true */ } /* main */ /* list the filenames on the screen */ list() { long fcnt = 0; /* file name numbers */ register int crscnt = 0; /* current column (Up to MXCOL columns) */ register int lincnt = 0; /* current line number, of current screen */ struct stat fsbuf; /* buffer for stat'ed file's modes, etc */ lseek(fd, 0L, 0); while (read(fd,&d_ent,sizeof (struct direct)) == sizeof (struct direct)) { if (d_ent.d_ino != 0) { highest = fcnt; /* highest file # seen yet */ printf("%4d", fcnt); stat(d_ent.d_name, &fsbuf); /* get file modes */ if (fsbuf.st_mode & S_IFDIR) putchar('/'); else if (fsbuf.st_mode & 0111) /* at all executable ? */ putchar('*'); else putchar(SPC); /* Otherwise, space */ if (++crscnt == MXCOL) { /* Terminate a line of the listing */ crscnt = 0; pfilen(d_ent.d_name, MAXED); putchar('\n'); if (++lincnt == MXLIN) { /* pause on EO screen */ lincnt = 0; printf("Type 'return' to continue : "); gets(buf); } } else pfilen(d_ent.d_name, FIXED); } fcnt++; } if (crscnt != 0) /* Terminate the last line of listing */ putchar('\n'); } /* print filename, translating odd chars */ pfilen(buf, ef) register char *buf; int ef; /* 0 = fixed # of cols, space, or * for overflow: FIXED * 1 = max # of cols, space, or * for overflow: MAXED * 2 = var # of cols: VAR */ { char tmp[30]; /* temp filename buffer */ register char *k = tmp; /* tmp pointer */ register i; /* temp char */ register maxcount = 0; /* keep it to 14 chars, please */ while (*buf != '\0' && ++maxcount <= 14) { i = *buf++; i &= 127; /* make 7-bit */ if (i < 32) { *k++ = '^'; /* arrow control chars */ *k++ = i + 64; /* ^@ = null, ^A = control-a (code 1), etc. */ } else if (i == 127) { /* rubout = ^? */ *k++ = '^'; *k++ = '?'; } else { *k++ = i; /* the unmodified char */ } *k = '\0'; } switch (ef) { case FIXED: if (strlen(tmp) > 14) /* '*' means that filename is too wide */ tmp[13] = '*'; printf("%-14.14s", tmp); /* print the filename, fixed length */ break; case MAXED: if (strlen(tmp) > 14) { tmp[13] = '*'; printf("%-14.14s", tmp); /* '*' means that filename is too wide */ } else { printf("%s", tmp); /* print the filename, variable length */ } break; case VAR: printf("%s", tmp); /* print the filename, var length */ break; } } /* rename a file */ rename(oldname, newname) char *oldname; char *newname; { fixname(oldname); fixname(newname); if (link(oldname, newname) != 0) { fprintf(stderr, "%s: Can't link %s\n", prgnm, newname); return; } if (unlink(oldname) != 0) { fprintf(stderr, "%s: Can't unlink old file\n", prgnm); } } fixname(name) /* make sure that it's null terminated */ char *name; { register char *i,j; for (i = name, j = 0; j < 14; j++) if (*i++ == '\0') return; name[14] = '\0'; } ren() /* get number & new name */ { char namebuf[80]; char oname[80]; /* old filename buffer */ printf("file number: "); if (gets(oname) != NULL) { if (getfile(oname)) { printf("New name: "); if (gets(namebuf) != NULL) rename(oname, namebuf); } } } getfile(buf) /* Get a numeric file name => buf */ char *buf; { char tbuf[80]; /* temp input buffer */ long entry_num; /* input file number */ entry_num = atoi(buf); if (entry_num < 2) { fprintf(stderr, "%s: . and .. are illegal\n", prgnm); return(FALSE); } if (entry_num > highest) { fprintf(stderr, "%s: file not found\n", prgnm); return(FALSE); } lseek(fd, entry_num * sizeof (struct direct), 0); read(fd, &d_ent, sizeof (struct direct)); if (d_ent.d_ino != 0) { putchar('"'); pfilen(d_ent.d_name, VAR); printf("\" (y/n): "); if (gets(tbuf) != NULL && (*tbuf == 'y' || *tbuf == 'Y')) { strncpy(buf, d_ent.d_name, 14); return(TRUE); } else return(FALSE); } }