date.c revision 1.20
1219820Sjeff/* $NetBSD: date.c,v 1.20 1998/01/20 22:06:02 mycroft Exp $ */ 2219820Sjeff 3219820Sjeff/* 4219820Sjeff * Copyright (c) 1985, 1987, 1988, 1993 5219820Sjeff * The Regents of the University of California. All rights reserved. 6219820Sjeff * 7219820Sjeff * Redistribution and use in source and binary forms, with or without 8219820Sjeff * modification, are permitted provided that the following conditions 9219820Sjeff * are met: 10219820Sjeff * 1. Redistributions of source code must retain the above copyright 11219820Sjeff * notice, this list of conditions and the following disclaimer. 12219820Sjeff * 2. Redistributions in binary form must reproduce the above copyright 13219820Sjeff * notice, this list of conditions and the following disclaimer in the 14219820Sjeff * documentation and/or other materials provided with the distribution. 15219820Sjeff * 3. All advertising materials mentioning features or use of this software 16219820Sjeff * must display the following acknowledgement: 17219820Sjeff * This product includes software developed by the University of 18219820Sjeff * California, Berkeley and its contributors. 19219820Sjeff * 4. Neither the name of the University nor the names of its contributors 20219820Sjeff * may be used to endorse or promote products derived from this software 21219820Sjeff * without specific prior written permission. 22219820Sjeff * 23219820Sjeff * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 24219820Sjeff * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 25219820Sjeff * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 26219820Sjeff * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 27219820Sjeff * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 28219820Sjeff * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 29219820Sjeff * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 30219820Sjeff * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 31219820Sjeff * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 32219820Sjeff * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 33219820Sjeff * SUCH DAMAGE. 34219820Sjeff */ 35219820Sjeff 36219820Sjeff#include <sys/cdefs.h> 37219820Sjeff#ifndef lint 38219820Sjeff__COPYRIGHT( 39219820Sjeff"@(#) Copyright (c) 1985, 1987, 1988, 1993\n\ 40219820Sjeff The Regents of the University of California. All rights reserved.\n"); 41219820Sjeff#endif /* not lint */ 42219820Sjeff 43219820Sjeff#ifndef lint 44219820Sjeff#if 0 45219820Sjeffstatic char sccsid[] = "@(#)date.c 8.2 (Berkeley) 4/28/95"; 46219820Sjeff#else 47219820Sjeff__RCSID("$NetBSD: date.c,v 1.20 1998/01/20 22:06:02 mycroft Exp $"); 48219820Sjeff#endif 49219820Sjeff#endif /* not lint */ 50219820Sjeff 51219820Sjeff#include <sys/param.h> 52219820Sjeff#include <sys/time.h> 53219820Sjeff 54219820Sjeff#include <ctype.h> 55219820Sjeff#include <err.h> 56219820Sjeff#include <fcntl.h> 57219820Sjeff#include <stdio.h> 58219820Sjeff#include <stdlib.h> 59219820Sjeff#include <string.h> 60219820Sjeff#include <locale.h> 61219820Sjeff#include <syslog.h> 62219820Sjeff#include <tzfile.h> 63219820Sjeff#include <unistd.h> 64219820Sjeff#include <util.h> 65219820Sjeff 66219820Sjeff#include "extern.h" 67219820Sjeff 68219820Sjefftime_t tval; 69219820Sjeffint retval, nflag; 70219820Sjeff 71219820Sjeffint main __P((int, char *[])); 72219820Sjeffstatic void setthetime __P((char *)); 73219820Sjeffstatic void badformat __P((void)); 74219820Sjeffstatic void usage __P((void)); 75219820Sjeff 76219820Sjeffint 77219820Sjeffmain(argc, argv) 78219820Sjeff int argc; 79219820Sjeff char *argv[]; 80219820Sjeff{ 81219820Sjeff extern int optind; 82219820Sjeff extern char *optarg; 83219820Sjeff int ch, rflag; 84219820Sjeff char *format, buf[1024]; 85219820Sjeff 86219820Sjeff (void)setlocale(LC_ALL, ""); 87219820Sjeff 88219820Sjeff rflag = 0; 89219820Sjeff while ((ch = getopt(argc, argv, "nr:u")) != -1) 90219820Sjeff switch((char)ch) { 91219820Sjeff case 'n': /* don't set network */ 92219820Sjeff nflag = 1; 93219820Sjeff break; 94219820Sjeff case 'r': /* user specified seconds */ 95219820Sjeff rflag = 1; 96219820Sjeff tval = atol(optarg); 97219820Sjeff break; 98219820Sjeff case 'u': /* do everything in GMT */ 99219820Sjeff (void)setenv("TZ", "GMT0", 1); 100219820Sjeff break; 101219820Sjeff default: 102219820Sjeff usage(); 103219820Sjeff } 104219820Sjeff argc -= optind; 105219820Sjeff argv += optind; 106219820Sjeff 107219820Sjeff if (!rflag && time(&tval) == -1) 108219820Sjeff err(1, "time"); 109219820Sjeff 110219820Sjeff format = "%a %b %e %H:%M:%S %Z %Y"; 111219820Sjeff 112219820Sjeff /* allow the operands in any order */ 113219820Sjeff if (*argv && **argv == '+') { 114219820Sjeff format = *argv + 1; 115219820Sjeff ++argv; 116219820Sjeff } 117219820Sjeff 118219820Sjeff if (*argv) { 119219820Sjeff setthetime(*argv); 120219820Sjeff ++argv; 121219820Sjeff } 122219820Sjeff 123219820Sjeff if (*argv && **argv == '+') 124219820Sjeff format = *argv + 1; 125219820Sjeff 126219820Sjeff (void)strftime(buf, sizeof(buf), format, localtime(&tval)); 127219820Sjeff (void)printf("%s\n", buf); 128219820Sjeff exit(retval); 129219820Sjeff /* NOTREACHED */ 130219820Sjeff} 131219820Sjeff 132219820Sjeff#define ATOI2(ar) ((ar)[0] - '0') * 10 + ((ar)[1] - '0'); (ar) += 2; 133219820Sjeffvoid 134219820Sjeffsetthetime(p) 135219820Sjeff char *p; 136219820Sjeff{ 137219820Sjeff struct tm *lt; 138219820Sjeff struct timeval tv; 139219820Sjeff char *dot, *t; 140219820Sjeff int yearset; 141219820Sjeff 142219820Sjeff for (t = p, dot = NULL; *t; ++t) { 143219820Sjeff if (isdigit(*t)) 144219820Sjeff continue; 145219820Sjeff if (*t == '.' && dot == NULL) { 146219820Sjeff dot = t; 147219820Sjeff continue; 148219820Sjeff } 149219820Sjeff badformat(); 150219820Sjeff } 151219820Sjeff 152219820Sjeff lt = localtime(&tval); 153219820Sjeff 154219820Sjeff if (dot != NULL) { /* .ss */ 155219820Sjeff *dot++ = '\0'; 156219820Sjeff if (strlen(dot) != 2) 157219820Sjeff badformat(); 158219820Sjeff lt->tm_sec = ATOI2(dot); 159219820Sjeff } else 160219820Sjeff lt->tm_sec = 0; 161219820Sjeff 162219820Sjeff yearset = 0; 163219820Sjeff switch (strlen(p)) { 164219820Sjeff case 12: 165219820Sjeff lt->tm_year = ATOI2(p); 166219820Sjeff lt->tm_year *= 100; 167219820Sjeff yearset = 1; 168219820Sjeff /* FALLTHROUGH */ 169219820Sjeff case 10: /* yy */ 170219820Sjeff if (yearset) { 171219820Sjeff yearset = ATOI2(p); 172219820Sjeff lt->tm_year += yearset; 173219820Sjeff } else { 174219820Sjeff yearset = ATOI2(p); 175219820Sjeff if (yearset < 69) /* hack for 2000 ;-} */ 176219820Sjeff lt->tm_year = yearset + 2000; 177219820Sjeff else 178219820Sjeff lt->tm_year = yearset + 1900; 179219820Sjeff } 180219820Sjeff lt->tm_year -= TM_YEAR_BASE; 181219820Sjeff /* FALLTHROUGH */ 182219820Sjeff case 8: /* mm */ 183219820Sjeff lt->tm_mon = ATOI2(p); 184219820Sjeff --lt->tm_mon; /* time struct is 0 - 11 */ 185219820Sjeff /* FALLTHROUGH */ 186219820Sjeff case 6: /* dd */ 187219820Sjeff lt->tm_mday = ATOI2(p); 188219820Sjeff /* FALLTHROUGH */ 189219820Sjeff case 4: /* hh */ 190219820Sjeff lt->tm_hour = ATOI2(p); 191219820Sjeff /* FALLTHROUGH */ 192219820Sjeff case 2: /* mm */ 193219820Sjeff lt->tm_min = ATOI2(p); 194219820Sjeff break; 195219820Sjeff default: 196219820Sjeff badformat(); 197219820Sjeff } 198219820Sjeff 199219820Sjeff /* convert broken-down time to GMT clock time */ 200219820Sjeff if ((tval = mktime(lt)) == -1) 201219820Sjeff badformat(); 202219820Sjeff 203219820Sjeff /* set the time */ 204219820Sjeff if (nflag || netsettime(tval)) { 205219820Sjeff logwtmp("|", "date", ""); 206219820Sjeff tv.tv_sec = tval; 207219820Sjeff tv.tv_usec = 0; 208219820Sjeff if (settimeofday(&tv, NULL)) { 209219820Sjeff perror("date: settimeofday"); 210219820Sjeff exit(1); 211219820Sjeff } 212219820Sjeff logwtmp("{", "date", ""); 213219820Sjeff } 214219820Sjeff 215219820Sjeff if ((p = getlogin()) == NULL) 216219820Sjeff p = "???"; 217219820Sjeff syslog(LOG_AUTH | LOG_NOTICE, "date set by %s", p); 218219820Sjeff} 219219820Sjeff 220219820Sjeffstatic void 221219820Sjeffbadformat() 222219820Sjeff{ 223219820Sjeff warnx("illegal time format"); 224219820Sjeff usage(); 225219820Sjeff} 226219820Sjeff 227219820Sjeffstatic void 228219820Sjeffusage() 229219820Sjeff{ 230219820Sjeff (void)fprintf(stderr, 231219820Sjeff "usage: date [-nu] [-r seconds] [+format]\n"); 232219820Sjeff (void)fprintf(stderr, " date [[[[[cc]yy]mm]dd]hh]mm[.ss]\n"); 233219820Sjeff exit(1); 234219820Sjeff} 235219820Sjeff