1: /* 2: * Copyright (c) 1987 by Ed James, UC Berkeley. All rights reserved. 3: * 4: * Copy permission is hereby granted provided that this notice is 5: * retained on all partial or complete copies. 6: * 7: * For more info on this and all of my stuff, mail edjames@berkeley.edu. 8: */ 9: 10: #ifndef lint 11: static char sccsid[] = "@(#)log.c 1.4 (Berkeley) 12/26/87"; 12: #endif not lint 13: 14: #include "include.h" 15: 16: compar(a, b) 17: SCORE *a, *b; 18: { 19: if (b->planes == a->planes) 20: return (b->time - a->time); 21: else 22: return (b->planes - a->planes); 23: } 24: 25: #define SECAMIN 60 26: #define MINAHOUR 60 27: #define HOURADAY 24 28: #define SECAHOUR (SECAMIN * MINAHOUR) 29: #define SECADAY (SECAHOUR * HOURADAY) 30: #define DAY(t) ((t) / SECADAY) 31: #define HOUR(t) (((t) % SECADAY) / SECAHOUR) 32: #define MIN(t) (((t) % SECAHOUR) / SECAMIN) 33: #define SEC(t) ((t) % SECAMIN) 34: 35: char * 36: timestr(t) 37: { 38: static char s[80]; 39: 40: if (DAY(t) > 0) 41: (void)sprintf(s, "%dd+%02dhrs", DAY(t), HOUR(t)); 42: else if (HOUR(t) > 0) 43: (void)sprintf(s, "%d:%02d:%02d", HOUR(t), MIN(t), SEC(t)); 44: else if (MIN(t) > 0) 45: (void)sprintf(s, "%d:%02d", MIN(t), SEC(t)); 46: else if (SEC(t) > 0) 47: (void)sprintf(s, ":%02d", SEC(t)); 48: else 49: *s = '\0'; 50: 51: return (s); 52: } 53: 54: log_score(list_em) 55: { 56: register int i, fd, num_scores = 0, good, changed = 0, found = 0; 57: struct passwd *pw; 58: FILE *fp; 59: char *cp, logstr[BUFSIZ], *index(), *rindex(); 60: SCORE score[100], thisscore; 61: #ifdef SYSV 62: struct utsname name; 63: #endif 64: 65: strcpy(logstr, SPECIAL_DIR); 66: strcat(logstr, LOG); 67: 68: umask(0); 69: fd = open(logstr, O_CREAT|O_RDWR, 0644); 70: if (fd < 0) { 71: perror(logstr); 72: return (-1); 73: } 74: /* 75: * This is done to take advantage of stdio, while still 76: * allowing a O_CREAT during the open(2) of the log file. 77: */ 78: fp = fdopen(fd, "r+"); 79: if (fp == NULL) { 80: perror(logstr); 81: return (-1); 82: } 83: #ifdef BSD 84: if (flock(fileno(fp), LOCK_EX) < 0) 85: #endif 86: #ifdef SYSV 87: while (lockf(fileno(fp), F_LOCK, 1) < 0) 88: #endif 89: { 90: perror("flock"); 91: return (-1); 92: } 93: for (;;) { 94: good = fscanf(fp, "%s %s %s %d %d %d", 95: score[num_scores].name, 96: score[num_scores].host, 97: score[num_scores].game, 98: &score[num_scores].planes, 99: &score[num_scores].time, 100: &score[num_scores].real_time); 101: if (good != 6 || ++num_scores >= NUM_SCORES) 102: break; 103: } 104: if (!test_mode && !list_em) { 105: if ((pw = (struct passwd *) getpwuid(getuid())) == NULL) { 106: fprintf(stderr, 107: "getpwuid failed for uid %d. Who are you?\n", 108: getuid()); 109: return (-1); 110: } 111: strcpy(thisscore.name, pw->pw_name); 112: #ifdef BSD 113: if (gethostname(thisscore.host, sizeof (thisscore.host)) < 0) { 114: perror("gethostname"); 115: return (-1); 116: } 117: #endif 118: #ifdef SYSV 119: uname(&name); 120: strcpy(thisscore.host, name.sysname); 121: #endif 122: 123: cp = rindex(file, '/'); 124: if (cp == NULL) { 125: fprintf(stderr, "log: where's the '/' in %s?\n", file); 126: return (-1); 127: } 128: cp++; 129: strcpy(thisscore.game, cp); 130: 131: thisscore.time = clock; 132: thisscore.planes = safe_planes; 133: thisscore.real_time = time(0) - start_time; 134: 135: for (i = 0; i < num_scores; i++) { 136: if (strcmp(thisscore.name, score[i].name) == 0 && 137: strcmp(thisscore.host, score[i].host) == 0 && 138: strcmp(thisscore.game, score[i].game) == 0) { 139: if (thisscore.time > score[i].time) { 140: score[i].time = thisscore.time; 141: score[i].planes = thisscore.planes; 142: score[i].real_time = 143: thisscore.real_time; 144: changed++; 145: } 146: found++; 147: break; 148: } 149: } 150: if (!found) { 151: for (i = 0; i < num_scores; i++) { 152: if (thisscore.time > score[i].time) { 153: if (num_scores < NUM_SCORES) 154: num_scores++; 155: bcopy(&score[i], 156: &score[num_scores - 1], 157: sizeof (score[i])); 158: bcopy(&thisscore, &score[i], 159: sizeof (score[i])); 160: changed++; 161: break; 162: } 163: } 164: } 165: if (!found && !changed && num_scores < NUM_SCORES) { 166: bcopy(&thisscore, &score[num_scores], 167: sizeof (score[num_scores])); 168: num_scores++; 169: changed++; 170: } 171: 172: if (changed) { 173: if (found) 174: puts("You beat your previous score!"); 175: else 176: puts("You made the top players list!"); 177: qsort(score, num_scores, sizeof (*score), compar); 178: rewind(fp); 179: for (i = 0; i < num_scores; i++) 180: fprintf(fp, "%s %s %s %d %d %d\n", 181: score[i].name, score[i].host, 182: score[i].game, score[i].planes, 183: score[i].time, score[i].real_time); 184: } else { 185: if (found) 186: puts("You didn't beat your previous score."); 187: else 188: puts("You didn't make the top players list."); 189: } 190: putchar('\n'); 191: } 192: #ifdef BSD 193: flock(fileno(fp), LOCK_UN); 194: #endif 195: #ifdef SYSV 196: /* lock will evaporate upon close */ 197: #endif 198: fclose(fp); 199: printf("%2s: %-8s %-8s %-18s %4s %9s %4s\n", "#", "name", "host", 200: "game", "time", "real time", "planes safe"); 201: puts("-------------------------------------------------------------------------------"); 202: for (i = 0; i < num_scores; i++) { 203: cp = index(score[i].host, '.'); 204: if (cp != NULL) 205: *cp = '\0'; 206: printf("%2d: %-8s %-8s %-18s %4d %9s %4d\n", i + 1, 207: score[i].name, score[i].host, score[i].game, 208: score[i].time, timestr(score[i].real_time), 209: score[i].planes); 210: } 211: putchar('\n'); 212: return (0); 213: }