1 /*- 2 * SPDX-License-Identifier: BSD-3-Clause 3 * 4 * Copyright (c) 1989, 1993, 1994 5 * The Regents of the University of California. All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions 9 * are met: 10 * 1. Redistributions of source code must retain the above copyright 11 * notice, this list of conditions and the following disclaimer. 12 * 2. Redistributions in binary form must reproduce the above copyright 13 * notice, this list of conditions and the following disclaimer in the 14 * documentation and/or other materials provided with the distribution. 15 * 3. Neither the name of the University nor the names of its contributors 16 * may be used to endorse or promote products derived from this software 17 * without specific prior written permission. 18 * 19 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 22 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 29 * SUCH DAMAGE. 30 * 31 * @(#)calendar.c 8.3 (Berkeley) 3/25/94 32 * $FreeBSD: head/usr.bin/calendar/calendar.c 326025 2017-11-20 19:49:47Z pfg $ 33 */ 34 35 #include <sys/types.h> 36 37 #include <err.h> 38 #include <errno.h> 39 #include <locale.h> 40 #include <login_cap.h> 41 #include <pwd.h> 42 #include <stdbool.h> 43 #include <stdio.h> 44 #include <stdlib.h> 45 #include <string.h> 46 #include <time.h> 47 #include <unistd.h> 48 49 #include "calendar.h" 50 51 struct passwd *pw; 52 bool doall = false; 53 bool debug = false; 54 static char *DEBUG = NULL; 55 static time_t f_time = 0; 56 double UTCOffset; 57 double EastLongitude; 58 59 static void usage(void) __dead2; 60 static double get_utcoffset(void); 61 62 int 63 main(int argc, char *argv[]) 64 { 65 int f_dayAfter = 0; /* days after current date */ 66 int f_dayBefore = 0; /* days before current date */ 67 int Friday = 5; /* day before weekend */ 68 69 int ch; 70 struct tm tp1, tp2; 71 72 setlocale(LC_ALL, ""); 73 UTCOffset = get_utcoffset(); 74 EastLongitude = UTCOffset * 15; 75 76 while ((ch = getopt(argc, argv, "-A:aB:D:dF:f:hl:t:U:W:?")) != -1) { 77 switch (ch) { 78 case '-': /* backward compatible */ 79 case 'a': 80 if (getuid()) { 81 errno = EPERM; 82 err(1, NULL); 83 } 84 doall = true; 85 break; 86 87 case 'W': /* we don't need no steenking Fridays */ 88 Friday = -1; 89 /* FALLTHROUGH */ 90 case 'A': /* days after current date */ 91 f_dayAfter = atoi(optarg); 92 if (f_dayAfter < 0) 93 errx(1, "number of days must be positive"); 94 break; 95 96 case 'B': /* days before current date */ 97 f_dayBefore = atoi(optarg); 98 if (f_dayBefore < 0) 99 errx(1, "number of days must be positive"); 100 break; 101 102 case 'D': /* debug output of sun and moon info */ 103 DEBUG = optarg; 104 break; 105 106 case 'd': /* debug output of current date */ 107 debug = true; 108 break; 109 110 case 'F': /* Change the time: When does weekend start? */ 111 Friday = atoi(optarg); 112 break; 113 114 case 'f': /* other calendar file */ 115 calendarFile = optarg; 116 break; 117 118 case 'l': /* Change longitudal position */ 119 EastLongitude = strtod(optarg, NULL); 120 UTCOffset = EastLongitude / 15; 121 break; 122 123 case 't': /* other date, for tests */ 124 f_time = Mktime(optarg); 125 break; 126 127 case 'U': /* Change UTC offset */ 128 UTCOffset = strtod(optarg, NULL); 129 EastLongitude = UTCOffset * 15; 130 break; 131 132 case 'h': 133 case '?': 134 default: 135 usage(); 136 } 137 } 138 argc -= optind; 139 argv += optind; 140 141 if (argc) 142 usage(); 143 144 /* use current time */ 145 if (f_time <= 0) 146 time(&f_time); 147 148 settimes(f_time, f_dayBefore, f_dayAfter, Friday, &tp1, &tp2); 149 generatedates(&tp1, &tp2); 150 151 /* 152 * FROM now on, we are working in UTC. 153 * This will only affect moon and sun related events anyway. 154 */ 155 if (setenv("TZ", "UTC", 1) != 0) 156 errx(1, "setenv: %s", strerror(errno)); 157 tzset(); 158 159 if (debug) 160 dumpdates(); 161 162 if (DEBUG != NULL) { 163 dodebug(DEBUG); 164 exit(0); 165 } 166 167 if (doall) { 168 while ((pw = getpwent()) != NULL) { 169 pid_t pid; 170 171 if (chdir(pw->pw_dir) == -1) 172 continue; 173 174 pid = fork(); 175 if (pid < 0) 176 err(1, "fork"); 177 if (pid == 0) { 178 login_cap_t *lc; 179 180 lc = login_getpwclass(pw); 181 if (setusercontext(lc, pw, pw->pw_uid, 182 LOGIN_SETALL) != 0) 183 errx(1, "setusercontext"); 184 185 cal(); 186 exit(0); 187 } 188 } 189 } else { 190 cal(); 191 } 192 193 return (0); 194 } 195 196 197 static void __dead2 198 usage(void) 199 { 200 fprintf(stderr, "%s\n%s\n%s\n", 201 "usage: calendar [-A days] [-a] [-B days] [-D sun|moon] [-d]", 202 " [-F friday] [-f calendarfile] [-l longitude]", 203 " [-t dd[.mm[.year]]] [-U utcoffset] [-W days]" 204 ); 205 exit(1); 206 } 207 208 209 /* 210 * Calculate the timezone difference between here and UTC. 211 * 212 * Return the offset hour from UTC. 213 */ 214 static double 215 get_utcoffset(void) 216 { 217 time_t t; 218 struct tm tm; 219 long utcoffset; 220 221 time(&t); 222 localtime_r(&t, &tm); 223 utcoffset = tm.tm_gmtoff; 224 225 return (utcoffset / FSECSPERHOUR); 226 } 227