rose@uw-june (Scott Rose) (06/09/85)
Below is a quick and dirty yet-another-version of touch and of chmod for the IBM-PC MS-DOS 2.X. Must be compiled with MicroSoft 3.0 C compiler. Shar format. ---Cut me!---Here!--- #!/bin/sh cat >README <<'------ EOF ------' This distribution contains a hastily slapped together 'touch' and an even hastier 'chmod' function for the IBM-PC running DOS 2.X. Both are designed to be compiled with the Microsoft C Compiler 3.0. 'touch' is an attempt to match the action of the Unix 'touch' command as closely as possible (as opposed to an attempt to define a touch with reasonable semantics). Thus, touching a non-existant file causes it to be created, when possible. Non-expandable wildcard characters cause immediate termination of execution, regardless whether other file specs in the file list are valid, just as if the shell had found a problem and reported it. The faulty semantics of the DOS '?' wildcard are reflected in the execution of this program because of the cheap and easy manner in which the expansion is implemented. 'chmod' is a limited command to change the mode of its arguments to read/write or read-only, the only supported modes in MS-DOS. So sloppy is my work here that, although I hear that DOS 3.0 provides such a command, I didn't bother to walk down the hall to check it out. Ah, the perils of public domain. To compile either file, type cl -c x.c cl -o x x.obj ssetargv.obj where x is either 'chmod' or 'touch'. Ssetargv is required to expand the wildcard characters. Note that I have followed the suggested Microsoft conventions for which files to place in the 'sys' subdirectory of the 'include' subdirectory. Scott Rose (rose@uw-bluechip.arpa) Department of Computer Science University of Washington Seattle, Washington ------ EOF ------ ls -l README cat >chmod.c <<'------ EOF ------' /* * Chmod.c * * Change the protection mode of the argument files to read-only or * read/write. * * Designed for use with the Microsoft 3.00 C Compiler for MS-DOS 2.X. * To effect wildcard expansion, link with the file SSETARGV.OBJ. * * Hastily authored by Scott Rose at the University of Washington. * Public domain. * */ #include <stdio.h> #include <sys/types.h> #include <sys/stat.h> main(argc, argv) int argc; char *argv[]; { int tmp; int index; if(argc < 3) { fprintf(stderr, "usage: chmod r|w <file-list>\n"); exit(-1); } if(*argv[1] == 'w') tmp = S_IREAD | S_IWRITE; else if(*argv[1] == 'r') tmp = S_IREAD; else { fprintf(stderr, "chmod: invalid mode spec.\n"); exit(-1); } for(index = 2; index < argc; index++) if(CheckArg(argv[index])) { fprintf(stderr, "No match.\n"); exit(-1); } for(index = 2; index < argc; index++) if(chmod(argv[index], tmp)) fprintf(stderr, "chmod: file %s not found.\n", argv[index]); } /* end chmod */ /* * CheckArg * * Scan the argument filename for wildcard characters. * */ static CheckArg(name) char *name; { register char c; while(c = *name++) if(c == '?' || c == '*') return(-1); return(0); } /* end CheckArg */ ------ EOF ------ ls -l chmod.c cat >touch.c <<'------ EOF ------' /* * Touch.c * * Mimics the Unix TOUCH command. Designed for the Microsoft C Compiler * for MS-DOS, version 3.00. * * Touch updates the modify time of the files that match its arguments. * Filenames are expanded. Nonexistant arguments are created with a file * size of zero; failure of any wildcard spec cancels the entire * operation (which semantics are purely for consistency with the Unix * version of the command). * * This code is designed to be compiled with the small model. The file * SSETARGV.OBJ must be linked in in order to replace the standard * command line argument handling with that which expands wildcard * characters automatically. * * Authored by Scott Rose and Randy Day, University of Washington * Computer Science. Public domain for eternity. * */ #include <stdio.h> #include <sys\types.h> #include <sys\utime.h> #include <sys\timeb.h> #include <sys\stat.h> static struct utimbuf Time; /* * main * * Main execution control. * */ main(argc, argv) int argc; char *argv[]; { int index; if(argc == 1) /* no arguments */ { fprintf(stderr, "usage: touch <file-list>\n"); exit(-1); } /* Check for residual wildcard characters. * The XSETARGV routines, at variance with the Unix shell filename * expansion semantics, pass filename arguments with unmatched wildcard * characters to the caller, unmodified. Rather than attempt to use * such bogus filenames, they are detected and the operation aborted, * just as if detected by a shell. */ for(index = 1; index < argc; index++) if(CheckArg(argv[index])) { fprintf(stderr, "No match.\n"); exit(-1); } FreezeTime(&Time); for(index = 1; index < argc; index++) Touch(argv[index]); exit(0); } /* end main */ /* * Touch * * Update the modify time of the specified file, creating it if * necessary. * */ static Touch(name) char *name; { if(access(name, 2)) /* check write privilege */ { if(access(name, 0)) /* check existence, creat if possible */ { int tmp; if((tmp = creat(name, S_IWRITE)) == -1) { fprintf(stderr, "touch: unable to create %s.\n", name); return(-1); } close(tmp); } else /* no write privilege */ { fprintf(stderr, "touch: no write privilege for %s.\n", name); return(-1); } } return(utime(name, &Time)); } /* end Touch */ /* * FreezeTime * * Record the current time in the static global struct Time. * */ static FreezeTime(uTimeBuf) struct utimbuf *uTimeBuf; { struct timeb timeBuf; ftime(&timeBuf); Time.modtime = timeBuf.time; } /* end FreezeTime */ /* * CheckArg * * Scan the argument filename for wildcard characters. * */ static CheckArg(name) char *name; { register char c; while(c = *name++) if(c == '?' || c == '*') return(-1); return(0); } /* end CheckArg */ ------ EOF ------ ls -l touch.c