root/trunk/athena/bin/lpr/quota/gbill_db.c @ 4280

Revision 4280, 8.3 KB (checked in by epeisach, 19 years ago)

Allow proper linking when DEBUG defined.

Line 
1/* $Source: /afs/dev.mit.edu/source/repository/athena/bin/lpr/quota/gbill_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 "gquota_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 = "gbill_db";
20int quota_debug=1;
21int gquota_debug=1;
22#endif
23
24/* Define all codes that that the bursar files will use. */
25#define STUFF "SU1"
26#define ATHCODE "385"
27#define TITLE "Printing: "
28#define ACC "24745"
29#define OBJ "480"
30
31/* file names*/
32static char filename1[] = "/tmp/db_dump_groupXXXXXX";
33static char filename2[] = "/tmp/bursar_groupsXXXXXX";
34
35int clean1=0, clean2=0;     /* cleanup temp variables */
36
37FILE *fp, *fp2;
38char realm[REALM_SZ];
39
40/* function declarations */
41/* long gquota_start_update(), gquota_end_update(); */
42int gquota_db_set_name(), gquota_db_iterate();
43int gquota_db_get_group(), gquota_db_put_group();
44
45struct group {
46  int group_number;
47  int account_number;
48  struct group *next;
49};
50
51main(argc, argv)
52int argc;
53char *argv[];
54{
55  struct group *group_list, *read_group_list();
56  int dump_groups(), 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, "gbill_db group_user_file quota_db\n");
74      exit(1);
75  }
76
77/* ask user for semester */
78  printf("Please enter the semester.\n");
79  printf("    1 = Fall\n");
80  printf("    2 = Spring\n");
81  printf("    s = Summer\n");
82  scanf("%c", &semester);
83
84/* start */
85  if (!(group_list = read_group_list(argv[1])))
86    fprintf(stderr, "error in reading group list file %s\n", argv[1]);
87  else if (gquota_db_set_name(argv[2]))
88    fprintf(stderr, "error in setting db name %s\n", argv[2]);
89  else {
90
91/* generate unique file names */
92    mktemp(filename1);
93    clean1=1;
94    mktemp(filename2);
95    clean2=1;
96
97/* dump database */
98    fp = fopen(filename1, "w");
99    /* age = gquota_start_update(argv[2]); */
100    if (gquota_db_iterate(dump_groups, 0) < 0)
101      exit(-1);
102    /* gquota_end_update(argv[2], age); */
103    (void)fclose(fp);
104
105/* now use dump to generate bursar file and restore */
106    fp = fopen(filename1, "r");
107    fp2 = fopen(filename2, "w");
108    /* age = gquota_start_update(argv[2]); */
109    generate_bursar(group_list, month, day, year, semester);
110    /* gquota_end_update(argv[2], age); */
111    (void)fclose(fp);
112    (void)fclose(fp2);
113    unlink(filename1);
114  }
115  exit(0);
116}
117
118/*
119 * Read_group_list function: Will read a group list file consisting of
120 * "group_number:account_number" into memeory as a linked list.
121 */
122
123struct group *read_group_list(argv)
124char* argv;
125{
126  int trip=0;
127  struct group *current, *new, *group_list;
128  int group, number;
129
130  current = new = group_list = (struct group *)NULL;
131
132  if(!(fp = fopen(argv, "r"))) return NULL;
133  while (fscanf(fp, "%d:%d\n", &number, &group) != EOF) {
134    if (trip == 1) 
135      new = (struct group *)malloc((unsigned)sizeof(struct group));
136    else {
137      group_list = (struct group *)malloc((unsigned)sizeof(struct group));
138      new = group_list;
139    }
140    if (new == NULL) {
141      fprintf(stderr, "Out of memeory at %d", group);
142      exit(-1);
143    }
144    new->group_number = group;
145    new->account_number = number;
146    new->next = NULL;
147    if (trip == 1)
148      current->next = new;
149    current = new;
150    trip = 1;
151  }
152  (void)fclose(fp);
153  if (trip == 0)
154    return(NULL);
155  return(group_list);
156}
157
158/*
159 * dump_groups function: will dump the database into a text file to be
160 * used with the upcoming fscanf to get service.
161 *
162 * Only the account # and service are needed for the gquota_db_get_group
163 * The first line is dumped for error purposes. The arrays of admin and
164 * user are ignored.
165 */
166
167dump_groups(arg, qrec)
168char *arg;
169gquota_rec *qrec;
170{
171  fprintf(fp, "%d:%s:", qrec->account, qrec->service);
172  fprintf(fp, "%8d:%8d:", qrec->admin[0], qrec->user[0]);
173  fprintf(fp, "%d ", qrec->quotaAmount);
174  fprintf(fp, "%d %d ", qrec->quotaLimit, qrec->lastBilling);
175  fprintf(fp, "%d %d ", qrec->lastCharge, qrec->pendingCharge);
176  fprintf(fp, "%d %d ", qrec->lastQuotaAmount, qrec->yearToDateCharge);
177  fprintf(fp, "%d %d\n", qrec->allowedToPrint, qrec->deleted);
178  return(0);
179}
180
181/*
182 * Generate_bursar Function: will use dumped database file, with the linked
183 * list in memory and generate a bursar file with appropriate format
184 * and update the database using get and put group functions.
185 *
186 * The dump doesn't contain admin and user lists. That info is not needed
187 * for billing purposes.
188 */
189
190generate_bursar(group_list, month, day, year, semester)
191struct group *group_list;
192int month, day, year;
193char semester;
194{
195  gquota_rec qrec, temp;
196  struct group *current;
197  int billing_amount, found, more;
198
199  while (fscanf(fp, "%d:%[^:]:%d:%d: %d %d %d %d %d %d %d %d %d\n", 
200                &temp.account, temp.service, &temp.admin[0], &temp.user[0],
201                &temp.quotaAmount, &temp.quotaLimit,
202                &temp.lastBilling, &temp.lastCharge,
203                &temp.pendingCharge, &temp.lastQuotaAmount,
204                &temp.yearToDateCharge, &temp.allowedToPrint,
205                &temp.deleted) != EOF) {
206    found = 0;
207    for (current = group_list; current && !found; current = current->next) {
208      if (current->account_number == temp.account) {
209        found = 1;
210
211        /* do calculations */
212        bzero(&qrec, sizeof(qrec));
213        if (gquota_db_get_group(temp.account, temp.service, &qrec,
214                                (unsigned int)1, &more) == 1) {
215          billing_amount = qrec.quotaAmount - qrec.quotaLimit
216            - qrec.yearToDateCharge;
217          if (billing_amount < 500) {  /* restore and continue */
218            qrec.pendingCharge = billing_amount;
219            if (gquota_db_put_group(&qrec, (unsigned int)1) <= 0)
220              printf("database locked\n");
221            continue;
222          }
223          else if (billing_amount > 30000) {
224            qrec.pendingCharge = billing_amount - 30000;
225            billing_amount = 30000;
226          }
227          else
228            qrec.pendingCharge = 0;
229
230          /* now send to print routine */
231          print_bursar(current, month, day, year, semester, 
232                       billing_amount);
233         
234          /* now restore */
235          qrec.lastBilling = (gquota_time)time(0);
236          qrec.yearToDateCharge += billing_amount;
237          /* The following is to cause the quotaLimit
238             to reflect total allowed per managers request */
239          qrec.quotaLimit += billing_amount;
240          if (gquota_db_put_group(&qrec, (unsigned int)1) <= 0)
241            printf("database locked\n");
242        }
243        else
244          fprintf(stderr, "%d not found with get_group", temp.account);
245      }
246    }
247    if (found)
248      continue;
249
250    /* else the temp.account was not found */
251    if (temp.quotaAmount - temp.quotaLimit - temp.yearToDateCharge > 500) {
252      fprintf(stderr, "Group %d was not found in list and ", temp.account);
253      fprintf(stderr, "needs to be billed for %d.\n",
254              temp.quotaAmount - temp.quotaLimit - temp.yearToDateCharge);
255    }
256  }
257  return(0);
258}
259
260/*
261 * print_bursar function: prints to tmp file with proper formats
262 */
263
264print_bursar(group, month, day, year, semester, billing_amount)
265struct group *group;
266int month, day, year, billing_amount;
267char semester;
268{
269  /* print students into bursar file with proper format */
270  fprintf(fp2, "%3s", STUFF);             /* trans code */
271  fprintf(fp2, "%09d", group->account_number);    /* ID number */
272  fprintf(fp2, "%3s", ATHCODE);           /* Athena code */
273  fprintf(fp2, "%2d%c", year+(semester == '1' ? 1 : 0), semester);  /* semester */
274  fprintf(fp2, "%02d%02d%2d", month, day, year); /* billing date */
275  fprintf(fp2, "%08d", billing_amount);   /* amount */
276  fprintf(fp2, "%10s", TITLE);            /* title */
277  fprintf(fp2, "%-20.20d", group->group_number);  /* real name */
278  fprintf(fp2, "%5s", ACC);               /* account # */
279  fprintf(fp2, "%3s", OBJ);               /* obj code */
280  fprintf(fp2, "      ");                 /* space for Bursar code */
281  fprintf(fp2, "ATHN\n");                 /* office code */
282}
283
284cleanup()
285{
286  if (clean1 == 1) {
287    unlink(filename1);
288  }
289  if (clean2 == 1) {
290    unlink(filename2);
291    fprintf(stderr, "%s removed.\n", filename2);
292  }
293  exit(-1);
294}
295
296void PROTECT(){}
297void UNPROTECT(){}
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
Note: See TracBrowser for help on using the browser.