Relay-Version: version B 2.10 5/3/83; site utzoo.UUCP Posting-Version: version B 2.10.2 9/5/84; site umich.UUCP Path: utzoo!watmath!clyde!burl!ulysses!gamma!epsilon!mb2c!umich!doug From: doug@umich.UUCP (Douglas Orr) Newsgroups: net.sources Subject: shell for MS-DOS (part 3 - utilities) Message-ID: <204@umich.UUCP> Date: Sun, 4-Aug-85 14:15:17 EDT Article-I.D.: umich.204 Posted: Sun Aug 4 14:15:17 1985 Date-Received: Tue, 6-Aug-85 12:19:24 EDT Distribution: net Organization: University of Michigan, EECS Dept., Ann Arbor, MI Lines: 538 Here is part 3 of the Unix-like shell for DOS. This part contains some DOS utilities. -Doug {ihnp4,mb2c,pur-ee}!umich!textset!doug doug%textset@umich.csnet # This is a shell archive. # Remove everything above and including the cut line. # Then run the rest of the file through sh. -----cut here-----cut here-----cut here-----cut here----- #!/bin/sh # shar: Shell Archiver # Run the following text with /bin/sh to create: # cp.c # more.c # fgrep.c # This archive created: Sun Aug 4 14:02:56 1985 cat << \SHAR_EOF > cp.c #include #include #include #include #include #define Usage "usage: %s file1 file2\n\tor %s file1 file2 ... [dir|dev:]\n" main( argc, argv ) int argc; char * argv[]; { struct stat statb; int dir; char * dest; char dbuf[256]; static char buf[30*BUFSIZ]; int ifd, ofd; int cnt; int mv; char * pgm; char * ptr; int ident; pgm = argv[0]; if( argc < 3 ) { usage: fprintf( stderr, Usage, pgm, pgm ); exit(1); } /* is this "mv" or "cp"? */ strlwr( pgm ); if( (ptr = strrchr( pgm, '\\' )) == NULL) ptr = pgm; else ++ptr; mv = (strcmp( ptr, "mv.exe" ) == 0) || (strcmp( ptr, "mv" ) == 0); /* is this cp a b, or cp a b c ? */ dest = argv[--argc]; if( (stat( dest, &statb ) == -1 || !((statb.st_mode & S_IFDIR) || (strcmp( dest, "\\" ) == 0))) /* msdos sucks */ && !((strlen(dest) == 2) && (dest[1] == ':')) ) dir = 0; else dir = 1; if( strcmp( dest, "." ) == 0 ) ident = 1; else ident = 0; if( (argc > 2) && !dir ) goto usage; /* * move or copy all of the files on the arg list */ while( --argc ) { ++argv; if( ident ) { /* I hate ms-dos */ if( (ptr = strrchr( *argv, '\\' )) == NULL && (ptr = strrchr( *argv, '/')) == NULL ) { fprintf( stderr, "can't copy %s onto itself\n", *argv ); exit( 1 ); } strcpy( dbuf, ptr+1 ); } else if( dir ) sprintf( dbuf, "%s\\%s", dest, *argv ); else strcpy( dbuf, dest ); if( (ifd = open( *argv, O_RDONLY+O_BINARY )) < 0 ) { perror( pgm ); exit(1); } if( (ofd = open( dbuf, O_WRONLY+O_CREAT+O_TRUNC+O_BINARY, 0666 )) < 0 ) { perror( pgm ); exit(1); } while( (cnt = read( ifd, buf, sizeof(buf) )) > 0 ) { if( (cnt = write( ofd, buf, cnt )) < 0 ) break; } close(ifd); close(ofd); if( cnt < 0 ) { /* I/O error */ perror( pgm ); exit( 1 ); } if( mv ) unlink( *argv ); } exit(0); } SHAR_EOF cat << \SHAR_EOF > more.c #include "gen.h" #include #include #include #include #include #include /* * more: a Unix(tm) like more command for MS-DOS * * by Douglas Orr * Textset Inc. * Ann Arbor, Michigan * * Copyright (c) 1985 Textset. All rights reserved. * * This program may be freely distributed, but not sold for profit. * */ /* * To compile: msc -Ze more.c * * Code in chin must be changed if you go to a large memory model. */ Local char esc = '\033'; Local char ctl_z = '\032'; Local FILE * con = NULL; main( argc, argv ) int argc; char * argv[]; { int fd; struct stat statb; while( --argc ) { if( (*++argv)[0] == '-' ) switch( (*argv)[1] ) { default: fprintf( stderr, "invalid argument %s\n", *argv ); exit(1); } else break; } if( argc == 0 ) { more( NULL, fileno(stdin), 0L); exit( 0 ); } else while( argc-- ) { if( (fd = open( *argv, O_RDONLY+O_BINARY )) < 0 ) fprintf( stderr, "couldn't open %s\n", *argv ); else { statb.st_size = 0; /* just in case fstat fails */ fstat( fd, &statb ); more( *argv, fd, statb.st_size ); close( fd ); } argv++; if( argc ) { printf( "%c[7m Next file: %s %c[0m", esc, *argv, esc ); chin(); printf( "\r%c[K", esc ); } } } Local char buffer[BUFSIZ]; Local int bufp = 0; Local long pos = 0; Local int cnt = 0; Local int eof; initfile() { bufp = pos = cnt = 0; eof = False; } long getline( fd, line, linesize ) int fd; char * line; int linesize; { int linep; bool eol; if( eof ) return( -1 ); for( linep=0; linep < linesize; ) { if( bufp >= cnt ) { pos += cnt; bufp = 0; if( (cnt = read( fd, buffer, sizeof buffer )) == 0 ) { if( linep != 0 ) { eof = True; break; } return( -1 ); } } /* newline signals eol */ if( buffer[bufp] == '\n' ) { bufp++; break; } else if( buffer[bufp] == ctl_z ) { eof = True; break; } else { /* ignore crs */ if( buffer[bufp] != '\r' ) line[linep++] = buffer[bufp]; bufp++; } } line[linep] = '\0'; return( pos + bufp ); } more(fname, fd, size) char * fname; int fd; long size; { int cnt; char buf[80]; long pos; long lineno = 0; initfile(); if( fname ) { printf( "%c[1m More: File <%s> %c[0m\n", esc, fname, esc ); cnt = 1; } else cnt = 0; while( (pos = getline( fd, buf, sizeof(buf)-1 )) >= 0 ) { printf( "%s\n", buf ); lineno++; if( (++cnt % 24) == 0 ) { bool done; if( size ) printf( "%c[7m -More(%ld%%)- %c[0m", esc, ((pos*100)/size), esc ); else printf( "%c[7m -More- %c[0m", esc, esc ); for( done=False; !done; ) { done = True; switch( chin() ) { case ' ': cnt = 0; break; case '\r': case '\n': cnt--; break; case 'q': printf( "\n" ); exit(0); case 'v': sprintf( buf, "v %s", fname ); system( buf ); cnt--; break; case ':': switch( chin() ) { case 'n': printf( "\r%c[K", esc ); return; } default: done = False; break; } } printf( "\r%c[K", esc ); } } } /* * !! Today's mystery: I have tried every way that I can think of * to open con: in binary mode, using uSoft routines, and I just * can't get it. I open with the right flags, using open or fopen, * and the file descriptor comes up as non-binary when polled via * ioctl. Even "setmode" doesn't work. What gives? * * the result is what follows: * */ chin() { Local int confd = -1; union REGS regs; char far * buf; /* need -Ze to compile */ char buffer[1]; if( confd < 0 ) { if( (confd = open("con", O_RDONLY)) < 0 ) { fprintf( stderr, "couldn't open con:\n" ); exit(1); } /* get the current ioctl bits for con: */ regs.h.ah = 0x44; regs.h.al = 0; regs.x.bx = confd; intdos( ®s, ®s ); /* flip on binary mode */ regs.h.ah = 0x44; regs.h.al = 1; regs.x.bx = confd; regs.x.dx |= 0x20; regs.x.dx &= ~(0x8010); intdos( ®s, ®s ); } /* read seems to be a bit problematical, also */ buf = buffer; regs.h.ah = 0x3f; regs.x.bx = confd; /* !! small model - ds is the current ds */ regs.x.dx = FP_OFF(buf); regs.x.cx = 1; intdos( ®s, ®s ); return( buf[0] ); } SHAR_EOF cat << \SHAR_EOF > fgrep.c #include "gen.h" #include #include Local char esc = '\033'; Local char ctl_z = '\032'; main( argc, argv ) int argc; char * argv[]; { FILE * fd; int rc; char * pattern; while( --argc ) { if( (*++argv)[0] == '-' ) switch( (*argv)[1] ) { default: fprintf( stderr, "invalid argument %s\n", *argv ); exit(1); } else break; } if( argc == 0 ) { fprintf( stderr, "usage: fgrep pattern [file ...]\n" ); exit(1); } pattern = *argv++; argc--; rc = 0; if( argc == 0 ) { rc = fgrep( NULL, pattern, stdin ); exit( 0 ); } else while( argc-- ) { if( (fd = fopen( *argv, "r" )) == NULL ) fprintf( stderr, "couldn't open %s\n", *argv ); else { rc |= fgrep( *argv, pattern, fd ); close( fd ); } argv++; } exit( !rc ); } fgrep( file, pattern, fd ) char * file; char * pattern; FILE * fd; { char line[BUFSIZ]; int rc; rc = 0; while( fgets( line, sizeof(line), fd ) != NULL ) if( rc = match( pattern, line ) ) printf( "%s: %s", (file) ? file : "stdin", line ); return( rc ); } match( pattern, line ) char * pattern; char * line; { /* not a great algorithm */ char * ptr; char * end; int plen = strlen(pattern); int llen = strlen(line); if( plen > llen ) return( 0 ); end = line+(llen-plen); for( ptr=line; ptr < end; ptr++ ) { if( strncmp( pattern, ptr, plen ) == 0 ) return( 1 ); } return( 0 ); } SHAR_EOF # End of shell archive exit 0