1 /* $OpenBSD: cfscores.c,v 1.15 2009/10/27 23:59:24 deraadt Exp $ */ 2 /* $NetBSD: cfscores.c,v 1.3 1995/03/21 15:08:37 cgd Exp $ */ 3 4 /* 5 * Copyright (c) 1983, 1993 6 * The Regents of the University of California. All rights reserved. 7 * 8 * Redistribution and use in source and binary forms, with or without 9 * modification, are permitted provided that the following conditions 10 * are met: 11 * 1. Redistributions of source code must retain the above copyright 12 * notice, this list of conditions and the following disclaimer. 13 * 2. Redistributions in binary form must reproduce the above copyright 14 * notice, this list of conditions and the following disclaimer in the 15 * documentation and/or other materials provided with the distribution. 16 * 3. Neither the name of the University nor the names of its contributors 17 * may be used to endorse or promote products derived from this software 18 * without specific prior written permission. 19 * 20 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 21 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 22 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 23 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 24 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 25 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 26 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 27 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 28 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 29 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 30 * SUCH DAMAGE. 31 */ 32 33 #include <sys/types.h> 34 #include <err.h> 35 #include <fcntl.h> 36 #include <pwd.h> 37 #include <stdio.h> 38 #include <stdlib.h> 39 #include <string.h> 40 #include <unistd.h> 41 #include "pathnames.h" 42 43 struct betinfo { 44 long hand; /* cost of dealing hand */ 45 long inspection; /* cost of inspecting hand */ 46 long game; /* cost of buying game */ 47 long runs; /* cost of running through hands */ 48 long information; /* cost of information */ 49 long thinktime; /* cost of thinking time */ 50 long wins; /* total winnings */ 51 long worth; /* net worth after costs */ 52 }; 53 54 int dbfd; 55 56 void printuser(const struct passwd *, int); 57 58 int 59 main(int argc, char *argv[]) 60 { 61 struct passwd *pw; 62 uid_t uid; 63 gid_t gid; 64 65 if (argc > 2) { 66 fprintf(stderr, "usage: cfscores [-a] [username]\n"); 67 exit(1); 68 } 69 dbfd = open(_PATH_SCORE, O_RDONLY); 70 if (dbfd < 0) 71 err(2, "%s", _PATH_SCORE); 72 73 /* revoke privs */ 74 gid = getgid(); 75 setresgid(gid, gid, gid); 76 77 setpwent(); 78 if (argc == 1) { 79 uid = getuid(); 80 pw = getpwuid(uid); 81 if (pw == 0) { 82 printf("You are not listed in the password file?!?\n"); 83 exit(2); 84 } 85 printuser(pw, 1); 86 exit(0); 87 } 88 if (strcmp(argv[1], "-a") == 0) { 89 while ((pw = getpwent()) != 0) 90 printuser(pw, 0); 91 exit(0); 92 } 93 pw = getpwnam(argv[1]); 94 if (pw == 0) { 95 printf("User %s unknown\n", argv[1]); 96 exit(3); 97 } 98 printuser(pw, 1); 99 exit(0); 100 } 101 102 /* 103 * print out info for specified password entry 104 */ 105 void 106 printuser(const struct passwd *pw, int printfail) 107 { 108 struct betinfo total; 109 int i; 110 111 if (pw->pw_uid < 0) { 112 printf("Bad uid %u\n", pw->pw_uid); 113 return; 114 } 115 i = lseek(dbfd, pw->pw_uid * sizeof(struct betinfo), SEEK_SET); 116 if (i < 0) { 117 warn("lseek %s", _PATH_SCORE); 118 return; 119 } 120 i = read(dbfd, (char *)&total, sizeof(total)); 121 if (i < 0) { 122 warn("lseek %s", _PATH_SCORE); 123 return; 124 } 125 if (i == 0 || total.hand == 0) { 126 if (printfail) 127 printf("%s has never played canfield.\n", pw->pw_name); 128 return; 129 } 130 i = strlen(pw->pw_name); 131 printf("*----------------------*\n"); 132 if (total.worth >= 0) { 133 if (i <= 8) 134 printf("* Winnings for %-8s*\n", pw->pw_name); 135 else { 136 printf("* Winnings for *\n"); 137 if (i <= 20) 138 printf("* %20s *\n", pw->pw_name); 139 else 140 printf("%s\n", pw->pw_name); 141 } 142 } else { 143 if (i <= 10) 144 printf("* Losses for %-10s*\n", pw->pw_name); 145 else { 146 printf("* Losses for *\n"); 147 if (i <= 20) 148 printf("* %20s *\n", pw->pw_name); 149 else 150 printf("%s\n", pw->pw_name); 151 } 152 } 153 printf("*======================*\n"); 154 printf("|Costs Total |\n"); 155 printf("| Hands %8ld |\n", total.hand); 156 printf("| Inspections %8ld |\n", total.inspection); 157 printf("| Games %8ld |\n", total.game); 158 printf("| Runs %8ld |\n", total.runs); 159 printf("| Information %8ld |\n", total.information); 160 printf("| Think time %8ld |\n", total.thinktime); 161 printf("|Total Costs %8ld |\n", total.wins - total.worth); 162 printf("|Winnings %8ld |\n", total.wins); 163 printf("|Net Worth %8ld |\n", total.worth); 164 printf("*----------------------*\n\n"); 165 } 166