rmtodd@uokmax.UUCP (Richard Michael Todd) (12/10/87)
This shar file contains the rest of the stuff needed to compile PD Tar, except for the changes to exit() (As I said, I'll post that tomorrow.) This sharfile contains the revised Makefile to fit MINIX's broken make, the revised doprintf.c, the routines ctime.c and getopt.c, and create.diff, a context diff to apply to create.c in the PD tar distribution *if* you're using the Gwyn directory library. -------------------------- cut here -------------------------------------- #!/bin/sh # Shell archive created with Richard Todd's makeshar on Tue Dec 8 12:40:03 1987 echo x - Makefile sed 's/^X//' >Makefile << 'EOF' X# Makefile for public domain tar program. X# @(#)Makefile 1.29 87/11/06 X X# Berserkeley version X#DEFS = -DBSD42 X#LDFLAGS = X#LIBS = X#LINT = lint X#LINTFLAGS = -abchx X#DEF_AR_FILE = \"/dev/rmt8\" X#DEFBLOCKING = 20 X#O = o X X# USG version X#DEFS = -DUSG X#LDFLAGS = X#LIBS = -lndir X#LINT = lint X#LINTFLAGS = -p X#DEF_AR_FILE = \"/dev/rmt8\" X#DEFBLOCKING = 20 X#O = o X X# UniSoft's Uniplus SVR2 with NFS X#DEFS = -DUSG -DUNIPLUS -DNFS -DSVR2 X#LDFLAGS = X#LIBS = -lndir X#LINT = lint X#LINTFLAGS = -bx X#DEF_AR_FILE = \"/dev/rmt8\" X#DEFBLOCKING = 20 X#O = o X X# MASSCOMP version X#CC = ucb cc X#DEFS = -DBSD42 X#LDFLAGS = X#LIBS = X#LINT = lint X#LINTFLAGS = -bx X#DEF_AR_FILE = \"/dev/rmt0\" X#DEFBLOCKING = 20 X#O = o X X# (yuk) MS-DOS (Microsoft C) version X#MODEL = S X#DEFS = -DNONAMES -A$(MODEL) -nologo X#LDFLAGS = X#LIBS = $(MODEL)dir.lib X#LINT = $(CC) X#LINTFLAGS = -W3 X#DEF_AR_FILE = \"tar.out\" X#DEFBLOCKING = 20 X#O = obj X X# V7 version X# Pick open3 emulation or nonexistence. See open3.h, port.c. X##DEFS = -DV7 -DEMUL_OPEN3 -Dvoid=int X##DEFS = -DV7 -DNO_OPEN3 -Dvoid=int X#LDFLAGS = X#LIBS = -lndir X#LINT = lint X#LINTFLAGS = -abchx X#DEF_AR_FILE = \"/dev/rmt8\" X#DEFBLOCKING = 20 X#O = o X X# Minix version X# No lint, so no lintflags. Default file is stdin/out. (Minix "tar" X# doesn't even take an "f" flag, it assumes argv[2] is the archive name!) X# Minix "make" doesn't expand macros right, so Minix users will have X# to expand CFLAGS, SRCS, etc by hand, or fix your make. Not my problem! X# You'll also need to come up with getopt() and ctime(), the directory X# library, and a fixed doprintf() that handles %*s. Put this stuff in X# the "SUBSRC/SUBOBJ" macro below if you didn't put it in your C library. X# X# Pick open3 emulation or nonexistence. See open3.h, port.c. XDEFS = -DV7 -DMINIX -DEMUL_OPEN3 X##DEFS = -DV7 -DMINIX -DNO_OPEN3 X#LDFLAGS = XLIBS = XDEF_AR_FILE = \"-\" XDEFBLOCKING = 8 /* No good reason for this, change at will */ XO = s X X# Xenix version X#DEFS = -DUSG -DXENIX X#LDFLAGS = X#LIBS = -lx X#LINT = lint X#LINTFLAGS = -p X#DEF_AR_FILE = \"/dev/rmt8\" X#DEFBLOCKING = 20 X#O = o X X XCFLAGS = -DV7 -DMINIX -DEMUL_OPEN3 -DDEF_AR_FILE=\"-\" -DDEFBLOCKING=8 -F -T. XALLDEFS = $(DEFS) \ X -DDEF_AR_FILE=$(DEF_AR_FILE) \ X -DDEFBLOCKING=$(DEFBLOCKING) X# next line for Debugging XCOPTS = X# next line for Production X#COPTS = -O X X# Add things here like getopt, readdir, etc that aren't in your X# standard libraries. (E.g. MSDOS needs getopt, msd_dir.c, msd_dir.obj) XSUBSRC= XSUBOBJ= X X# Destination directory and installation program for make install XDESTDIR = /usr/pd XINSTALL = cp XRM = rm -f X XSRC1 = tar.c create.c extract.c buffer.c getoldopt.c XSRC2 = list.c names.c diffarch.c port.c wildmat.c $(SUBSRC) XSRCS = $(SRC1) $(SRC2) XOBJS = tar.s create.s extract.s buffer.s getoldopt.s list.s \ X names.s diffarch.s port.s wildmat.s X XAUX = README PORTING Makefile TODO tar.1 tar.5 tar.h port.h open3.h \ X msd_dir.h msd_dir.c X Xall: tar X Xtar: $(OBJS) X asld -o tar -i -T. /usr/lib/crtso.s $(OBJS) /usr/lib/libc.a /usr/lib/end.s X# command is too long for Messy-Dos (128 char line length limit) so X# this kludge is used... X# @echo $(OBJ1) + > command X# @echo $(OBJ2) >> command X# link @command, $@,,$(LIBS) /NOI; X# @$(RM) command X Xinstall: all X $(RM) $(DESTDIR)/tar $(DESTDIR)/.man/tar.[15] X $(INSTALL) tar $(DESTDIR)/tar X $(INSTALL) tar.1 $(DESTDIR)/.man/tar.1 X $(INSTALL) tar.5 $(DESTDIR)/.man/tar.5 X X Xclean: X $(RM) errs $(OBJS) tar X Xtar.shar: $(SRCS) $(AUX) X shar >tar.shar1 $(AUX) X shar >tar.shar2 $(SRC1) X shar >tar.shar3 $(SRC2) X Xtar.tar.Z: $(SRCS) $(AUX) X /bin/tar cf - $(AUX) $(SRCS) | compress -v >tar.tar.Z X X$(OBJS): tar.h port.h EOF echo x - create.diff sed 's/^X//' >create.diff << 'EOF' X*** create.c Fri Nov 06 16:18:31 1987 X--- create.c.new Fri Nov 06 21:24:07 1987 X*************** X*** 29,35 **** X * for the portable directory access routines. Change the #include line X * below to bring it in from wherever it is. X */ X! #include "ndir.h" X #endif X #endif X X--- 29,35 ---- X * for the portable directory access routines. Change the #include line X * below to bring it in from wherever it is. X */ X! #include "dirent.h" X #endif X #endif X X*************** X*** 301,307 **** X case S_IFDIR: /* Directory */ X { X register DIR *dirp; X! register struct direct *d; X char namebuf[NAMSIZ+2]; X register int len; X int our_device = hstat.st_dev; X--- 301,307 ---- X case S_IFDIR: /* Directory */ X { X register DIR *dirp; X! register struct dirent *d; X char namebuf[NAMSIZ+2]; X register int len; X int our_device = hstat.st_dev; X*************** X*** 367,373 **** X if (d->d_name[2] == '\0') continue; X } X } X! if (d->d_namlen + len >= NAMSIZ) { X annorec(stderr, tar); X fprintf(stderr, "%s%s: name too long\n", X namebuf, d->d_name); X--- 367,373 ---- X if (d->d_name[2] == '\0') continue; X } X } X! if (strlen(d->d_name) + len >= NAMSIZ) { X annorec(stderr, tar); X fprintf(stderr, "%s%s: name too long\n", X namebuf, d->d_name); EOF echo x - ctime.c sed 's/^X//' >ctime.c << 'EOF' X/* ctime.c yah (yet another hack) from date.c */ X X Xint days_per_month[] = X { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }; Xchar *months[] = X { "Jan", "Feb", "Mar", "Apr", "May", "Jun", X "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" }; Xchar *days[] = X { "Thu", "Fri", "Sat", "Sun", "Mon", "Tue", "Wed" }; X Xstruct { X int year, month, day, hour, min, sec; X} tm; X Xlong s_p_min; Xlong s_p_hour; Xlong s_p_day; Xlong s_p_year; X Xchar t_buf[26]; X Xchar *ctime(t) Xlong *t; X{ X long tt; X X s_p_min = 60L; X s_p_hour = 60L * 60L; X s_p_day = 60L * 60L * 24L; X s_p_year = 60L * 60L * 24L * 365L; X X tt = *t; X cv_time(tt); X X sprintf(t_buf,"%s %s %02d %02d:%02d:%02d %04d\n", days[(tt / s_p_day) % 7], X months[tm.month], tm.day, tm.hour, tm.min, tm.sec, tm.year); X return(t_buf); X} X Xcv_time(t) Xlong t; X{ X tm.year = 0; X tm.month = 0; X tm.day = 1; X tm.hour = 0; X tm.min = 0; X tm.sec = 0; X while (t >= s_p_year) { X if (((tm.year + 2) % 4) == 0) X t -= s_p_day; X tm.year += 1; X t -= s_p_year; X } X if (((tm.year + 2) % 4) == 0) X days_per_month[1]++; X tm.year += 1970; X while ( t >= (days_per_month[tm.month] * s_p_day)) X t -= days_per_month[tm.month++] * s_p_day; X while (t >= s_p_day) { X t -= s_p_day; X tm.day++; X } X while (t >= s_p_hour) { X t -= s_p_hour; X tm.hour++; X } X while (t >= s_p_min) { X t -= s_p_min; X tm.min++; X } X tm.sec = (int) t; X} X X/* finis */ EOF echo x - doprintf.c sed 's/^X//' >doprintf.c << 'EOF' X#include "../include/stdio.h" X X#define MAXDIGITS 12 X#define PRIVATE static X X/* X** _doprintf(fp, format, args) -- function called by fprintf, printf, sprintf X** Revised 06/21/87 by rmtodd@uokmax to add %ld, %lx, %lu, %lo formats X** Revised 06/28/87 by rmtodd@uokmax to add variable-length formats X** (e.g. printf("%*s",width,string); X*/ X X/* This is the same as varargs , on BSD systems */ X X#define GET_ARG(arglist,mode) ((mode *)(arglist += sizeof(mode)))[-1] X X_doprintf(fp, format, args) XFILE *fp; Xregister char *format; Xint args; X{ X register char *vl; X int long_flag; X int unsign_flag; X int r, X w1, w2, X sign; X long l; X char c; X char *s; X char padchar; X char a[MAXDIGITS]; X X vl = (char *) args; X X while ( *format != '\0') { X if ( *format != '%' ) { X putc( *format++, fp ); X continue; X } X X w1 = 0; X w2 = 0; X sign = 1; X long_flag = unsign_flag = 0; X padchar = ' '; X format++; X X X /* handle variable-size formats */ X if ( *format == '*') { X w1 = (int) GET_ARG(vl, int); X format++; X } else { X if ( *format == '-' ) { X sign = -1; X format++; X } X X if ( *format == '0') { X padchar = '0'; X format++; X } X X while ( *format >='0' && *format <='9' ){ X w1 = 10 * w1 + sign * ( *format - '0' ); X format++; X } X } X X if ( *format == '.'){ X format++; X if ( *format == '*') { X w2 = (int) GET_ARG(vl, int); X format++; X } else { X while ( *format >='0' && *format <='9' ){ X w2 = 10 * w2 + ( *format - '0' ); X format++; X } X } X } X if (*format == 'l') { X long_flag = 1; X ++format; X } X X switch (*format) { X case 'd': X if (long_flag) { X l = (long) GET_ARG(vl, long); X } else { X l = (long) GET_ARG(vl, int); X } X r = 10; X break; X case 'u': X if (long_flag) { X l = (long) GET_ARG(vl, long); X } else { X l = (long) GET_ARG(vl, int); X l = l & 0xFFFF; X } X unsign_flag = 1; X r = 10; X break; X case 'o': X if (long_flag) { X l = (long) GET_ARG(vl, long); X } else { X l = (long) GET_ARG(vl, int); X if (l < 0) l = l & 0xFFFF; X } X unsign_flag = 1; X r = 8; X break; X case 'x': X if (long_flag) { X l = (long) GET_ARG(vl, long); X } else { X l = (long) GET_ARG(vl, int); X if (l < 0) l = l & 0xFFFF; X } X unsign_flag = 1; X r = 16; X break; X case 'D': X l = (long) GET_ARG(vl, long); X r = 10; X break; X case 'O': X l = (long) GET_ARG(vl, long); X r = 8; X break; X case 'X': X l = (long) GET_ARG(vl, long); X r = 16; X break; X case 'c': X c = (char) GET_ARG(vl, int); X /* char's are casted back to int's */ X putc( c, fp); X format++; X continue; X case 's': X s = GET_ARG(vl, char *); X _printit(s,w1,w2,padchar,strlen(s),fp); X format++; X continue; X default: X putc(*format++,fp); X continue; X } X X _bintoascii (l, r, a, unsign_flag); X _printit(a,w1,w2,padchar,strlen(a),fp); X format++; X } X} X X X XPRIVATE _bintoascii (num, radix, a, unsg) Xunsigned long num; Xint radix; Xchar *a; Xint unsg; /* 1 if unsigned number output */ X{ X char b[MAXDIGITS]; X int hit, negative; X register int n, i; X long temp; X negative = 0; X if (num == 0) { X a[0] = '0'; X a[1] = '\0'; X return; X } X if (radix == 10 && !unsg) { X temp = num; X if (temp < 0) {num = -temp; negative++;} X } X X for (n = 0; n < MAXDIGITS; n++) X b[n] = 0; X X n = 0; X X do { X if (radix == 10) { X b[n] = num % 10; X num = (num - b[n]) / 10; X } X if (radix == 8) { X b[n] = num & 0x7; X num = (num >> 3) & 0x1FFFFFFF; X } X if (radix == 16) { X b[n] = num & 0xF; X num = (num >> 4) & 0x0FFFFFFF; X } X n++; X } X while (num != 0); X X /* Convert to ASCII. */ X hit = 0; X for (i = n - 1; i >= 0; i--) { X if (b[i] == 0 && hit == 0) { X b[i] = ' '; X } X else { X if (b[i] < 10) X b[i] += '0'; X else X b[i] += 'A' - 10; X hit++; X } X } X if (negative) X b[n++] = '-'; X X for(i = n - 1 ; i >= 0 ; i-- ) X *a++ = b[i]; X X *a = '\0'; X X} X X XPRIVATE _printit(str, w1, w2, padchar, length, file) Xchar *str; Xint w1, w2; Xchar padchar; Xint length; XFILE *file; X{ X int len2 = length; X int temp; X X if ( w2 > 0 && length > w2) X len2 = w2; X X temp = len2; X X if ( w1 > 0 ) X while ( w1 > len2 ){ X --w1; X putc(padchar,file); X } X X while ( *str && ( len2-- != 0 )) X putc(*str++, file); X X if ( w1 < 0 ) X if ( padchar == '0' ){ X putc('.',file); X w1++; X } X while ( w1 < -temp ){ X w1++; X putc(padchar,file); X } X} EOF echo x - getopt.c sed 's/^X//' >getopt.c << 'EOF' X/* X** @(#)getopt.c 2.2 (smail) 1/26/87 X*/ X X/* X * Here's something you've all been waiting for: the AT&T public domain X * source for getopt(3). It is the code which was given out at the 1985 X * UNIFORUM conference in Dallas. I obtained it by electronic mail X * directly from AT&T. The people there assure me that it is indeed X * in the public domain. X * X * There is no manual page. That is because the one they gave out at X * UNIFORUM was slightly different from the current System V Release 2 X * manual page. The difference apparently involved a note about the X * famous rules 5 and 6, recommending using white space between an option X * and its first argument, and not grouping options that have arguments. X * Getopt itself is currently lenient about both of these things White X * space is allowed, but not mandatory, and the last option in a group can X * have an argument. That particular version of the man page evidently X * has no official existence, and my source at AT&T did not send a copy. X * The current SVR2 man page reflects the actual behavor of this getopt. X * However, I am not about to post a copy of anything licensed by AT&T. X */ X X X/*LINTLIBRARY*/ X#define NULL 0 X#define EOF (-1) X#define ERR(s, c) if(opterr){\ X extern int write();\ X char errbuf[2];\ X errbuf[0] = c; errbuf[1] = '\n';\ X (void) write(2, argv[0], (unsigned)strlen(argv[0]));\ X (void) write(2, s, (unsigned)strlen(s));\ X (void) write(2, errbuf, 2);} X Xextern char *index(); X Xint opterr = 1; Xint optind = 1; Xint optopt; Xchar *optarg; X Xint Xgetopt(argc, argv, opts) Xint argc; Xchar **argv, *opts; X{ X static int sp = 1; X register int c; X register char *cp; X X if(sp == 1) X if(optind >= argc || X argv[optind][0] != '-' || argv[optind][1] == '\0') X return(EOF); X else if(strcmp(argv[optind], "--") == NULL) { X optind++; X return(EOF); X } X optopt = c = argv[optind][sp]; X if(c == ':' || (cp=index(opts, c)) == NULL) { X ERR(": illegal option -- ", c); X if(argv[optind][++sp] == '\0') { X optind++; X sp = 1; X } X return('?'); X } X if(*++cp == ':') { X if(argv[optind][sp+1] != '\0') X optarg = &argv[optind++][sp+1]; X else if(++optind >= argc) { X ERR(": option requires an argument -- ", c); X sp = 1; X return('?'); X } else X optarg = argv[optind++]; X sp = 1; X } else { X if(argv[optind][++sp] == '\0') { X sp = 1; X optind++; X } X optarg = NULL; X } X return(c); X} EOF