source: trunk/athena/bin/lpr/quota/gbill_db.c @ 4371

Revision 4371, 8.2 KB checked in by epeisach, 33 years ago (diff)
Do not subtract the YTD charge in determining if someone should be billed. The limit is upped when someone is charged.
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          if (billing_amount < 500) {  /* restore and continue */
217            qrec.pendingCharge = billing_amount;
218            if (gquota_db_put_group(&qrec, (unsigned int)1) <= 0)
219              printf("database locked\n");
220            continue;
221          }
222          else if (billing_amount > 30000) {
223            qrec.pendingCharge = billing_amount - 30000;
224            billing_amount = 30000;
225          }
226          else
227            qrec.pendingCharge = 0;
228
229          /* now send to print routine */
230          print_bursar(current, month, day, year, semester,
231                       billing_amount);
232         
233          /* now restore */
234          qrec.lastBilling = (gquota_time)time(0);
235          qrec.yearToDateCharge += billing_amount;
236          /* The following is to cause the quotaLimit
237             to reflect total allowed per managers request */
238          qrec.quotaLimit += billing_amount;
239          if (gquota_db_put_group(&qrec, (unsigned int)1) <= 0)
240            printf("database locked\n");
241        }
242        else
243          fprintf(stderr, "%d not found with get_group", temp.account);
244      }
245    }
246    if (found)
247      continue;
248
249    /* else the temp.account was not found */
250    if (temp.quotaAmount - temp.quotaLimit > 500) {
251      fprintf(stderr, "Group %d was not found in list and ", temp.account);
252      fprintf(stderr, "needs to be billed for %d.\n",
253              temp.quotaAmount - temp.quotaLimit);
254    }
255  }
256  return(0);
257}
258
259/*
260 * print_bursar function: prints to tmp file with proper formats
261 */
262
263print_bursar(group, month, day, year, semester, billing_amount)
264struct group *group;
265int month, day, year, billing_amount;
266char semester;
267{
268  /* print students into bursar file with proper format */
269  fprintf(fp2, "%3s", STUFF);             /* trans code */
270  fprintf(fp2, "%09d", group->account_number);    /* ID number */
271  fprintf(fp2, "%3s", ATHCODE);           /* Athena code */
272  fprintf(fp2, "%2d%c", year+(semester == '1' ? 1 : 0), semester);  /* semester */
273  fprintf(fp2, "%02d%02d%2d", month, day, year); /* billing date */
274  fprintf(fp2, "%08d", billing_amount);   /* amount */
275  fprintf(fp2, "%10s", TITLE);            /* title */
276  fprintf(fp2, "%-20.20d", group->group_number);  /* real name */
277  fprintf(fp2, "%5s", ACC);               /* account # */
278  fprintf(fp2, "%3s", OBJ);               /* obj code */
279  fprintf(fp2, "      ");                 /* space for Bursar code */
280  fprintf(fp2, "ATHN\n");                 /* office code */
281}
282
283cleanup()
284{
285  if (clean1 == 1) {
286    unlink(filename1);
287  }
288  if (clean2 == 1) {
289    unlink(filename2);
290    fprintf(stderr, "%s removed.\n", filename2);
291  }
292  exit(-1);
293}
294
295void PROTECT(){}
296void UNPROTECT(){}
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
Note: See TracBrowser for help on using the repository browser.