stp@ethz.UUCP (Stephan Paschedag) (08/16/89)
#! /bin/sh
# This is a shell archive. Remove anything before this line, then unpack
# it by saving it into a file and typing "sh file". To overwrite existing
# files, type "sh file -c". You can also feed this as standard input via
# unshar, or by typing "sh <file", e.g.. If this archive is complete, you
# will see the following message at the end:
# "End of shell archive."
# Contents: readme makefile tar.c
# Wrapped by stp@ethz on Wed Aug 16 14:17:38 1989
PATH=/bin:/usr/bin:/usr/ucb ; export PATH
if test -f 'readme' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'readme'\"
else
echo shar: Extracting \"'readme'\" \(924 characters\)
sed "s/^X//" >'readme' <<'END_OF_FILE'
X
Xthis version of tar has originally been Simmule Turners tar for OS-9/6809.
XI've adapted it to OS-9/68k and added some new features.
XI did this in a manner that it still should be able to be compiled on a
X6809 system (but i haven't been able to test it).
X
Xnew features :
X
X it's now possible to extract a single file from an archive
X all missing directories are now automatically created
X extraction of entire directories in now possible
X directories from UNIX-written archives are now correctly created
X
Xexamples:
X
X tar x archive test/abc extract file 'test/abc' from archive
X directory 'test' is automatically created
X
X tar x archive test extracts entire directory 'test'
X
Xplease send more ideas or bug reports to me :
X
XStephan Paschedag paschedag@strati.ethz.ch or stp@ethz.UUCP
XSwiss Federal Institute Of Technology Zurich ..!cernvax!ethz!stp
END_OF_FILE
if test 924 -ne `wc -c <'readme'`; then
echo shar: \"'readme'\" unpacked with wrong size!
fi
# end of 'readme'
fi
if test -f 'makefile' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'makefile'\"
else
echo shar: Extracting \"'makefile'\" \(118 characters\)
sed "s/^X//" >'makefile' <<'END_OF_FILE'
XCFLAGS=-qit=/r0
XCC=cc
X
X.makedate: tar.c
X $(CC) $(CFLAGS) -fd=tar tar.c
X @attr tar -ea
X @touch .makedate
X
X
END_OF_FILE
if test 118 -ne `wc -c <'makefile'`; then
echo shar: \"'makefile'\" unpacked with wrong size!
fi
# end of 'makefile'
fi
if test -f 'tar.c' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'tar.c'\"
else
echo shar: Extracting \"'tar.c'\" \(19127 characters\)
sed "s/^X//" >'tar.c' <<'END_OF_FILE'
Xchar scid[]="$Header: tar.c,v 1.5 08/06/89 SrT/stp $";
X
X/*
X * Modified for use under OS-9/68k (08/03/89)
X * Stephan Paschedag stp@ethz.uucp ..cernvax!ethz!stp
X *
X * Compilation for OS-9/68k: cc -qi tar.c
X *
X * 08/06/89 V1.5 Allow extraction of entire directories,
X * allow extraction of single files in subdirectories,
X * creates automatically missing directories.
X * continues now correctly after some errors
X * handles directories from unix archives correctly (stp)
X *
X * Modified for use under OS-9/6809
X * Simmule Turner simmy@nu.cs.fsu.edu 70651,67
X *
X * Compilation for OS-9/6809: cc -m=3k tar.c
X * Use extra memory for recursive directory descents.
X *
X * 07/17/88 V1.4 Allow extraction of specified file(s)....
X * from archive named on the command line
X * with wildcard matching *,?. (SrT)
X *
X * 07/14/88 V1.3 Added verbose TOC ala unix. Cleaned up
X * printing routines, use decimal instead of
X * octal. Removed conditional compilation. (SrT)
X *
X * 07/13/88 V1.2 Tries to set the correct file permissions.
X * Send diagnostics to stderr. Use lseek's
X * for TOC generation when a rbf device. (SrT)
X *
X * 07/12/88 V1.1 Added option of reading/writing
X * archive to stdin/stdout (SrT)
X *
X * 07/12/88 V1.0 Initial port (SrT)
X * added dummy fv options
X * SrT */
X
X/* tar - tape archiver Author: Michiel Huisjes */
X
X/* Usage: tar [cxt][v] tapefile [files]
X *
X * Bugs:
X * This tape archiver should only be used as a program to read or make
X * simple tape archives. Its basic goal is to read (or build) UNIX V7 tape
X * archives and extract the named files. It is not wise to use it on
X * raw magnetic tapes. It doesn't know anything about linked files,
X * except when the involved fields are filled in.
X */
X
X#include <stdio.h>
X#include <direct.h>
X#include <modes.h>
X#include <sgstat.h>
X#include <time.h>
X#ifndef OSK
X# include <utime.h>
X#else
X# include <types.h>
X# include <errno.h>
X# include <strings.h>
X#endif
X
X#define STDIN 0
X#define STDOUT 1
X
Xtypedef char BOOL;
X#define TRUE 1
X#define FALSE 0
X
X#define HEADER_SIZE 512
X#define NAME_SIZE 100
X#define BLOCK_BOUNDARY 20
X
Xtypedef union {
X char hdr_block[HEADER_SIZE];
X struct m {
X char m_name[NAME_SIZE];
X char m_mode[8];
X char m_uid[8];
X char m_gid[8];
X char m_size[12];
X char m_time[12];
X char m_checksum[8];
X char m_linked;
X char m_link[NAME_SIZE];
X } member;
X} HEADER;
X
XHEADER header;
X
X#define INT_TYPE (sizeof(header.member.m_uid))
X#define LONG_TYPE (sizeof(header.member.m_size))
X
X#define NIL_HEADER ((HEADER *) 0)
X#define NIL_PTR ((char *) 0)
X#define BLOCK_SIZE 512
X
X#define flush() print(NIL_PTR)
X
XBOOL show_fl, creat_fl, ext_fl, verbose_fl, modtime_fl;
X
Xchar modestr[11], stbuf[132];
Xstruct sgbuf opts;
Xstruct fildes ofdbuf;
X#ifdef OSK
Xchar *dummy = NULL;
X#endif
X
Xint tar_fd;
X#ifdef OSK
Xchar usage[] = "Syntax : tar [ctx][mfv] tarfile [file(s)...]\nFunction: Builds and extracts from Unix tape archive files\nOptions:\n c : create archive\n t : list contents\n x : extract from archive";
X#else
Xchar usage[] = "Usage: tar [ctx][mfv] tarfile [file(s)...]";
X#endif
Xchar io_buffer[BLOCK_SIZE];
X
Xint total_blocks;
Xlong convert();
Xchar **match();
X
Xblock_size() {
X return ((int) ((convert(header.member.m_size, LONG_TYPE)
X + (long) BLOCK_SIZE - 1) / (long) BLOCK_SIZE));
X}
X
Xerror(s1, s2)
Xchar *s1, *s2;
X{
X#ifdef OSK
X fprintf(stderr,"%s %s\n", s1, s2 ? s2 : "");
X exit(1);
X#else
X string_print(NIL_PTR, "%s %s\r\l", s1, s2 ? s2 : "");
X flush();
X exit(1);
X#endif
X}
X
Xmain(argc, argv)
Xint argc;
Xregister char *argv[];
X{
X register char *ptr;
X#ifdef OSK
X char **p = &dummy;
X#else
X char **p = "\0";
X#endif
X int i;
X
X pflinit();
X
X if (argc < 3)
X error(usage, NIL_PTR);
X
X for (ptr = argv[1]; *ptr; ptr++) {
X switch (*ptr) {
X case 'c' :
X creat_fl = TRUE;
X break;
X case 't' :
X show_fl = TRUE;
X break;
X case 'x' :
X ext_fl = TRUE;
X if (argc > 3)
X p = &argv[3];
X break;
X/*
X * Modifiers
X * SrT */
X case 'f':
X break;
X case 'm':
X modtime_fl = TRUE;
X break;
X case 'v':
X verbose_fl = TRUE;
X break;
X default :
X error(usage, NIL_PTR);
X }
X }
X
X if (creat_fl + ext_fl + show_fl != 1)
X error(usage, NIL_PTR);
X
X if (argv[2][0] == '-')
X tar_fd = creat_fl ? STDOUT : STDIN;
X else
X tar_fd = creat_fl ? creat(argv[2],3) : open(argv[2],1);
X
X if (tar_fd < 0) {
X#ifdef OSK
X exit(_errmsg(errno,"cannot open archive. "));
X#else
X error("Cannot open ", argv[2]);
X#endif
X }
X
X if (creat_fl) {
X for (i = 3; i < argc; i++)
X add_file(argv[i]);
X adjust_boundary();
X }
X else
X tarfile (p);
X
X flush();
X exit(0);
X}
X
XBOOL get_header()
X{
X register int check,c;
X
X mread(tar_fd, &header, sizeof(header));
X if (header.member.m_name[0] == '\0')
X return FALSE;
X
X check = (int) convert(header.member.m_checksum, INT_TYPE);
X
X if (check != (c = checksum()))
X error("tar: header checksum error.", NIL_PTR);
X
X return TRUE;
X}
X
Xtarfile(p)
X char **p;
X{
X register char *ptr;
X register char *mem_name;
X char *atime();
X int i;
X register char **q;
X register char *pp;
X
X _gs_opt(tar_fd,&opts);
X
X while (get_header()) {
X mem_name = header.member.m_name;
X if (ext_fl) {
X if (*p) {
X/* extract entire directories (08/05/89 stp) */
X if (mem_name[strlen(mem_name)-1] == '/') {
X mem_name[strlen(mem_name)-1] = '\0';
X if (q=match(p,mem_name)) {
X pp = (char *) malloc(strlen(mem_name)+3);
X strcpy(pp,mem_name);
X strncat(pp,"/*",3);
X *q = pp;
X mkdir(mem_name);
X }
X }
X else {
X if (match(p,mem_name)) {
X extract(mem_name);
X }
X else
X skip_entry();
X }
X }
X else {
X if (is_dir(mem_name)) {
X for (ptr = mem_name; *ptr != '/'; ptr++);
X *ptr = '\0';
X mkdir(mem_name);
X }
X else {
X extract(mem_name);
X }
X }
X }
X else {
X if (!verbose_fl)
X#ifdef OSK
X printf("%s",mem_name);
X#else
X string_print(NIL_PTR, "%s", mem_name);
X#endif
X else {
X u29mode((int) convert(header.member.m_mode,INT_TYPE));
X#ifdef OSK
X printf("%s ",modestr);
X#else
X string_print(NIL_PTR, "%s ",modestr);
X#endif
X sprintf(stbuf,"%3d/%3d %8ld %s %s",
X (int) convert(header.member.m_uid, INT_TYPE),
X (int) convert(header.member.m_gid, INT_TYPE),
X convert(header.member.m_size,LONG_TYPE),
X atime(convert(header.member.m_time,LONG_TYPE)),
X header.member.m_name);
X#ifdef OSK
X printf("%s",stbuf);
X }
X printf("\n");
X#else
X print(stbuf);
X }
X print("\r\l");
X#endif
X skip_entry();
X }
X flush();
X }
X}
X
Xskip_entry()
X{
X register int blocks = block_size();
X
X if (opts.sg_class == 1) {
X long pos;
X
X pos = ((long) blocks) * BLOCK_SIZE;
X lseek(tar_fd,pos,1);
X }
X else {
X while (blocks--)
X read(tar_fd, io_buffer, BLOCK_SIZE);
X }
X}
X
Xextract(file)
Xregister char *file;
X{
X register int fd;
X
X if (header.member.m_linked == '1') {
X#ifdef OSK
X fprintf(stderr,"Cannot link %s (symbolic links not supportet)\n",header.member.m_link);
X#else
X string_print(NIL_PTR,"Cannot link %s\r\l",header.member.m_link);
X#endif
X skip_entry();
X return;
X }
X
X if ((fd = creat(file, 3)) < 0) {
X/* create missing directories (08/06/89) stp */
Xregister char *s,*pp;
X pp = file;
X#ifdef OSK
X while (s = index(pp,'/')) {
X#else
X while (s = strchr(pp,'/')) {
X#endif
X pp = (char *) malloc(s-file+1);
X strncpy(pp,file,s-file);
X pp[s-file] = '\0';
X mkdir(pp);
X free(pp);
X pp = s+1;
X }
X if ((fd = creat(file, 3)) < 0) {
X#ifdef OSK
X fprintf(stderr, "Cannot create %s : ", file); fflush(stderr);
X prerr(0,errno);
X#else
X string_print(NIL_PTR, "Cannot create %s\r\l", file);
X#endif
X skip_entry();
X return;
X }
X }
X
X copy(file, tar_fd, fd, convert(header.member.m_size, LONG_TYPE));
X
X _ss_attr(fd, u29mode((int) convert(header.member.m_mode, INT_TYPE)));
X
X if (!modtime_fl)
X#ifdef OSK
X if (_gs_gfd(fd,&ofdbuf,sizeof(ofdbuf)) != -1) {
X#else
X if (_gs_gfd(fd,&ofdbuf,sizeof(ofdbuf)) != ERROR) {
X#endif
X
X struct tm *utm;
X struct sgtbuf otm;
X long clock;
X
X clock = convert(header.member.m_time,LONG_TYPE);
X utm = localtime(&clock);
X u2otime(&otm,utm);
X _strass(&ofdbuf.fd_date[0], &otm, 5);
X _ss_pfd(fd,&ofdbuf);
X }
X
X close(fd);
X flush();
X}
X
Xcopy(file, from, to, bytes)
Xchar *file;
Xint from, to;
Xregister long bytes;
X{
X register int rest;
X int blocks = (int) ((bytes + (long) BLOCK_SIZE - 1) / (long) BLOCK_SIZE);
X
X if (verbose_fl) {
X if (to == tar_fd)
X#ifdef OSK
X printf("a %s, %d tape blocks\n",file,blocks);
X#else
X sprintf(stbuf,"a %s, %d tape blocks\r\l",file,blocks);
X#endif
X else
X#ifdef OSK
X printf("x %s, %ld bytes, %d tape blocks\n",file,bytes,blocks);
X#else
X sprintf(stbuf,"x %s, %ld bytes, %d tape blocks\r\l",file,bytes,blocks);
X print(stbuf);
X flush();
X#endif
X }
X
X while (blocks--) {
X read(from, io_buffer, BLOCK_SIZE);
X rest = (bytes > (long) BLOCK_SIZE) ? BLOCK_SIZE : (int) bytes;
X mwrite(to, io_buffer, (to == tar_fd) ? BLOCK_SIZE : rest);
X bytes -= (long) rest;
X }
X}
X
Xlong convert(str, type)
Xchar str[];
Xint type;
X{
X register long ac = 0L;
X register int i;
X
X for (i = 0; i < type; i++) {
X if (str[i] >= '0' && str[i] <= '7') {
X ac <<= 3;
X ac += (long) (str[i] - '0');
X }
X }
X
X return ac;
X}
X
Xmkdir(dir_name)
Xchar *dir_name;
X{
X if (mknod(dir_name,3) < 0) {
X return;
X }
X else {
X int fd;
X if ((fd = open(dir_name,0x83)) > 0) {
X _ss_attr(fd, S_IFDIR | u29mode((int) convert(header.member.m_mode, INT_TYPE)));
X close(fd);
X }
X }
X}
X
Xchecksum()
X{
X register char *ptr = header.member.m_checksum;
X register int ac = 0;
X
X while (ptr < &header.member.m_checksum[INT_TYPE])
X *ptr++ = ' ';
X
X ptr = header.hdr_block;
X while (ptr < &header.hdr_block[BLOCK_SIZE])
X ac += *ptr++;
X
X return ac;
X}
X
Xis_dir(file)
Xregister char *file;
X{
X while (*file++ != '\0') ;
X return (*(file - 2) == '/');
X}
X
Xchar path[NAME_SIZE];
X
Xchar pathname[NAME_SIZE];
Xchar *path_name(file)
Xregister char *file;
X{
X
X string_print(pathname, "%s%s", path, file);
X return pathname;
X}
X
Xadd_path(name)
Xregister char *name;
X{
X register char *path_ptr = path;
X
X while (*path_ptr)
X path_ptr++;
X
X if (name == NIL_PTR) {
X while (*path_ptr-- != '/')
X ;
X while (*path_ptr != '/' && path_ptr != path)
X path_ptr--;
X if (*path_ptr == '/')
X path_ptr++;
X *path_ptr = '\0';
X }
X else {
X while (*name) {
X if (path_ptr == &path[NAME_SIZE])
X error("tar: Pathname too long", NIL_PTR);
X *path_ptr++ = *name++;
X }
X *path_ptr++ = '/';
X *path_ptr = '\0';
X }
X}
X
Xadd_file(file)
Xregister char *file;
X{
X struct fildes st;
X struct dirent dir;
X register int fd;
X#ifdef OSK
X unsigned long siz;
X u_char *sip = (u_char*) st.fd_fsize;
X#endif
X
X if ((fd = open(file,0x81)) < 0)
X if ((fd = open(file, 1)) < 0) {
X#ifdef OSK
X fprintf(stderr, "Cannot open '%s' ", file); fflush(stderr);
X prerr(0,errno);
X#else
X string_print(NIL_PTR, "Cannot open %s\r\l", file);
X#endif
X return;
X }
X if (_gs_gfd(fd,&st,sizeof(st)) < 0) {
X#ifdef OSK
X fprintf(stderr, "Cannot get file descriptor for %s",file); fflush(stderr);
X prerr(0,errno);
X#else
X string_print(NIL_PTR, "Cannot get file descriptor for %s\r\l",file);
X#endif
X close(fd);
X return;
X }
X siz = (((((sip[0] << 8) + sip[1]) << 8) + sip[2]) << 8) + sip[3];
X
X make_header(path_name(file), &st);
X mwrite(tar_fd, &header, sizeof(header));
X if (!(st.fd_att & S_IFDIR))
X#ifdef OSK
X copy(path_name(file), fd, tar_fd, siz);
X#else
X copy(path_name(file), fd, tar_fd, st.fd_fsize);
X#endif
X else if (st.fd_att & S_IFDIR) {
X if (chdir(file) < 0)
X string_print(NIL_PTR, "Cannot chdir to %s\n", file);
X else {
X add_path(file);
X mread(fd, &dir, sizeof(dir)); /* "." */
X mread(fd, &dir, sizeof(dir)); /* ".." */
X while (read(fd, &dir, sizeof(dir)) == sizeof(dir)) {
X#ifdef OSK
X if (dir.dir_addr) {
X#else
X if (dir.dir_addr[0] || dir.dir_addr[1] || dir.dir_addr[2]) {
X#endif
X strhcpy(dir.dir_name,dir.dir_name);
X if (*dir.dir_name)
X add_file(dir.dir_name);
X }
X }
X chdir("..");
X add_path(NIL_PTR);
X }
X }
X else
X#ifdef OSK
X _errmsg("unknown file type. Not added. ",0);
X#else
X print("tar: unknown file type. Not added.\r\l");
X#endif
X
X close(fd);
X}
X
Xmake_header(file, st)
Xchar *file;
Xregister struct fildes *st;
X{
X register char *ptr = header.member.m_name;
X char tbuf[6];
X#ifdef OSK
X u_char *sip = (u_char*) st->fd_fsize;
X unsigned long siz = (((((sip[0] << 8) + sip[1]) << 8) +
X sip[2]) << 8) + sip[3];
X u_char *owp = (u_char*) st->fd_own;
X unsigned short own = owp[1];
X unsigned short group = owp[0];
X#endif
X
X clear_header();
X
X while (*ptr++ = *file++)
X ;
X
X if (st->fd_att & S_IFDIR) {
X *(ptr - 1) = '/';
X#ifdef OSK
X siz = 0;
X#else
X st->fd_fsize = 0L;
X#endif
X }
X
X _strass(tbuf,st->fd_date,5);
X tbuf[5] = 0;
X string_print(header.member.m_mode, "%I ", o2umode(st->fd_att));
X#ifdef OSK
X string_print(header.member.m_uid, "%I ", own);
X string_print(header.member.m_gid, "%I ", group);
X string_print(header.member.m_size, "%L ", siz);
X#else
X string_print(header.member.m_uid, "%I ", st->fd_own);
X string_print(header.member.m_gid, "%I ", 101);
X string_print(header.member.m_size, "%L ", st->fd_fsize);
X#endif
X string_print(header.member.m_time, "%L ", o2utime(tbuf));
X header.member.m_linked = ' ';
X string_print(header.member.m_checksum, "%I", checksum());
X}
X
Xclear_header()
X{
X register char *ptr = header.hdr_block;
X
X while (ptr < &header.hdr_block[BLOCK_SIZE])
X *ptr++ = '\0';
X}
X
Xadjust_boundary()
X{
X clear_header();
X mwrite(tar_fd, &header, sizeof(header));
X
X while (total_blocks++ < BLOCK_BOUNDARY)
X mwrite(tar_fd, &header, sizeof(header));
X close(tar_fd);
X}
X
Xmread(fd, address, bytes)
Xint fd, bytes;
Xchar *address;
X{
Xregister int r;
X
X if ((r = read(fd, address, bytes)) != bytes) {
X#ifdef OSK
X if (r == 0)
X errno = E_EOF;
X exit(_errmsg(errno,"read error. "));
X#else
X error("tar: read error.", NIL_PTR);
X#endif
X }
X}
X
Xmwrite(fd, address, bytes)
Xint fd, bytes;
Xchar *address;
X{
X if (write(fd, address, bytes) != bytes) {
X#ifdef OSK
X exit(_errmsg(errno,"write error. "));
X#else
X error("tar: write error.", NIL_PTR);
X#endif
X }
X total_blocks++;
X}
X
Xchar output[BLOCK_SIZE];
Xprint(str)
Xregister char *str;
X{
X static int index = 0;
X
X if (str == NIL_PTR) {
X write(2, output, index);
X index = 0;
X return;
X }
X
X while (*str) {
X output[index++] = *str++;
X if (index == BLOCK_SIZE) {
X write(2, output, BLOCK_SIZE);
X index = 0;
X }
X }
X}
X
Xchar *num_out(number)
Xregister long number;
X{
X static char num_buf[13];
X char temp[13];
X register int i;
X
X for (i = 0; i < 11; i++) {
X temp[i] = (number & 07) + '0';
X number >>= 3;
X }
X
X for (i = 0; i < 11; i++)
X num_buf[i] = temp[10 - i];
X
X return num_buf;
X}
X
X/* VARARGS */
Xstring_print(buffer, fmt, args)
Xchar *buffer;
Xregister char *fmt;
Xint args;
X{
X register char *buf_ptr;
X char *scan_ptr;
X char buf[NAME_SIZE];
X int *argptr = &args;
X BOOL pr_fl, i;
X
X if (pr_fl = (buffer == NIL_PTR))
X buffer = buf;
X
X buf_ptr = buffer;
X while (*fmt) {
X if (*fmt == '%') {
X fmt++;
X switch (*fmt++) {
X case 's':
X scan_ptr = (char *) *argptr;
X break;
X case 'I':
X scan_ptr = num_out((long) *argptr) + 5;
X/* for (i = 0; i < 5; i++)
X scan_ptr++; */
X break;
X case 'L':
X scan_ptr = num_out(*((long *) argptr));
X argptr++;
X break;
X default:
X scan_ptr = "";
X }
X while (*buf_ptr++ = *scan_ptr++)
X ;
X buf_ptr--;
X argptr++;
X }
X else
X *buf_ptr++ = *fmt++;
X }
X *buf_ptr = '\0';
X
X if (pr_fl)
X print(buffer);
X}
X
X o2umode(mode)
X char mode;
X{
X int ret_mode=0;
X
X if (mode & S_IFDIR)
X ret_mode |= 040000;
X if (mode & S_IREAD)
X ret_mode |= 0400;
X if (mode & S_IWRITE)
X ret_mode |= 0200;
X if (mode & S_IEXEC)
X ret_mode |= 0100;
X if (mode & S_IOREAD)
X ret_mode |= 04;
X if (mode & S_IOWRITE)
X ret_mode |= 02;
X if (mode & S_IOEXEC)
X ret_mode |= 01;
X
X return(ret_mode);
X}
X
X u29mode(mode)
X int mode;
X{
X int ret_mode=0;
X
X strcpy(modestr,"-----------");
X
X if (mode & 040000) {
X ret_mode |= S_IFDIR;
X modestr[0] = 'd';
X }
X
X if (mode & 0400) {
X ret_mode |= S_IREAD;
X modestr[1] = 'r';
X }
X
X if (mode & 0200) {
X ret_mode |= S_IWRITE;
X modestr[2] = 'w';
X }
X
X if (mode & 0100) {
X ret_mode |= S_IEXEC;
X modestr[3] = 'x';
X }
X
X if (mode & 04) {
X ret_mode |= S_IOREAD;
X modestr[7] = 'r';
X }
X
X if (mode & 02) {
X ret_mode |= S_IOWRITE;
X modestr[8] = 'w';
X }
X
X if (mode & 01) {
X ret_mode |= S_IOEXEC;
X modestr[9] = 'x';
X }
X
X return(ret_mode);
X}
X
Xchar *atime(clock)
X long clock;
X{
X static char buf[26];
X int i;
X
X strcpy(buf,ctime(&clock));
X
X for (i=4; i< 16; i++)
X buf[i-4] = buf[i];
X buf[12] = ' ';
X
X for (i=20; i<24; i++)
X buf[i-7] = buf[i];
X buf[17] = 0;
X
X return(buf);
X}
X
Xchar **match(p,name)
X char **p, *name;
X{
Xchar **q = p;
X
X while (*q) {
X#ifdef OSK
X if (!_cmpnam(name,*q,strlen(*q))) {
X#else
X if (patmatch(*q,name,1)) {
X#endif
X return(q);
X }
X q++;
X }
X return(NULL);
X}
X
X#ifdef OSK
Xu2otime(om,um)
Xstruct sgtbuf *om;
Xstruct tm *um;
X{
X om->t_year = um->tm_year;
X om->t_month = um->tm_mon+1;
X om->t_day = um->tm_mday;
X om->t_hour = um->tm_hour;
X om->t_minute = um->tm_min;
X om->t_second = um->tm_sec;
X}
X
Xlong o2utime(om)
Xstruct sgtbuf *om;
X{
Xstruct tm um;
X
X um.tm_year = om->t_year;
X um.tm_mon = om->t_month-1;
X um.tm_mday = om->t_day;
X um.tm_hour = om->t_hour;
X um.tm_min = om->t_minute;
X um.tm_sec = om->t_second;
X return mktime(&um);
X}
X#endif
END_OF_FILE
if test 19127 -ne `wc -c <'tar.c'`; then
echo shar: \"'tar.c'\" unpacked with wrong size!
fi
# end of 'tar.c'
fi
echo shar: End of shell archive.
exit 0