[comp.binaries.ibm.pc] Fix filenames on Unix

W8SDZ@SIMTEL20.ARPA (Keith Petersen) (04/20/88)

If you have ever extracted files from an MSDOS ARC on Unix you know
the frustration of ending up with all those upper case filenames.
This program will correct upper-case filenames to lower in addition to
its stated purpose of handling Tops-20 filenames.  It won't touch
normal filenames on Unix, just those with names that are not normally
used on Unix.  It does a rename function.

--cut-here--xxu.c--cut-here--
/*  X X U  --  20-to-Unix filename converter  */

/*
 Change DEC-20 or VAX/VMS style filenames into normal Unix names.
 Handy for use after ftp MGETs, when you find your directory full of
 files with names like LIB:<KERMIT>CKUFIO.C.2 or FRED::[ETHEL]A.B;37
 when all you really wanted was ckufio.c and a.b.

 Usage: xxu file(s)

 Action: Renames argument files as follows:
   strips Unix path name from front (up to rightmost '/') if present
   strips DEC device:, node:: names from front (up to rightmost ':') if present
   strips DEC-20 <directory> or VMS [directory] name if present
   strips DEC-20 version number from end (everything after 2nd dot) if present
   strips VMS generation number from end (everything after ';') if present
   lowercases any uppercase letters
   honors DEC-20 CTRL-V quote for special characters
   discards unquoted unprintable characters
   if result is null, file is renamed to xxfile-n, where n is a number.
   if result would write over an existing file, file also renamed to xxfile-n.

 Recommended procedure: make a new directory, cd to it, then FTP files
 from DEC-20 or VMS system, then do "xxu *".

 Author:  F. da Cruz, CUCCA, July 85
*/
#include <stdio.h>
#include <ctype.h>
#include <sys/file.h>			/* For access() */

char name[500];				/* File name buffer */
char *pp, *cp, *xp;			/* Character pointers */
char delim;				/* Directory Delimiter */
int dc = 0, n = 0;			/* Counters */
int quote = 0, indir = 0; done = 0;	/* Flags */

main(argc,argv) int argc; char **argv; {

    if (argc < 2) {			/* Give message if no args */
	fprintf(stderr,"Usage: xxu file(s)\n");
	exit(1);
    }
    n = 0;				/* Unfixable filename counter */
    while (--argc > 0) {		/* For all files on command line... */
	argv++;
	xp = *argv;			/* Copy pointer for simplicity */
	printf("%s ",*argv);		/* Echo name of this file */

	pp = name;			/* Point to translation buffer */
	*name = '\0';			/* Initialize buffer */
	dc = 0;				/* Filename dot counter */
	done = 0;			/* Flag for early completion */

	for (cp = xp; (*cp != '\0') && !done; cp++) { /* Loop thru chars... */

	    if (quote) {		/* If this char quoted, */
		*pp++ = *cp;		/*  include it literally. */
		quote = 0;
	    }
	    else if (indir) {		/* If in directory name, */
		if (*cp == delim) indir = 0; /* look for end delimiter. */
	    }
	    else switch (*cp) {
		case '<':		/* Discard DEC-20 directory name */
		    indir = 1;
		    delim = '>';
		    break;
		case '[':		/* Discard VMS directory name */
		    indir = 1;
		    delim = ']';
		    break;
		case '/':		/* Discard Unix path name */
		case ':':   	    	/*  or DEC dev: or node:: name */
		    pp = name; 
		    break;
		case '.':		/* DEC -20 generation number */
	    	    if (++dc == 1)	/* Keep first dot */
		    	*pp++ = *cp;
		    else		/* Discard everything starting */
		    	done = 1;	/* with second dot. */
		    break;
		case ';':		/* VMS generation or DEC-20 attrib */
		    done = 1;		/* Discard everything starting with */
		    break;		/* semicolon */
	    	case '\026':		/* Control-V quote for special chars */
		    quote = 1;		/* Set flag for next time. */
		    break;
		default:
		    if (isupper(*cp))  	/* Uppercase letter to lowercase */
	    	    	*pp++ = tolower(*cp);
		    else if (isprint(*cp)) /* Other printable, just keep */
		    	*pp++ = *cp;
	    }
	}
	*pp = '\0';			/* Done with name, terminate it */
	if (strcmp(name,xp) == 0) {	/* If no renaming necessary, */
	    printf("(ok)\n");		/*  just give message. */
	    continue;
        }
	while (*name == '\0' || access(name,0) == 0) { /* Find unique name */
	    sprintf(name,"xxfile-%d",n++);
	}
	printf("=> %s ",name);		/* Tell what new name will be */
	if (rename(xp,name) == 0)	/* Try to rename it */
	    printf("(ok)\n");		/* Say what happened */
	else
	    perror("failed");
    }
    exit(0);				/* Done. */
}

--Keith Petersen
Arpa: W8SDZ@SIMTEL20.ARPA
Uucp: {decwrl,harvard,lll-crg,ucbvax,uunet,uw-beaver}!simtel20.arpa!w8sdz
GEnie: W8SDZ

joe@tekbspa.UUCP (Joe Angelo) (04/23/88)

in article <KPETERSEN.12391885314.BABYL@SIMTEL20.ARPA>, W8SDZ@SIMTEL20.ARPA (Keith Petersen) says:
> 
> If you have ever extracted files from an MSDOS ARC on Unix you know
> the frustration of ending up with all those upper case filenames.
> This program will correct upper-case filenames to lower in addition to
> its stated purpose of handling Tops-20 filenames.  It won't touch
> normal filenames on Unix, just those with names that are not normally
> used on Unix.  It does a rename function.

And if you don't have a compiler, pipe the output of this to the shell...

	/bin/ls $* >/tmp/XX$$
	tr '[A-Z]' '[a-z]' < /tmp/XX$$ > /tmp/YY$$
	echo 'set -v'
	paste /tmp/XX$$ /tmp/YY$$ | sed 's/^/mv /'
	rm -f /tmp/XX$$ /tmp/YY$$
-- 
"I'm trying             Joe Angelo -- Senior Systems Engineer/Systems Manager
 to think               at Teknekron Software Systems, Palo Alto 415-325-1025
 but nothing
 happens!"              uunet!tekbspa!joe -OR- tekbspa!joe@uunet.uu.net

frotz@drivax.UUCP (Frotz) (04/27/88)

#In article <180@tekbspa.UUCP> joe@tekbspa.UUCP (Joe Angelo) writes:
#	/bin/ls $* >/tmp/XX$$
#	tr '[A-Z]' '[a-z]' < /tmp/XX$$ > /tmp/YY$$
#	echo 'set -v'
#	paste /tmp/XX$$ /tmp/YY$$ | sed 's/^/mv /'
#	rm -f /tmp/XX$$ /tmp/YY$$

# For all you csh hacks:

#
#	lower
#
#	Lowercases all filenames that are uppercased.
#
set progname = `basename $0`
foreach file ($*)
	set newname = `echo $file | tr A-Z a-z`
	if  -f $newname then
		echo ${progname}: Will not overwrite ${newname}.
	else
		echo ${progname}: \[$file\]\	-\> \[$newname\]
		mv $file $newname
	endif
end


# Frotz