root/trunk/athena/bin/lpr/quota/bill_db.c @ 4370

Revision 4370, 9.4 KB (checked in by epeisach, 19 years ago)

Fixed a bug in determining if a person needed a statement as it would
subtract the YTD charge. This is wrong as quotaLimit is upped after every bill

Line 
1/* $Source: /afs/dev.mit.edu/source/repository/athena/bin/lpr/quota/bill_db.c,v $ */
2/* $Author: epeisach $ */
3
4/*
5 * Copyright (c) 1990 by the Massachusetts Institute of Technology.
6 * For copying and distribution information, see the file "mit-copyright.h."
7 */
8#include <stdio.h>
9#include <strings.h>
10#include <krb.h>
11#include <time.h>
12#include <signal.h>
13#include "quota_db.h"
14#include "quota.h"
15
16/* These have to be defined here because quota_dba.o declares them */
17/* extern.   Normally, the are declared in qmain.c. */
18#ifdef DEBUG
19char *progname = "bill_db";
20int quota_debug=1;
21#endif
22
23/* Define all codes that that the bursar files will use. */
24#define STUFF "SU1"
25#define ATHCODE "721"
26#define TITLE "Printing: "
27#define TITLE1 "Athena Printing Charges"
28#define ACC "24745"
29#define OBJ "480"
30
31/* Global Variables */
32static char filename1[] = "/tmp/db_dumpXXXXXX";
33static char filename2[] = "/tmp/bursar_studentsXXXXXX";
34static char filename3[] = "/tmp/bursar_facultyXXXXXX";
35
36int clean1=0, clean2=0, clean3=0;
37extern int errno;
38
39FILE *fp, *fp2, *fp3;
40char realm[REALM_SZ];
41/* long quota_start_update(), quota_end_update(); */
42
43struct person {
44  char username[9];       /* NULL terminated username */
45  int number;
46  char flag;
47  char real_name[33];
48  struct person *next;
49};
50
51main(argc, argv)
52int argc;
53char *argv[];
54{
55  struct person *name_list, *read_name_list();
56  int dump(), kresult, cleanup();
57  struct tm *time_str;
58  int day, month, year;
59  long given_time;
60  /* long age; */
61  char semester;
62
63  signal(SIGINT, cleanup);
64
65/* set time for files */
66  given_time = time(0);
67  time_str = localtime(&given_time);
68  day = time_str->tm_mday;
69  year = time_str->tm_year;
70  month = time_str->tm_mon + 1;
71
72  if(argc != 3) {
73      fprintf(stderr, "bill_db user_file quota_db\n");
74      exit(1);
75  }
76/* ask user for semester */
77  printf("Please enter the semester.\n");
78  printf("    1 = Fall\n");
79  printf("    2 = Spring\n");
80  printf("    s = Summer\n");
81  scanf("%c", &semester);
82
83/* start */
84  kresult = krb_get_lrealm(realm, 1);
85  if (kresult != KSUCCESS)
86    fprintf(stderr, "bill_db: error in obtaining realm\n");
87  else if (!(name_list = read_name_list(argv[1])) && errno)
88    fprintf(stderr, "error in reading name list file %s\n", argv[1]);
89  else if (quota_db_set_name(argv[2]))
90    fprintf(stderr, "error in setting db name %s\n", argv[2]);
91  else {
92
93/* generate unique file names */
94    mktemp(filename1);
95    clean1=1;
96    mktemp(filename2);
97    clean2=1;
98    mktemp(filename3);
99    clean3=1;
100
101/* dump database */
102    fp = fopen(filename1, "w");
103    /* age = quota_start_update(argv[2]); */
104    if (quota_db_iterate(dump, 0) < 0)
105      exit(-1);
106    /* quota_end_update(argv[2], age); */
107    (void)fclose(fp);
108
109/* now use dump to generate bursar file and restore */
110    fp = fopen(filename1, "r");
111    fp2 = fopen(filename2, "w");
112    fp3 = fopen(filename3, "w");
113    /* age = quota_start_update(argv[2]); */
114    generate_bursar(name_list, month, day, year, semester);
115    /* quota_end_update(argv[2], age); */
116    (void)fclose(fp);
117    (void)fclose(fp2);
118    (void)fclose(fp3);
119    unlink(filename1);
120  }
121  exit(0);
122}
123
124/*
125 * Read_name_list function: Will read a name list file consisting of
126 * "username:social_security:flag:real_name" into memeory as a linked list.
127 */
128
129struct person *read_name_list(argv)
130char* argv;
131{
132  int trip=0;
133  struct person *current, *new, *name_list;
134  char user_name[9], flag, real_name[33];     /* NULL terminated username */
135  int number;
136
137  current = new = name_list = (struct person *)NULL;
138
139  errno = ENOENT;
140  if(!(fp = fopen(argv, "r"))) return NULL;
141  errno = 0;
142  while (fscanf(fp, "%[^:]:%d:%c:%[^\n]\n", user_name, &number, 
143                &flag, real_name) != EOF) {
144    if (trip == 1) 
145      new = (struct person *)malloc((unsigned)sizeof(struct person));
146    else {
147      name_list = (struct person *)malloc((unsigned)sizeof(struct person));
148      new = name_list;
149    }
150    if (new == NULL) {
151      fprintf(stderr, "Out of memeory at %s", user_name);
152      exit(-1);
153    }
154    strcpy(new->username, user_name);
155    new->number = number;
156    new->flag = flag;
157    strcpy(new->real_name, real_name);
158    new->next = NULL;
159    if (trip == 1)
160      current->next = new;
161    current = new;
162    trip = 1;
163  }
164  (void)fclose(fp);
165  if (trip == 0)
166    return((struct person *)NULL);
167  return(name_list);
168}
169
170/*
171 * dump function: will dump the database into a text file to be used
172 * with the upcoming fscanf to get user, realm, instance, and service.
173 */
174
175dump(arg, qrec)
176char *arg;
177quota_rec *qrec;
178{
179  fprintf(fp, "%s:%s:", qrec->name, qrec->instance);
180  fprintf(fp, "%s:%s:", qrec->realm, qrec->service);
181  fprintf(fp, "%d %d ", qrec->uid, qrec->quotaAmount);
182  fprintf(fp, "%d %d ", qrec->quotaLimit, qrec->lastBilling);
183  fprintf(fp, "%d %d ", qrec->lastCharge, qrec->pendingCharge);
184  fprintf(fp, "%d %d ", qrec->lastQuotaAmount, qrec->yearToDateCharge);
185  fprintf(fp, "%d %d\n", qrec->allowedToPrint, qrec->deleted);
186  return(0);
187}
188
189/*
190 * Generate_bursar Function: will use dumped database file, with the linked
191 * list in memory and generate two bursar files with appropriate formats
192 * and update the database using get and put principal functions.
193 */
194
195generate_bursar(name_list, month, day, year, semester)
196struct person *name_list;
197int month, day, year;
198char semester;
199{
200  quota_rec qrec, temp;
201  int billing_amount, found;
202  struct person *current;
203  int more;
204
205  bzero(&temp, sizeof(temp));
206  while (fscanf(fp, "%[^:]:%[^:]:%[^:]:%[^:]: %d %d %d %d %d %d %d %d %d %d\n",
207                 temp.name, temp.instance, temp.realm, temp.service,
208                 &temp.uid, &temp.quotaAmount, &temp.quotaLimit,
209                 &temp.lastBilling, &temp.lastCharge,
210                 &temp.pendingCharge, &temp.lastQuotaAmount,
211                 &temp.yearToDateCharge, &temp.allowedToPrint,
212                 &temp.deleted) != EOF) {
213    found = 0;
214    for (current = name_list; current && !found; current = current->next) {
215      if ((strcmp(realm, temp.realm) == 0) &&   
216          (strcmp(current->username, temp.name) == 0)) {
217        found = 1;
218
219        /* do calculations */
220        bzero(&qrec, sizeof(qrec));
221        if (quota_db_get_principal(temp.name, temp.instance, temp.service,
222                                   temp.realm, &qrec, (unsigned int)1,
223                                   &more) == 1) { 
224          billing_amount = qrec.quotaAmount - qrec.quotaLimit;
225          if (billing_amount < 500) {  /* restore and continue */
226            qrec.pendingCharge = billing_amount;
227            if (quota_db_put_principal(&qrec, (unsigned int)1) <= 0)
228              printf("database locked\n");
229            continue;
230          }
231          else if (billing_amount > 30000) {
232            qrec.pendingCharge = billing_amount - 30000;
233            billing_amount = 30000;
234          }
235          else
236            qrec.pendingCharge = 0;
237
238          /* now send to print routine */
239          print_bursar(current, month, day, year, semester, billing_amount);
240
241          /* now restore */
242          qrec.lastBilling = (quota_time)time(0);
243          qrec.lastCharge = billing_amount;
244          qrec.yearToDateCharge += billing_amount;
245          /* The following is to cause the quotaLimit
246             to reflect total allowed per managers request */
247          qrec.quotaLimit += billing_amount;
248          if (quota_db_put_principal(&qrec, (unsigned int)1) <= 0)
249            printf("database locked\n");
250        }
251        else
252          fprintf(stderr, "%s not found with get_principal", temp.name);
253      }
254    }
255    if (found) {
256      bzero(&temp, sizeof(temp));
257      continue;
258    }
259    /* else the username was not found */
260    if (temp.quotaAmount - temp.quotaLimit > 500) {
261      fprintf(stderr, "%s was not found in list and ", temp.name);
262      fprintf(stderr, "needs to be billed for %d.\n",
263              temp.quotaAmount - temp.quotaLimit);
264    }
265    bzero(&temp, sizeof(temp));
266  }
267  return(0);
268}
269
270/*
271 * print_bursar function: prints depending on flag of structure with
272 * proper formats
273 */
274
275print_bursar(user, month, day, year, semester, billing_amount)
276struct person *user;
277int month, day, year, billing_amount;
278char semester;
279{
280  if (user->flag == 's') {
281    /* print students into bursar file with proper format */
282    fprintf(fp2, "%3s", STUFF);             /* trans code */
283    fprintf(fp2, "%09d", user->number);  /* ID number */
284    fprintf(fp2, "%3s", ATHCODE);           /* Athena code */
285    fprintf(fp2, "%2d%c", year+(semester == '1' ? 1 : 0), semester);  /* semester */
286    fprintf(fp2, "%02d%02d%2d", month, day, year); /* billing date */
287    fprintf(fp2, "%08d", billing_amount);   /* amount */
288    fprintf(fp2, "%-30.30s", TITLE1);            /* title */
289    fprintf(fp2, "%5s", ACC);               /* account # */
290    fprintf(fp2, "%3s", OBJ);               /* obj code */
291    fprintf(fp2, "      ");                 /* space for Bursar code */
292    fprintf(fp2, "ATHN\n");                 /* office code */
293  }
294  else {
295    /* print faculty into bursar file with proper format */
296    fprintf(fp3, "         ");              /* blank */
297    fprintf(fp3, "%5s", ACC);               /* acount# */
298    fprintf(fp3, "%3s", OBJ);               /* obj code */
299    fprintf(fp3, "%3s", STUFF);             /* trans code */
300    fprintf(fp3, " ");                      /* blank */
301    fprintf(fp3, "%10s", TITLE);            /* title */
302    fprintf(fp3, "%8s:", user->username);   /* username */
303    fprintf(fp3, "%-23.23s", user->real_name);  /* real name */
304    fprintf(fp3, "%02d%02d%2d", month, day, year); /* billing date */
305    fprintf(fp3, "%011d", billing_amount);  /* amount */
306    fprintf(fp3, "J\n");                    /* weird char */
307  }
308}
309
310cleanup()
311{
312  if (clean1 == 1) {
313    unlink(filename1);
314  }
315  if (clean2 == 1) {
316    unlink(filename2);
317    fprintf(stderr, "%s removed.\n", filename2);
318  }
319  if (clean3 == 1) {
320    unlink(filename3);
321    fprintf(stderr, "%s removed.\n", filename3);
322  }
323  exit(-1);
324}
325
326void PROTECT(){}
327void UNPROTECT(){}
328
329
Note: See TracBrowser for help on using the browser.