/usr.bin/calendar/calendar.c

https://bitbucket.org/freebsd/freebsd-head/ · C · 228 lines · 150 code · 38 blank · 40 comment · 24 complexity · bebcbbcda83c011ddc830bdc3c8e18e4 MD5 · raw file

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