1 #include <u.h> 2 #include <libc.h> 3 #include <auth.h> 4 #include <fcall.h> 5 #include "../boot/boot.h" 6 7 static long lusertime(char*); 8 9 char *timeserver = "#s/boot"; 10 11 void 12 settime(int islocal) 13 { 14 int n, f; 15 int timeset; 16 Dir dir; 17 char dirbuf[DIRLEN]; 18 19 print("time..."); 20 timeset = 0; 21 if(islocal){ 22 /* 23 * set the time from the real time clock 24 */ 25 f = open("#r/rtc", ORDWR); 26 if(f >= 0){ 27 if((n = read(f, dirbuf, sizeof(dirbuf)-1)) > 0){ 28 dirbuf[n] = 0; 29 timeset = 1; 30 } 31 close(f); 32 }else do{ 33 strcpy(dirbuf, "yymmddhhmm[ss]"); 34 outin(cpuflag, "\ndate/time ", dirbuf, sizeof(dirbuf)); 35 }while((timeset=lusertime(dirbuf)) <= 0); 36 } 37 if(timeset == 0){ 38 /* 39 * set the time from the access time of the root 40 */ 41 f = open(timeserver, ORDWR); 42 if(f < 0) 43 return; 44 if(mount(f, "/n/boot", MREPL, "") < 0){ 45 warning("settime mount"); 46 close(f); 47 return; 48 } 49 close(f); 50 if(stat("/n/boot", dirbuf) < 0) 51 fatal("stat"); 52 convM2D(dirbuf, &dir); 53 sprint(dirbuf, "%ld", dir.atime); 54 unmount(0, "/n/boot"); 55 /* 56 * set real time clock if there is one 57 */ 58 f = open("#r/rtc", ORDWR); 59 if(f > 0){ 60 write(f, dirbuf, strlen(dirbuf)); 61 close(f); 62 } 63 } 64 65 f = open("#c/time", OWRITE); 66 if(write(f, dirbuf, strlen(dirbuf)) < 0) 67 warning("can't set #c/time"); 68 close(f); 69 } 70 71 #define SEC2MIN 60L 72 #define SEC2HOUR (60L*SEC2MIN) 73 #define SEC2DAY (24L*SEC2HOUR) 74 75 int 76 g2(char **pp) 77 { 78 int v; 79 80 v = 10*((*pp)[0]-'0') + (*pp)[1]-'0'; 81 *pp += 2; 82 return v; 83 } 84 85 /* 86 * days per month plus days/year 87 */ 88 static int dmsize[] = 89 { 90 365, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 91 }; 92 static int ldmsize[] = 93 { 94 366, 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 95 }; 96 97 /* 98 * return the days/month for the given year 99 */ 100 static int * 101 yrsize(int yr) 102 { 103 if((yr % 4) == 0) 104 return ldmsize; 105 else 106 return dmsize; 107 } 108 109 /* 110 * compute seconds since Jan 1 1970 111 */ 112 static long 113 lusertime(char *argbuf) 114 { 115 char *buf; 116 ulong secs; 117 int i, y, m; 118 int *d2m; 119 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 /* 133 * seconds per year 134 */ 135 for(i = 1970; i < y; i++){ 136 d2m = yrsize(i); 137 secs += d2m[0] * SEC2DAY; 138 } 139 140 /* 141 * seconds per month 142 */ 143 d2m = yrsize(y); 144 for(i = 1; i < m; i++) 145 secs += d2m[i] * SEC2DAY; 146 147 secs += (g2(&buf)-1) * SEC2DAY; 148 secs += g2(&buf) * SEC2HOUR; 149 secs += g2(&buf) * SEC2MIN; 150 if(*buf) 151 secs += g2(&buf); 152 153 sprint(argbuf, "%ld", secs); 154 return secs; 155 } 156