settime.c 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169
  1. /*
  2. * This file is part of the UCB release of Plan 9. It is subject to the license
  3. * terms in the LICENSE file found in the top-level directory of this
  4. * distribution and at http://akaros.cs.berkeley.edu/files/Plan9License. No
  5. * part of the UCB release of Plan 9, including this file, may be copied,
  6. * modified, propagated, or distributed except according to the terms contained
  7. * in the LICENSE file.
  8. */
  9. #include <u.h>
  10. #include <libc.h>
  11. #include <auth.h>
  12. #include <fcall.h>
  13. #include "../boot/boot.h"
  14. static int32_t lusertime(char *);
  15. char *timeserver = "#s/boot";
  16. static int
  17. setlocaltime(char *timebuf, int s)
  18. {
  19. int n, f, t;
  20. t = 0;
  21. f = open("#r/rtc", ORDWR);
  22. if(f >= 0){
  23. if((n = read(f, timebuf, s - 1)) > 0){
  24. timebuf[n] = '\0';
  25. t = 1;
  26. }
  27. close(f);
  28. } else
  29. do {
  30. strcpy(timebuf, "yymmddhhmm[ss]");
  31. outin("\ndate/time ", timebuf, s);
  32. } while((t = lusertime(timebuf)) <= 0);
  33. return t;
  34. }
  35. void
  36. settime(int islocal, int afd, char *rp)
  37. {
  38. int f;
  39. int timeset;
  40. Dir dir[2];
  41. char timebuf[64];
  42. print("time...");
  43. timeset = 0;
  44. if(islocal){
  45. /*
  46. * set the time from the real time clock
  47. */
  48. timeset = setlocaltime(timebuf, sizeof(timebuf));
  49. }
  50. if(timeset == 0){
  51. /*
  52. * set the time from the access time of the root
  53. */
  54. f = open(timeserver, ORDWR);
  55. if(f < 0)
  56. return;
  57. if(mount(f, afd, "/tmp", MREPL, rp, 'M') < 0){
  58. warning("settime mount");
  59. close(f);
  60. if((!islocal) && (setlocaltime(timebuf, sizeof(timebuf)) == 0))
  61. return;
  62. } else {
  63. close(f);
  64. if(stat("/tmp", statbuf, sizeof statbuf) < 0)
  65. fatal("stat");
  66. convM2D(statbuf, sizeof statbuf, &dir[0], (char *)&dir[1]);
  67. sprint(timebuf, "%ld", dir[0].atime);
  68. unmount(0, "/tmp");
  69. }
  70. }
  71. if((!islocal) && (strcmp(timebuf, "0") == 0))
  72. setlocaltime(timebuf, sizeof(timebuf));
  73. f = open("#c/time", OWRITE);
  74. if(write(f, timebuf, strlen(timebuf)) < 0)
  75. warning("can't set #c/time");
  76. close(f);
  77. print("\n");
  78. }
  79. #define SEC2MIN 60L
  80. #define SEC2HOUR (60L * SEC2MIN)
  81. #define SEC2DAY (24L * SEC2HOUR)
  82. int
  83. g2(char **pp)
  84. {
  85. int v;
  86. v = 10 * ((*pp)[0] - '0') + (*pp)[1] - '0';
  87. *pp += 2;
  88. return v;
  89. }
  90. /*
  91. * days per month plus days/year
  92. */
  93. static int dmsize[] = {
  94. 365, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
  95. static int ldmsize[] = {
  96. 366, 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
  97. /*
  98. * return the days/month for the given year
  99. */
  100. static int *
  101. yrsize(int y)
  102. {
  103. if((y % 4) == 0 && ((y % 100) != 0 || (y % 400) == 0))
  104. return ldmsize;
  105. else
  106. return dmsize;
  107. }
  108. /*
  109. * compute seconds since Jan 1 1970
  110. */
  111. static int32_t
  112. lusertime(char *argbuf)
  113. {
  114. char *buf;
  115. uint32_t secs;
  116. int i, y, m;
  117. int *d2m;
  118. buf = argbuf;
  119. i = strlen(buf);
  120. if(i != 10 && i != 12)
  121. return -1;
  122. secs = 0;
  123. y = g2(&buf);
  124. m = g2(&buf);
  125. if(y < 70)
  126. y += 2000;
  127. else
  128. y += 1900;
  129. /*
  130. * seconds per year
  131. */
  132. for(i = 1970; i < y; i++){
  133. d2m = yrsize(i);
  134. secs += d2m[0] * SEC2DAY;
  135. }
  136. /*
  137. * seconds per month
  138. */
  139. d2m = yrsize(y);
  140. for(i = 1; i < m; i++)
  141. secs += d2m[i] * SEC2DAY;
  142. secs += (g2(&buf) - 1) * SEC2DAY;
  143. secs += g2(&buf) * SEC2HOUR;
  144. secs += g2(&buf) * SEC2MIN;
  145. if(*buf)
  146. secs += g2(&buf);
  147. sprint(argbuf, "%ld", secs);
  148. return secs;
  149. }