settime.c 2.8 KB

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