settime.c 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172
  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. int n, f, t;
  19. t=0;
  20. f = open("#r/rtc", ORDWR);
  21. if(f >= 0){
  22. if((n = read(f, timebuf, s-1)) > 0){
  23. timebuf[n] = '\0';
  24. t = 1;
  25. }
  26. close(f);
  27. }else do{
  28. strcpy(timebuf, "yymmddhhmm[ss]");
  29. outin("\ndate/time ", timebuf, s);
  30. }while((t=lusertime(timebuf)) <= 0);
  31. return t;
  32. }
  33. void
  34. settime(int islocal, int afd, char *rp)
  35. {
  36. int f;
  37. int timeset;
  38. Dir dir[2];
  39. char timebuf[64];
  40. print("time...");
  41. timeset = 0;
  42. if(islocal){
  43. /*
  44. * set the time from the real time clock
  45. */
  46. timeset=setlocaltime(timebuf, sizeof(timebuf));
  47. }
  48. if(timeset == 0){
  49. /*
  50. * set the time from the access time of the root
  51. */
  52. f = open(timeserver, ORDWR);
  53. if(f < 0)
  54. return;
  55. if(mount(f, afd, "/tmp", MREPL, rp, 'M') < 0){
  56. warning("settime mount");
  57. close(f);
  58. if((!islocal) && (setlocaltime(timebuf, sizeof(timebuf)) == 0))
  59. return;
  60. } else {
  61. close(f);
  62. if(stat("/tmp", statbuf, sizeof statbuf) < 0)
  63. fatal("stat");
  64. convM2D(statbuf, sizeof statbuf, &dir[0], (char*)&dir[1]);
  65. sprint(timebuf, "%ld", dir[0].atime);
  66. unmount(0, "/tmp");
  67. }
  68. }
  69. if((!islocal) && (strcmp(timebuf,"0")==0))
  70. setlocaltime(timebuf, sizeof(timebuf));
  71. f = open("#c/time", OWRITE);
  72. if(write(f, timebuf, strlen(timebuf)) < 0)
  73. warning("can't set #c/time");
  74. close(f);
  75. print("\n");
  76. }
  77. #define SEC2MIN 60L
  78. #define SEC2HOUR (60L*SEC2MIN)
  79. #define SEC2DAY (24L*SEC2HOUR)
  80. int
  81. g2(char **pp)
  82. {
  83. int v;
  84. v = 10*((*pp)[0]-'0') + (*pp)[1]-'0';
  85. *pp += 2;
  86. return v;
  87. }
  88. /*
  89. * days per month plus days/year
  90. */
  91. static int dmsize[] =
  92. {
  93. 365, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31
  94. };
  95. static int ldmsize[] =
  96. {
  97. 366, 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31
  98. };
  99. /*
  100. * return the days/month for the given year
  101. */
  102. static int *
  103. yrsize(int y)
  104. {
  105. if((y%4) == 0 && ((y%100) != 0 || (y%400) == 0))
  106. return ldmsize;
  107. else
  108. return dmsize;
  109. }
  110. /*
  111. * compute seconds since Jan 1 1970
  112. */
  113. static int32_t
  114. lusertime(char *argbuf)
  115. {
  116. char *buf;
  117. uint32_t secs;
  118. int i, y, m;
  119. int *d2m;
  120. buf = argbuf;
  121. i = strlen(buf);
  122. if(i != 10 && i != 12)
  123. return -1;
  124. secs = 0;
  125. y = g2(&buf);
  126. m = g2(&buf);
  127. if(y < 70)
  128. y += 2000;
  129. else
  130. y += 1900;
  131. /*
  132. * seconds per year
  133. */
  134. for(i = 1970; i < y; i++){
  135. d2m = yrsize(i);
  136. secs += d2m[0] * SEC2DAY;
  137. }
  138. /*
  139. * seconds per month
  140. */
  141. d2m = yrsize(y);
  142. for(i = 1; i < m; i++)
  143. secs += d2m[i] * SEC2DAY;
  144. secs += (g2(&buf)-1) * SEC2DAY;
  145. secs += g2(&buf) * SEC2HOUR;
  146. secs += g2(&buf) * SEC2MIN;
  147. if(*buf)
  148. secs += g2(&buf);
  149. sprint(argbuf, "%ld", secs);
  150. return secs;
  151. }