[net.sources] rmfile.c, for wierd filenames

CSvax:Pucc-H:Physics:suitti (04/07/83)

/* rmfile, written by Mike Demoney, sometime before June 1982.
 * 	   hacked some more by Stephen Uitti, March 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	*rindex();		/* 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 = rindex(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);
    }
}