| 1 | /* |
| 2 | * sess - determines clock time used so far this session by this user |
| 3 | * or for tty or user supplied as an argument |
| 4 | * |
| 5 | * Author: Howard Katseff |
| 6 | * |
| 7 | * Note that 'sess ~' gives time since system last started. |
| 8 | */ |
| 9 | |
| 10 | struct {long l1;}; |
| 11 | struct {char c1, c2, c3, c4;}; |
| 12 | char buf[32]; |
| 13 | |
| 14 | main(argc, argv) |
| 15 | char **argv; { |
| 16 | int f, i; |
| 17 | char t[2], *p; |
| 18 | long lx; |
| 19 | int intrp(); |
| 20 | |
| 21 | t[1] = 0; |
| 22 | f = open("/usr/adm/wtmp", 0); |
| 23 | if (f < 0) { |
| 24 | printf("Can't open /usr/adm/wtmp\n"); |
| 25 | exit(); |
| 26 | } |
| 27 | fstat(f, buf); |
| 28 | |
| 29 | lx.c2 = 0; |
| 30 | lx.c1 = buf[9]; |
| 31 | lx.c3 = buf[10] & 0360; |
| 32 | lx.c4 = buf[11]; |
| 33 | |
| 34 | blseek(f, lx, 0); |
| 35 | |
| 36 | if (argc <= 1) { |
| 37 | t[0] = ttyn(2); |
| 38 | p = t; |
| 39 | } |
| 40 | else p = argv[1]; |
| 41 | |
| 42 | if ((signal(2,1) && 01) == 0) signal(2, &intrp); |
| 43 | |
| 44 | for (;;) { |
| 45 | if (bread(f, buf+16, -16) < 16) exit(); |
| 46 | lx =- 16; |
| 47 | if (equal(p, buf)) { |
| 48 | if (*(p+1) != '\0') { |
| 49 | t[0] = buf[8]; |
| 50 | p = t; |
| 51 | blseek(f, lx+16, 0); |
| 52 | while(bread(f, buf, 16) > 0) |
| 53 | if (equal(p, buf)) goto l1; |
| 54 | blseek(f, lx, 0); |
| 55 | bread(f, buf, 16); |
| 56 | l1:; } |
| 57 | time(&lx); |
| 58 | lx =+ 231231630 - (buf+10)->l1; |
| 59 | printf("Elapsed time:"); |
| 60 | if (lx < 231318030) |
| 61 | printf(" %5.5s", 11+ctime(&lx)); |
| 62 | else |
| 63 | printf(" %ld + %5.5s",(lx-231231630)/86400, |
| 64 | 11+ctime(&lx)); |
| 65 | if (buf[0] == '\0' && *p != '~') |
| 66 | printf(" since logout\n"); |
| 67 | else putchar('\n'); |
| 68 | exit(); |
| 69 | } |
| 70 | } |
| 71 | } |
| 72 | |
| 73 | |
| 74 | equal(c1, c2) |
| 75 | char *c1, *c2; { |
| 76 | int i; |
| 77 | |
| 78 | if (*(c1+1) == '\0') { |
| 79 | if (*c1 == *(c2+8)) return(1); |
| 80 | else return(0); |
| 81 | } |
| 82 | |
| 83 | for (i=0; i<8; i++) { |
| 84 | if (*c1 == '\0') return(*c2 == ' '); |
| 85 | if (*c1++ != *c2++) return(0); |
| 86 | } |
| 87 | |
| 88 | return(1); |
| 89 | } |
| 90 | |
| 91 | intrp() { |
| 92 | register char *q; |
| 93 | |
| 94 | signal(2,1); |
| 95 | |
| 96 | q = ctime(buf+10); |
| 97 | printf("interrupted at %10.10s %5.5s \n", |
| 98 | q, 11+q); |
| 99 | |
| 100 | exit(); |
| 101 | } |
| 102 | /* |
| 103 | * NAME: bread(), brseek(), blseek() |
| 104 | * |
| 105 | * DESCRIPTION: |
| 106 | * This is a buffered read package which simulates read(), seek() and |
| 107 | * lseek(). |
| 108 | * Bread may be called with a negative nbytes which causes it to |
| 109 | * read backwards . In this case, buffer should point to the first |
| 110 | * byte following the buffer. If only a partial read is possible |
| 111 | * (due to beginning of file), only the last bytes of the buffer |
| 112 | * will be filled. |
| 113 | */ |
| 114 | |
| 115 | int i, j, k; |
| 116 | int nl, nr; |
| 117 | char *next; |
| 118 | char b[512]; |
| 119 | |
| 120 | bread(file, buff, nbytes) |
| 121 | char *buff; { |
| 122 | register nb; |
| 123 | |
| 124 | if (nbytes > 0) { |
| 125 | for (nb=nbytes; nb>0; nb--) { |
| 126 | if (nr == 0) { |
| 127 | nr = read(file, next=b, 512); |
| 128 | nl = 0; |
| 129 | if (nr < 0) return(-1); |
| 130 | if (nr == 0) return(nbytes-nb); |
| 131 | } |
| 132 | *buff++ = *next++; |
| 133 | nr--; |
| 134 | nl++; |
| 135 | } |
| 136 | } |
| 137 | else { |
| 138 | nbytes = -nbytes; |
| 139 | for (nb=nbytes; nb>0; nb--) { |
| 140 | if (nl == 0) { |
| 141 | seek(file, -(512 + nr), 1); |
| 142 | nl = read(file, b, 512); |
| 143 | if (nl < 0) { |
| 144 | for (k=511; k>0; k--) { |
| 145 | seek(file, 1, 1); |
| 146 | nl = read(file, b, k); |
| 147 | if (nl >= 0) break; |
| 148 | } |
| 149 | if (nl < 0) return(nbytes-nb); |
| 150 | } |
| 151 | if (nl == 0) return(nbytes-nb); |
| 152 | next = b + nl; |
| 153 | nr = 0; |
| 154 | } |
| 155 | *--buff = *--next; |
| 156 | nr++; |
| 157 | nl--; |
| 158 | } |
| 159 | } |
| 160 | return(nbytes); |
| 161 | } |
| 162 | |
| 163 | |
| 164 | brseek(file, offset, flag) { |
| 165 | nl = 0; |
| 166 | nr = 0; |
| 167 | return(seek(file,offset,flag)); |
| 168 | } |
| 169 | |
| 170 | |
| 171 | blseek(file, offset, flag) |
| 172 | long offset; { |
| 173 | nl = 0; |
| 174 | nr = 0; |
| 175 | return(lseek(file,offset,flag)); |
| 176 | } |