/* Copyright (c) 1990, 1991 UNIX System Laboratories, Inc. */ /* Copyright (c) 1984, 1986, 1987, 1988, 1989, 1990 AT&T */ /* All Rights Reserved */ /* THIS IS UNPUBLISHED PROPRIETARY SOURCE CODE OF */ /* UNIX System Laboratories, Inc. */ /* The copyright notice above does not evidence any */ /* actual or intended publication of such source code. */ /* Portions Copyright (c) 1988, Sun Microsystems, Inc. */ /* All Rights Reserved. */ #ident "@(#)touch:touch.c 1.11.1.2" /* Copyright (c) 1987, 1988 Microsoft Corporation */ /* All Rights Reserved */ /* This Module contains Proprietary Information of Microsoft */ /* Corporation and should be treated as Confidential. */ #include #include #include #include #include #include #include #include #include #include #include #include #define dysize(y) \ (((((y) % 4) == 0 && ((y) % 100) != 0) || ((y) % 400) == 0) ? 366 : 365) struct stat64 stbuf; int status; int dmsize[12]={31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; char *cbp; time_t timbuf; gtime(int which, size_t len) { register int i, y, t; int d, h, m; long nt; int c = 0; /* entered century value */ int s = 0; /* entered seconds value */ int point = 0; /* relative byte position of decimal point */ int ssdigits = 0; /* count seconds digits include decimal pnt */ int noyear = 0; /* 0 means year is entered; 1 means none */ tzset(); /* * mmddhhmm is a total of 8 bytes min */ if (len < 8) return(1); if (which) { /* if '1'; means -t option */ /* * -t [[cc]yy]mmddhhmm[.ss] is a total of 15 bytes max */ if (len > 15) return(1); /* * Determine the decimal point position, if any. */ for (i=0; i 2) || ((len - (point + 1)) < 2)) ) { return(1); } /* * -t [[cc]yy]mmddhhmm.[ss] is greater than 12 bytes * -t [yy]mmddhhmm.[ss] is greater than 12 bytes * * If there is no decimal present and the length is greater * than 12 bytes, then error terminate. */ if (!point && (len > 12)) return(1); switch(len) { case 11: if (*(cbp + 8) != '.') return(1); break; case 13: if (*(cbp + 10) != '.') return(1); break; case 15: if (*(cbp + 12) != '.') return(1); break; } if (!point) ssdigits = 0; else ssdigits = ((len - point) + 1); if ((len - ssdigits) > 10) { /* * -t ccyymmddhhmm is the input */ /* detemine c -- century number */ c = gpair(); /* detemine y -- year number */ y = gpair(); if (y<0) { (void) time(&nt); y = localtime(&nt)->tm_year; } if ((c != 19) && ((y >= 69) && (y <= 99))) return(1); if ((c != 20) && ((y >= 0) && (y <= 68))) return(1); goto mm_next; } if ((len - ssdigits) > 8) { /* * -t yymmddhhmm is the input */ /* detemine yy -- year number */ y = gpair(); if (y<0) { (void) time(&nt); y = localtime(&nt)->tm_year; } if ((y >= 69) && (y <= 99)) c = 19; /* 19th century */ if ((y >= 0) && (y <= 68)) c = 20; /* 20th century */ goto mm_next; } if ((len - ssdigits) < 10) { /* * -t mmddhhmm is the input */ noyear++; } } mm_next: t = gpair(); if(t<1 || t>12) return(1); d = gpair(); if(d<1 || d>31) return(1); h = gpair(); if(h == 24) { h = 0; d++; } m = gpair(); if(m<0 || m>59) return(1); if (!which) { /* * There wasn't a "-t" input. */ y = gpair(); if (y<0) { (void) time(&nt); y = localtime(&nt)->tm_year % 100; } if ((y >= 69) && (y <= 99)) c = 19; /* 19th century */ if ((y >= 0) && (y <= 68)) c = 20; /* 20th century */ } else { /* * There was a "-t" input. * If there is a decimal get the seconds inout */ if (point) { cbp++; /* skip over decimal point */ s = gpair(); /* get [ss] */ if (s<0) { return(1); } if (!((s >= 0) && (s <= 61))) return(1); } if (noyear) { (void) time(&nt); y = localtime(&nt)->tm_year; } } if (*cbp == 'p') h += 12; if (h<0 || h>23) return(1); timbuf = 0; if (c && (c == 20)) y += 2000; else y += 1900; for(i=1970; i= 3) timbuf += 1; while(--t) timbuf += dmsize[t-1]; timbuf += (d-1); timbuf *= 24; timbuf += h; timbuf *= 60; timbuf += m; timbuf *= 60; timbuf += s; return(0); } gpair() { register int c, d; register char *cp; cp = cbp; if(*cp == 0) return(-1); c = (*cp++ - '0') * 10; if (c<0 || c>100) return(-1); if(*cp == 0) return(-1); if ((d = *cp++ - '0') < 0 || d > 9) return(-1); cbp = cp; return (c+d); } /* * Could this string be a datetime specification of the form "mmddhhmm[yy]"? * If it contains all digits and is 8 or 10 digits long, then it could be; * otherwise it isn't. */ static isdatetime(s) char *s; { register int c; register int i = 0; while(c = s[i]) { if(!isdigit(c)) return(0); i++; } if (i != 8 && i != 10) return(0); else return(1); } main(argc, argv) char *argv[]; { register c; #ifdef sgi struct utimbuf times; #else struct utbuf { time_t actime, modtime; } times; #endif int mflg=1, aflg=1, cflg=0, fflg=0, nflg=0, errflg=0, optc, fd; int rflg=0, tflg=0; int stflg=0; char *proto; char *dashr_file = 0; struct stat64 prstbuf; char *usage_OB = ":583:Usage: %s [%s] [mmddhhmm[yy]] file ...\n"; char *usage_XOP = ":Usage: %s [%s] [%s | %s] files\n"; char form_XOP[100]; char *tusage = "-amc"; char *susage = "-f file"; char *rusage = "-r ref_file"; char *t_usage = "-t [[cc]yy]mmddhhmm[.ss]"; char *susageid = ":584"; extern char *optarg, *basename(); extern int optind; int i, k; (void)setlocale(LC_ALL, ""); (void)setcat("uxcore.abi"); argv[0] = basename(argv[0]); if (!strcmp(argv[0], "settime")) { (void)setlabel("UX:settime"); while ((optc = getopt(argc, argv, "f:")) != EOF) switch (optc) { case 'f': fflg++; proto = optarg; break; default: errflg++; break; }; stflg = 1; ++cflg; } else { (void)setlabel("UX:touch"); while ((optc=getopt(argc, argv, "amcfr:t:")) != EOF) switch(optc) { case 'm': mflg++; aflg--; break; case 'a': aflg++; mflg--; break; case 'c': cflg++; break; case 'f': break; /* silently ignore */ case 'r': rflg++; dashr_file = optarg; break; case 't': tflg++; cbp= optarg; break; case '?': errflg++; } } if( ((argc-optind) < 1) || errflg || (rflg && tflg) || (fflg && rflg) || (tflg && stflg) || (rflg && stflg) ) { if (!errflg) pfmt(stderr, MM_ERROR, ":8:Incorrect usage\n"); (void) pfmt(stderr, MM_ACTION, usage_OB, argv[0], stflg ? gettxt(susageid, susage) : tusage); if (!stflg) { for(i=0; i= 3)) { cbp = (char *)argv[optind++];; } } if(gtime(tflg, (size_t)strlen(cbp))) { (void) pfmt(stderr, MM_ERROR, ":585:Bad date conversion\n"); exit(2); } timbuf += timezone; if (localtime(&timbuf)->tm_isdst) timbuf += -1*60*60; prstbuf.st_mtime = prstbuf.st_atime = timbuf; } got_dashr: for(c=optind; c