[comp.os.minix] changes needed for PD Tar, part 3 of 3

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