hyc@umix.cc.umich.edu (Howard Chu) (04/14/88)
XX * Generate output characters in reverse order XX */ XX while (code >= 256) { XX *stackp++ = suffix[code]; XX code = prefix[code]; XX } XX *stackp++ = finchar = suffix[code]; XX XX /* XX * And put them out in forward order XX */ XX do XX putc_unp(*--stackp, t); XX while (stackp > stack); XX XX /* XX * Generate the new entry. XX */ XX if ((code = free_ent) < maxcodemax) { XX prefix[code] = (unsigned short) oldcode; XX suffix[code] = finchar; XX free_ent = code + 1; XX } XX /* XX * Remember previous code. XX */ XX oldcode = incode; XX } XX} SHAR_EOF if test 11224 -ne "`wc -c arcsqs.c`" then echo shar: error transmitting arcsqs.c '(should have been 11224 characters)' fi echo shar: extracting arcsvc.c '(5470 characters)' sed 's/^XX//' << \SHAR_EOF > arcsvc.c XX/* XX * $Log: arcsvc.c,v $ XX * Revision 1.2 88/04/11 18:42:09 hyc XX * re-synch with MTS... XX * XX * Revision 1.1 88/04/11 18:39:02 hyc XX * Initial revision XX * XX * Revision 1.2 87/12/19 04:28:54 hyc XX * fixing indent problems XX * XX * Revision 1.1 87/12/19 04:27:04 hyc XX * Initial revision XX * XX * Revision 1.4 87/08/13 17:05:58 hyc XX * Run thru indent, fixed some signed vs. unsigned problems XX * with bp <-> buf, and inbuf and localbuf... XX * Revision 1.3 87/07/21 11:42:06 hyc *** empty XX * log message *** XX * XX * Revision 1.2 87/07/21 09:22:03 hyc *** empty log message *** XX * XX */ XX XX/* XX * ARC - Archive utility - ARCSVC XX * XX * Version 2.20, created on 10/24/86 at 12:17:00 XX * XX * (C) COPYRIGHT 1985,86 by System Enhancement Associates; ALL RIGHTS RESERVED XX * XX * By: Thom Henderson XX * XX * Description: This file contains service routines needed to maintain an XX * archive. XX * XX * Language: Computer Innovations Optimizing C86 XX */ XX#include <stdio.h> XX#include "arc.h" XX XXINT XXopenarc(chg) /* open archive */ XX INT chg; /* true to open for changes */ XX{ XX FILE *fopen();/* file opener */ XX XX if (!(arc = fopen(arcname, "rb"))) { XX if (chg) XX printf("Creating new archive: %s\n", arcname); XX else XX abort("Archive not found: %s", arcname); XX } XX if (chg) { /* if opening for changes */ XX if (!(new = fopen(newname, "wb"))) XX abort("Cannot create archive copy: %s", newname); XX } XX} XX XXINT XXclosearc(chg) /* close an archive */ XX INT chg; /* true if archive was changed */ XX{ XX if (arc) { /* if we had an initial archive */ XX if (kludge) /* kludge to update timestamp */ XX setstamp(arc, olddate, oldtime); XX fclose(arc); /* then close it */ XX } XX if (chg) { /* if things have changed */ XX#ifdef MSDOS XX setstamp(new, arcdate, arctime); XX#endif XX fclose(new); /* close the new copy */ XX#ifdef BSD XX setstamp(newname, arcdate, arctime); XX#endif XX XX if (arc) { /* if we had an original archive */ XX if (keepbak) { /* if a backup is wanted */ XX#ifdef BSD XX char *buf; XX buf = (char *) malloc((5 + strlen(arcname) + strlen(bakname)) * sizeof(char)); XX *buf = '\0'; XX strcat(buf, "mv "); XX strcat(buf, arcname); XX strcat(buf, " "); XX strcat(buf, bakname); XX if (system(buf)) XX#else XX unlink(bakname); /* erase any old copies */ XX if (rename(arcname, bakname)) XX#endif XX abort("Cannot rename %s to %s", arcname, bakname); XX printf("Keeping backup archive: %s\n", bakname); XX#ifdef BSD XX free(buf); XX#endif XX } else if (unlink(arcname)) XX abort("Cannot delete old archive: %s", arcname); XX } XX#ifdef BSD XX { XX char *buf; XX buf = (char *) malloc((5 + strlen(newname) + strlen(arcname)) * sizeof(char)); XX *buf = '\0'; XX strcat(buf, "mv "); XX strcat(buf, newname); XX strcat(buf, " "); XX strcat(buf, arcname); XX if (system(buf)) XX#else XX if (rename(newname, arcname)) XX#endif XX abort("Cannot rename %s to %s", newname, arcname); XX#ifdef BSD XX free(buf); XX } XX#endif XX} XX} XX XX/* XX * CRC computation logic XX * XX * The logic for this method of calculating the CRC 16 bit polynomial is taken XX * from an article by David Schwaderer in the April 1985 issue of PC Tech XX * Journal. XX */ XX XXstatic INT crctab[] = /* CRC lookup table */ XX{ XX 0x0000, 0xC0C1, 0xC181, 0x0140, 0xC301, 0x03C0, 0x0280, 0xC241, XX 0xC601, 0x06C0, 0x0780, 0xC741, 0x0500, 0xC5C1, 0xC481, 0x0440, XX 0xCC01, 0x0CC0, 0x0D80, 0xCD41, 0x0F00, 0xCFC1, 0xCE81, 0x0E40, XX 0x0A00, 0xCAC1, 0xCB81, 0x0B40, 0xC901, 0x09C0, 0x0880, 0xC841, XX 0xD801, 0x18C0, 0x1980, 0xD941, 0x1B00, 0xDBC1, 0xDA81, 0x1A40, XX 0x1E00, 0xDEC1, 0xDF81, 0x1F40, 0xDD01, 0x1DC0, 0x1C80, 0xDC41, XX 0x1400, 0xD4C1, 0xD581, 0x1540, 0xD701, 0x17C0, 0x1680, 0xD641, XX 0xD201, 0x12C0, 0x1380, 0xD341, 0x1100, 0xD1C1, 0xD081, 0x1040, XX 0xF001, 0x30C0, 0x3180, 0xF141, 0x3300, 0xF3C1, 0xF281, 0x3240, XX 0x3600, 0xF6C1, 0xF781, 0x3740, 0xF501, 0x35C0, 0x3480, 0xF441, XX 0x3C00, 0xFCC1, 0xFD81, 0x3D40, 0xFF01, 0x3FC0, 0x3E80, 0xFE41, XX 0xFA01, 0x3AC0, 0x3B80, 0xFB41, 0x3900, 0xF9C1, 0xF881, 0x3840, XX 0x2800, 0xE8C1, 0xE981, 0x2940, 0xEB01, 0x2BC0, 0x2A80, 0xEA41, XX 0xEE01, 0x2EC0, 0x2F80, 0xEF41, 0x2D00, 0xEDC1, 0xEC81, 0x2C40, XX 0xE401, 0x24C0, 0x2580, 0xE541, 0x2700, 0xE7C1, 0xE681, 0x2640, XX 0x2200, 0xE2C1, 0xE381, 0x2340, 0xE101, 0x21C0, 0x2080, 0xE041, XX 0xA001, 0x60C0, 0x6180, 0xA141, 0x6300, 0xA3C1, 0xA281, 0x6240, XX 0x6600, 0xA6C1, 0xA781, 0x6740, 0xA501, 0x65C0, 0x6480, 0xA441, XX 0x6C00, 0xACC1, 0xAD81, 0x6D40, 0xAF01, 0x6FC0, 0x6E80, 0xAE41, XX 0xAA01, 0x6AC0, 0x6B80, 0xAB41, 0x6900, 0xA9C1, 0xA881, 0x6840, XX 0x7800, 0xB8C1, 0xB981, 0x7940, 0xBB01, 0x7BC0, 0x7A80, 0xBA41, XX 0xBE01, 0x7EC0, 0x7F80, 0xBF41, 0x7D00, 0xBDC1, 0xBC81, 0x7C40, XX 0xB401, 0x74C0, 0x7580, 0xB541, 0x7700, 0xB7C1, 0xB681, 0x7640, XX 0x7200, 0xB2C1, 0xB381, 0x7340, 0xB101, 0x71C0, 0x7080, 0xB041, XX 0x5000, 0x90C1, 0x9181, 0x5140, 0x9301, 0x53C0, 0x5280, 0x9241, XX 0x9601, 0x56C0, 0x5780, 0x9741, 0x5500, 0x95C1, 0x9481, 0x5440, XX 0x9C01, 0x5CC0, 0x5D80, 0x9D41, 0x5F00, 0x9FC1, 0x9E81, 0x5E40, XX 0x5A00, 0x9AC1, 0x9B81, 0x5B40, 0x9901, 0x59C0, 0x5880, 0x9841, XX 0x8801, 0x48C0, 0x4980, 0x8941, 0x4B00, 0x8BC1, 0x8A81, 0x4A40, XX 0x4E00, 0x8EC1, 0x8F81, 0x4F40, 0x8D01, 0x4DC0, 0x4C80, 0x8C41, XX 0x4400, 0x84C1, 0x8581, 0x4540, 0x8701, 0x47C0, 0x4680, 0x8641, XX 0x8201, 0x42C0, 0x4380, 0x8341, 0x4100, 0x81C1, 0x8081, 0x4040 XX}; XX XXINT XXaddcrc(crc, c) /* update a CRC check */ XX INT crc; /* running CRC value */ XX unsigned char c; /* character to add */ XX{ XX return ((crc >> 8) & 0x00ff) ^ crctab[(crc ^ c) & 0x00ff]; XX} SHAR_EOF if test 5470 -ne "`wc -c arcsvc.c`" then echo shar: error transmitting arcsvc.c '(should have been 5470 characters)' fi echo shar: extracting arctst.c '(1437 characters)' sed 's/^XX//' << \SHAR_EOF > arctst.c XX/* XX * $Log: arctst.c,v $ XX * Revision 1.3 87/08/13 17:06:06 hyc XX * Run thru indent, fixed some signed vs. unsigned problems XX * with bp <-> buf, and inbuf and localbuf... XX * Revision 1.2 87/07/21 09:24:37 hyc *** empty XX * log message *** XX * XX */ XX XX/* XX * ARC - Archive utility - ARCTST XX * XX * Version 2.12, created on 02/03/86 at 23:00:40 XX * XX * (C) COPYRIGHT 1985 by System Enhancement Associates; ALL RIGHTS RESERVED XX * XX * By: Thom Henderson XX * XX * Description: This file contains the routines used to test archive integrity. XX * XX * Language: Computer Innovations Optimizing C86 XX */ XX#include <stdio.h> XX#include "arc.h" XX XXINT XXtstarc() XX{ /* test integrity of an archive */ XX struct heads hdr; /* file header */ XX LONG arcsize, ftell(); /* archive size */ XX XX openarc(0); /* open archive for reading */ XX fseek(arc, 0L, 2); /* move to end of archive */ XX arcsize = ftell(arc); /* see how big it is */ XX fseek(arc, 0L, 0); /* return to top of archive */ XX XX while (readhdr(&hdr, arc)) { XX if (ftell(arc) + hdr.size > arcsize) { XX printf("Archive truncated in file %s\n", hdr.name); XX nerrs++; XX break; XX } else { XX printf("Testing file: %-12s ", hdr.name); XX fflush(stdout); XX if (unpack(arc, NULL, &hdr)) XX nerrs++; XX else XX printf("okay\n"); XX } XX } XX XX if (nerrs < 1) XX printf("No errors detected\n"); XX else if (nerrs == 1) XX printf("One error detected\n"); XX else XX printf("%d errors detected\n", nerrs); XX} SHAR_EOF if test 1437 -ne "`wc -c arctst.c`" then echo shar: error transmitting arctst.c '(should have been 1437 characters)' fi echo shar: extracting arcunp.c '(5622 characters)' sed 's/^XX//' << \SHAR_EOF > arcunp.c XX/* XX * $Log: arcunp.c,v $ XX * Revision 1.1 88/04/11 18:42:39 hyc XX * Initial revision XX * XX * Revision 1.3 87/12/20 03:10:14 hyc XX * Ah hah! The value fgetc was returning was getting sign extended! XX * Thus, 0xff was indistinguishable from EOF, causing the premature XX * termination... The solution is to use getc, which doesn't do this XX * (on the Apollos, anyway...) XX * XX * Note that I could *not* duplicate this behavior in a 5 liner...? XX * XX * Revision 1.2 87/12/19 04:11:22 hyc XX * Move image mode code around from MTS only to non-MSDOS. XX * XX * Revision 1.1 87/12/19 04:06:39 hyc XX * Initial revision XX * XX * Revision 1.3 87/08/13 17:06:08 hyc XX * Run thru indent, fixed some signed vs. unsigned problems XX * with bp <-> buf, and inbuf and localbuf... XX * Revision 1.2 87/07/21 09:28:31 hyc *** empty XX * log message *** XX * XX */ XX XX/* XX * ARC - Archive utility - ARCUNP XX * XX * Version 3.17, created on 02/13/86 at 10:20:08 XX * XX * (C) COPYRIGHT 1985 by System Enhancement Associates; ALL RIGHTS RESERVED XX * XX * By: Thom Henderson XX * XX * Description: This file contains the routines used to expand a file when XX * taking it out of an archive. XX * XX * Language: Computer Innovations Optimizing C86 XX */ XX#include <stdio.h> XX#include "arc.h" XX XX/* stuff for repeat unpacking */ XX XX#define DLE 0x90 /* repeat byte flag */ XX XXstatic INT state; /* repeat unpacking state */ XX XX/* repeat unpacking states */ XX XX#define NOHIST 0 /* no relevant history */ XX#define INREP 1 /* sending a repeated value */ XX XXstatic INT crcval; /* CRC check value */ XXstatic LONG size; /* bytes to read */ XX XXINT XXunpack(f, t, hdr) /* unpack an archive entry */ XX FILE *f, *t; /* source, destination */ XX struct heads *hdr; /* pointer to file header data */ XX{ XX INT c; /* one char of stream */ XX INT putc_unp(); XX INT putc_ncr(); XX INT getc_unp(); XX XX /* setups common to all methods */ XX XX crcval = 0; /* reset CRC check value */ XX size = hdr->size; /* set input byte counter */ XX state = NOHIST; /* initial repeat unpacking state */ XX setcode(); /* set up for decoding */ XX XX /* use whatever method is appropriate */ XX XX switch (hdrver) { /* choose proper unpack method */ XX case 1: /* standard packing */ XX case 2: XX while ((c = getc_unp(f)) != EOF) XX putc_unp(c, t); XX break; XX XX case 3: /* non-repeat packing */ XX while ((c = getc_unp(f)) != EOF) XX putc_ncr(c, t); XX break; XX XX case 4: /* Huffman squeezing */ XX init_usq(f); XX while ((c = getc_usq(f)) != EOF) XX putc_ncr(c, t); XX break; XX XX case 5: /* Lempel-Zev compression */ XX init_ucr(0); XX while ((c = getc_ucr(f)) != EOF) XX putc_unp(c, t); XX break; XX XX case 6: /* Lempel-Zev plus non-repeat */ XX init_ucr(0); XX while ((c = getc_ucr(f)) != EOF) XX putc_ncr(c, t); XX break; XX XX case 7: /* L-Z plus ncr with new hash */ XX init_ucr(1); XX while ((c = getc_ucr(f)) != EOF) XX putc_ncr(c, t); XX break; XX XX case 8: /* dynamic Lempel-Zev */ XX decomp(f, t); XX break; XX XX case 9: /* Squashing */ XX sqdecomp(f, t); XX break; XX XX default: /* unknown method */ XX if (warn) { XX printf("I don't know how to unpack file %s\n", hdr->name); XX printf("I think you need a newer version of ARC\n"); XX nerrs++; XX } XX fseek(f, hdr->size, 1); /* skip over bad file */ XX return 1; /* note defective file */ XX } XX XX /* cleanups common to all methods */ XX XX if (crcval != hdr->crc) { XX if (warn || kludge) { XX printf("WARNING: File %s fails CRC check\n", hdr->name); XX nerrs++; XX } XX return 1; /* note defective file */ XX } XX return 0; /* file is okay */ XX} XX XX/* XX * This routine is used to put bytes in the output file. It also performs XX * various housekeeping functions, such as maintaining the CRC check value. XX */ XX XXINT XXputc_unp(c, t) /* output an unpacked byte */ XX char c; /* byte to output */ XX FILE *t; /* file to output to */ XX{ XX crcval = addcrc(crcval, c); /* update the CRC check value */ XX#ifdef MTS XX if (!image) XX atoe(&c, 1); XX#endif XX#ifndef MSDOS XX if ((c != '\r') || image) XX#endif XX putc_tst(c, t); XX} XX XX/* XX * This routine is used to decode non-repeat compression. Bytes are passed XX * one at a time in coded format, and are written out uncoded. The data is XX * stored normally, except that runs of more than two characters are XX * represented as: XX * XX * <char> <DLE> <count> XX * XX * With a special case that a count of zero indicates a DLE as data, not as a XX * repeat marker. XX */ XX XXINT XXputc_ncr(c, t) /* put NCR coded bytes */ XX unsigned char c; /* next byte of stream */ XX FILE *t; /* file to receive data */ XX{ XX static INT lastc; /* last character seen */ XX XX switch (state) { /* action depends on our state */ XX case NOHIST: /* no previous history */ XX if (c == DLE) /* if starting a series */ XX state = INREP; /* then remember it next time */ XX else XX putc_unp(lastc = c, t); /* else nothing unusual */ XX return; XX XX case INREP: /* in a repeat */ XX if (c) /* if count is nonzero */ XX while (--c) /* then repeatedly ... */ XX putc_unp(lastc, t); /* ... output the byte */ XX else XX putc_unp(DLE, t); /* else output DLE as data */ XX state = NOHIST; /* back to no history */ XX return; XX XX default: XX abort("Bad NCR unpacking state (%d)", state); XX } XX} XX XX/* XX * This routine provides low-level byte input from an archive. This routine XX * MUST be used, as end-of-file is simulated at the end of the archive entry. XX */ XX XXINT XXgetc_unp(f) /* get a byte from an archive */ XX FILE *f; /* archive file to read */ XX{ XX register INT xx; XX if (!size) /* if no data left */ XX return EOF; /* then pretend end of file */ XX XX size--; /* deduct from input counter */ XX xx = getc(f); XX return code(xx); /* and return next decoded byte */ XX} SHAR_EOF if test 5622 -ne "`wc -c arcunp.c`" then echo shar: error transmitting arcunp.c '(should have been 5622 characters)' fi echo shar: extracting arcusq.c '(2678 characters)' sed 's/^XX//' << \SHAR_EOF > arcusq.c XX/* XX * $Log: arcusq.c,v $ XX * Revision 1.1 88/04/11 18:45:37 hyc XX * Initial revision XX * XX * Revision 1.3 87/08/13 17:06:12 hyc XX * Run thru indent, fixed some signed vs. unsigned problems XX * with bp <-> buf, and inbuf and localbuf... XX * Revision 1.2 87/07/21 09:31:43 hyc *** empty XX * log message *** XX * XX */ XX XX/* XX * ARC - Archive utility - ARCUSQ XX * XX * Version 3.14, created on 07/25/86 at 13:04:19 XX * XX * (C) COPYRIGHT 1985 by System Enhancement Associates; ALL RIGHTS RESERVED XX * XX * By: Thom Henderson XX * XX * Description: This file contains the routines used to expand a file which was XX * packed using Huffman squeezing. XX * XX * Most of this code is taken from an USQ program by Richard Greenlaw, which was XX * adapted to CI-C86 by Robert J. Beilstein. XX * XX * Language: Computer Innovations Optimizing C86 XX */ XX#include <stdio.h> XX#include "arc.h" XX XX/* stuff for Huffman unsqueezing */ XX XX#define ERROR (-1) XX XX#define SPEOF 256 /* special endfile token */ XX#define NUMVALS 257 /* 256 data values plus SPEOF */ XX XXstruct nd { /* decoding tree */ XX INT child[2]; /* left, right */ XX} node[NUMVALS]; /* use large buffer */ XX XXstatic INT bpos; /* last bit position read */ XXstatic INT curin; /* last byte value read */ XXstatic INT numnodes; /* number of nodes in decode tree */ XX XXstatic INT XXget_int(f) /* get an integer */ XX FILE *f; /* file to get it from */ XX{ XX return (getc_unp(f) | (getc_unp(f) << 8)) & 0xFFFF; XX} XX XXINT XXinit_usq(f) /* initialize Huffman unsqueezing */ XX FILE *f; /* file containing squeezed data */ XX{ XX INT i; /* node index */ XX XX bpos = 99; /* force initial read */ XX XX numnodes = get_int(f); XX XX if (numnodes < 0 || numnodes >= NUMVALS) XX abort("File has an invalid decode tree"); XX XX /* initialize for possible empty tree (SPEOF only) */ XX XX node[0].child[0] = -(SPEOF + 1); XX node[0].child[1] = -(SPEOF + 1); XX XX for (i = 0; i < numnodes; ++i) { /* get decoding tree from XX * file */ XX node[i].child[0] = get_int(f); XX node[i].child[1] = get_int(f); XX } XX} XX XXint XXgetc_usq(f) /* get byte from squeezed file */ XX FILE *f; /* file containing squeezed data */ XX{ XX int i; /* tree index */ XX XX /* follow bit stream in tree to a leaf */ XX XX for (i = 0; i >= 0;) { /* work down(up?) from root */ XX if (++bpos > 7) { XX if ((curin = getc_unp(f)) == ERROR) XX return (ERROR); XX bpos = 0; XX XX /* move a level deeper in tree */ XX i = node[i].child[1 & curin]; XX } else XX i = node[i].child[1 & (curin >>= 1)]; XX } XX XX /* decode fake node index to original data value */ XX XX i = -(i + 1); XX XX /* decode special endfile token to normal EOF */ XX XX i = (i == SPEOF) ? EOF : i; XX return i; XX} SHAR_EOF if test 2678 -ne "`wc -c arcusq.c`" then echo shar: error transmitting arcusq.c '(should have been 2678 characters)' fi echo shar: extracting dtime.c '(9035 characters)' sed 's/^XX//' << \SHAR_EOF > dtime.c XX/* dtime.c - routines to do ``ARPA-style'' time structures XX XXver date who remarks XX--- ------- --- ------------------------------------------------------------- XX01B 15nov86 JP Thouroughly hacked by Jef Poskanzer. XX01A ??????? MTR Original version from the MH 6.5 distribution, courtesy XX of Marshall Rose. XX XX*/ XX XX XX#include "tws.h" XX#include <stdio.h> XX#include <sys/types.h> XX#include <time.h> XX#ifdef SYS5 XX#include <string.h> XX#else SYS5 XX#include <strings.h> XX#include <sys/timeb.h> XX#endif SYS5 XX XX#ifdef SYS5 XXextern int daylight; XXextern long timezone; XXextern char *tzname[]; XX#endif SYS5 XX XX/* */ XX XX#define abs(a) ( a >= 0 ? a : -a ) XX XXchar *tw_moty[] = { XX "Jan", "Feb", "Mar", "Apr", "May", "Jun", XX "Jul", "Aug", "Sep", "Oct", "Nov", "Dec", NULL }; XX XXchar *tw_dotw[] = { XX "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat", NULL }; XX XXchar *tw_ldotw[] = { XX "Sunday", "Monday", "Tuesday", "Wednesday", XX "Thursday", "Friday", "Saturday", NULL }; XX XX/* */ XX XXstatic struct zone XX { XX char *std; XX char *dst; XX int shift; XX } XX zones[] = { XX "GMT", "BST", 0, XX "EST", "EDT", -5, XX "CST", "CDT", -6, XX "MST", NULL, -7, XX "PST", "PDT", -8, XX "A", NULL, -1, XX "B", NULL, -2, XX "C", NULL, -3, XX "D", NULL, -4, XX "E", NULL, -5, XX "F", NULL, -6, XX "G", NULL, -7, XX "H", NULL, -8, XX "I", NULL, -9, XX "K", NULL, -10, XX "L", NULL, -11, XX "M", NULL, -12, XX "N", NULL, 1, XX#ifndef HUJI XX "O", NULL, 2, XX#else HUJI XX "JST", "JDT", 2, XX#endif HUJI XX "P", NULL, 3, XX "Q", NULL, 4, XX "R", NULL, 5, XX "S", NULL, 6, XX "T", NULL, 7, XX "U", NULL, 8, XX "V", NULL, 9, XX "W", NULL, 10, XX "X", NULL, 11, XX "Y", NULL, 12, XX NULL }; XX XX#define CENTURY 19 XX XXlong time( ); XXstruct tm *localtime( ); XX XX/* */ XX XXchar *dtimenow( ) XX { XX long clock; XX XX (void) time( &clock ); XX return ( dtime( &clock ) ); XX } XX XX XXchar * XXdctime( tw ) XXstruct tws *tw; XX { XX static char buffer[25]; XX XX if ( tw == NULL ) XX return ( NULL ); XX XX (void) sprintf( buffer, "%.3s %.3s %02d %02d:%02d:%02d %.4d\n", XX tw_dotw[tw -> tw_wday], tw_moty[tw -> tw_mon], tw -> tw_mday, XX tw -> tw_hour, tw -> tw_min, tw -> tw_sec, XX tw -> tw_year >= 100 ? tw -> tw_year : 1900 + tw -> tw_year ); XX XX return ( buffer ); XX } XX XX/* */ XX XXstruct tws * XXdtwstime( ) XX { XX long clock; XX XX (void) time( &clock ); XX return ( dlocaltime( &clock ) ); XX } XX XX XXstruct tws * XXdlocaltime( clock ) XXlong *clock; XX { XX register struct tm *tm; XX#ifndef SYS5 XX struct timeb tb; XX#endif not SYS5 XX static struct tws tw; XX XX if ( clock == NULL ) XX return ( NULL ); XX tw.tw_flags = TW_NULL; XX XX tm = localtime( clock ); XX tw.tw_sec = tm -> tm_sec; XX tw.tw_min = tm -> tm_min; XX tw.tw_hour = tm -> tm_hour; XX tw.tw_mday = tm -> tm_mday; XX tw.tw_mon = tm -> tm_mon; XX tw.tw_year = tm -> tm_year; XX tw.tw_wday = tm -> tm_wday; XX tw.tw_yday = tm -> tm_yday; XX if ( tm -> tm_isdst ) XX tw.tw_flags |= TW_DST; XX#ifndef SYS5 XX ftime( &tb ); XX tw.tw_zone = -tb.timezone; XX#else SYS5 XX tzset( ); XX tw.tw_zone = -(timezone / 60); XX#endif SYS5 XX tw.tw_flags &= ~TW_SDAY; XX tw.tw_flags |= TW_SEXP; XX tw.tw_clock = *clock; XX XX return ( &tw ); XX } XX XX XXstruct tws * XXdgmtime( clock ) XXlong *clock; XX { XX register struct tm *tm; XX static struct tws tw; XX XX if ( clock == NULL ) XX return ( NULL ); XX tw.tw_flags = TW_NULL; XX XX tm = gmtime( clock ); XX tw.tw_sec = tm -> tm_sec; XX tw.tw_min = tm -> tm_min; XX tw.tw_hour = tm -> tm_hour; XX tw.tw_mday = tm -> tm_mday; XX tw.tw_mon = tm -> tm_mon; XX tw.tw_year = tm -> tm_year; XX tw.tw_wday = tm -> tm_wday; XX tw.tw_yday = tm -> tm_yday; XX if ( tm -> tm_isdst ) XX tw.tw_flags |= TW_DST; XX tw.tw_zone = 0; XX tw.tw_flags &= ~TW_SDAY; XX tw.tw_flags |= TW_SEXP; XX tw.tw_clock = *clock; XX XX return( &tw ); XX } XX XX/* */ XX XXchar * XXdasctime( tw, flags ) XXstruct tws *tw; XXint flags; XX { XX static char buffer[80], result[80]; XX XX if ( tw == NULL ) XX return ( NULL ); XX XX (void) sprintf( buffer, "%02d %s %02d %02d:%02d:%02d %s", XX tw -> tw_mday, tw_moty[tw -> tw_mon], tw -> tw_year, XX tw -> tw_hour, tw -> tw_min, tw -> tw_sec, XX dtimezone( tw -> tw_zone, tw -> tw_flags | flags ) ); XX XX if ( (tw -> tw_flags & TW_SDAY) == TW_SEXP ) XX (void) sprintf( result, "%s, %s", tw_dotw[tw -> tw_wday], buffer ); XX else XX if ( (tw -> tw_flags & TW_SDAY) == TW_SNIL ) XX (void) strcpy( result, buffer ); XX else XX (void) sprintf( result, "%s (%s)", buffer, tw_dotw[tw -> tw_wday] ); XX XX return ( result ); XX } XX XX/* */ XX XXchar * XXdtimezone( offset, flags ) XXint offset, flags; XX { XX register int hours, mins; XX register struct zone *z; XX static char buffer[10]; XX XX if ( offset < 0 ) XX { XX mins = -((-offset) % 60); XX hours = -((-offset) / 60); XX } XX else XX { XX mins = offset % 60; XX hours = offset / 60; XX } XX XX if ( !(flags & TW_ZONE) && mins == 0 ) XX for ( z = zones; z -> std; z++ ) XX if ( z -> shift == hours ) XX return ( z -> dst && (flags & TW_DST) ? z -> dst : z -> std ); XX XX#ifdef DSTXXX XX if ( flags & TW_DST ) XX hours += 1; XX#endif DSTXXX XX (void) sprintf( buffer, "%s%02d%02d", XX offset < 0 ? "-" : "+", abs( hours ), abs( mins ) ); XX return ( buffer ); XX } XX XX/* */ XX XXvoid XXtwscopy( tb, tw ) XXstruct tws *tb, *tw; XX { XX#ifdef notdef XX tb -> tw_sec = tw -> tw_sec; XX tb -> tw_min = tw -> tw_min; XX tb -> tw_hour = tw -> tw_hour; XX tb -> tw_mday = tw -> tw_mday; XX tb -> tw_mon = tw -> tw_mon; XX tb -> tw_year = tw -> tw_year; XX tb -> tw_wday = tw -> tw_wday; XX tb -> tw_yday = tw -> tw_yday; XX tb -> tw_zone = tw -> tw_zone; XX tb -> tw_clock = tw -> tw_clock; XX tb -> tw_flags = tw -> tw_flags; XX#else not notdef XX *tb = *tw; XX#endif not notdef XX } XX XX XXint XXtwsort( tw1, tw2 ) XXstruct tws *tw1, *tw2; XX { XX register long c1, c2; XX XX (void) twclock( tw1 ); XX (void) twclock( tw2 ); XX XX return ( (c1 = tw1 -> tw_clock) > (c2 = tw2 -> tw_clock) ? 1 XX : c1 == c2 ? 0 : -1 ); XX } XX XX/* */ XX XX XX/* Julian day number of the Unix* clock's origin, 01 Jan 1970. */ XX#define JD1970 2440587L XX XX XXlong XXtwjuliandate( tw ) XXstruct tws *tw; XX { XX register int mday, mon, year; XX register long a, b; XX double jd; XX XX if ( (mday = tw -> tw_mday) < 1 || mday > 31 || XX (mon = tw -> tw_mon + 1) < 1 || mon > 12 || XX (year = tw -> tw_year) < 1 || year > 10000 ) XX return ( -1L ); XX if ( year < 100 ) XX year += CENTURY * 100; XX XX if ( mon == 1 || mon == 2 ) XX { XX --year; XX mon += 12; XX } XX if ( year < 1583 ) XX return ( -1L ); XX a = year / 100; XX b = 2 - a + a / 4; XX b += (long) ( (double) year * 365.25 ); XX b += (long) ( 30.6001 * ( (double) mon + 1.0 ) ); XX jd = mday + b + 1720994.5; XX return ( (long) jd ); XX } XX XX XXlong XXtwsubdayclock( tw ) XXstruct tws *tw; XX { XX register int i, sec, min, hour; XX register long result; XX XX if ( (sec = tw -> tw_sec) < 0 || sec > 59 || XX (min = tw -> tw_min) < 0 || min > 59 || XX (hour = tw -> tw_hour) < 0 || hour > 23 ) XX return ( -1L ); XX XX result = ( hour * 60 + min ) * 60 + sec; XX result -= 60 * tw -> tw_zone; XX if ( tw -> tw_flags & TW_DST ) XX result -= 60 * 60; XX XX return ( result ); XX } XX XX XXlong XXtwclock( tw ) XXstruct tws *tw; XX { XX register long jd, sdc, result; XX XX if ( tw -> tw_clock != 0L ) XX return ( tw -> tw_clock ); XX XX if ( ( jd = twjuliandate( tw ) ) == -1L ) XX return ( tw -> tw_clock = -1L ); XX if ( ( sdc = twsubdayclock( tw ) ) == -1L ) XX return ( tw -> tw_clock = -1L );