63a1a95fec126142e742b7744e85d83a243fc619
[mspang/plceo1.git] / lib_sys.pl
1 #
2 # Date                  Name                            Modification
3 # ----          ----                ------------
4 # 94/09/12              Alex Brodsky            Split off from main ceo file
5 # 96/05/17              Nikita Borisov          Added ISBN checks
6 # 96/10/23              Nikita Borisov          Use dbmtie instead of fakedbm
7 # 96/10/24              Nikita Borisov          'use NDBM_File' to make dbmopen
8 #                                                                       use that format.  Should really
9 #                                                                       replace them with 'tie' sometime
10 #                                                                       soon.
11 #
12
13
14 require "/u/ceo/ceo/isbn.pl";
15 use NDBM_File;
16
17 sub librarymenu
18 {
19     local($menu) = <<EOM;
20
21 Choose an option:
22   Sign a book (I)n
23   Sign a book (O)ut
24   (V)iew outstanding books list
25   (E)dit book list
26   (M)ain menu
27
28 (I,O,V,M): 
29 EOM
30     @opts=('idobookin','odobookout','vdooutstanding','mmainmenu','edoeditdb' );
31     $choice = &domenu($menu,@opts);
32     return $choice;
33 }
34
35 sub dobookin
36 {
37     local ($bid);
38         local ($yes);
39     ## Get the book ID
40     while(1)
41     {
42         print "Enter the book ID: ";
43         chop($bid = <STDIN>);
44         $bid =~ s/[^\w-]//g;
45                 # let people type 0-07-054235-x
46                 $bid =~ tr/x/X/;
47         if ($bid =~ /^\s*$/)
48         {
49             print "\n${beep}No ID supplied - aborting.\n";
50             return;
51         }
52         unless (&validbookID($bid))
53         {
54             print "\n${beep}Invalid checksum - try again.\n\n";
55             next;
56         }
57                 unless (&ISBN_checksum($bid)) {
58                         print "\n${beep}WARNING: Invalid ISBN: $bid.\n",
59                                   "Are you sure this is the right ID? ";
60                         $yes = <STDIN>;
61                         next unless $yes =~ /^y/i;
62                 }
63         last;
64     }
65
66     dbmopen(LIB, $LIBDB, 0600) || do
67     {
68         print "\n${beep}Error opening library database: $!\n";
69         return;
70     };
71
72     ## Make a library entry for this book, if none already
73     &Lib_Newbook($bid) unless defined $LIB{$bid};
74
75     ## Mark the book as being in the library
76     if (defined $LIB{$bid})
77     {
78         $LIB{$bid} =~ s/W\{([^\}]*)\}/W\{0\}/;
79         $whohad = $1;
80     }
81
82     ($btitle) = $LIB{$bid} =~ /N\{([^\}]*)\}/;
83
84     dbmclose(LIB);
85     &Backup("$LIBDB.db");
86     &Backup("$LIBDB.dir");
87     &Backup("$LIBDB.pag");
88
89     if ($whohad == 0)
90     {
91         print "\n${beep}No one had this book signed out - aborting.\n\n";
92         return;
93     }
94     
95     eval { dbmtie($MEMDB,\%MEM) } || do
96     {
97         print "\n${beep}Error opening members database: $!\n";
98         return;
99     };
100     $thename = (split(/;/,$MEM{$whohad}))[0];
101     dbmuntie(\%MEM);
102
103     ## Make an entry in the library log file
104     open (LIBLOG, ">>$LIBRARYLOG") || do
105     {
106         print "\n${beep}Error writing library log file: $!\n";
107         return;
108     };
109     chop($date = `date`);
110     print LIBLOG "$date;$whohad;$thename;IN;$bid;$btitle\n";
111     close(LIBLOG);
112
113     Backup($LIBRARYLOG);
114
115     print "\"$btitle\" has been received from $thename.\n";
116
117     &Gopher_Outstanding;
118 }
119
120 sub dobookout
121 {
122     local($memnum,$thename,$thepw,$bid,$flags,$btitle);
123     ## Who wants it?
124     print "Enter CSC member number: ";
125     chop($memnum=<STDIN>);
126     $memnum =~ s/\D//g;
127     if ($memnum =~ /^\s*$/)
128     {
129         print "\n${beep}No member number supplied - aborting.\n";
130         return;
131     }
132
133     ## Get the info on this member
134     eval { dbmtie($MEMDB,\%MEM) } || do
135     {
136         print "\n${beep}Unable to open member database: $!\n";
137         return;
138     };
139     unless (defined $MEM{$memnum})
140     {
141         print "\n${beep}No such member number is on record - aborting\n";
142         dbmuntie(\%MEM);
143         return;
144     }
145     $match = grep(/^$TERM$/,split(/,/,(split(/;/,$MEM{$memnum}))[7]));
146     unless ($match)
147     {
148         print "\n${beep}This member has not paid for the current term.\n";
149         dbmuntie(\%MEM);
150         return;
151     }
152     ($thename, $thepw) = (split(/;/,$MEM{$memnum}))[0,5];
153     dbmuntie(\%MEM);
154
155     if ($thepw ne "" && $ENV{'CALUM'} != 1)
156     {
157         print "Enter your CSC password: ";
158         if (crypt(&GetPass, $thepw) ne $thepw)
159         {
160             print "\n${beep}Incorrect password - aborting\n";
161             return;
162         }
163     }
164
165     print "\nName: $thename\n\n";
166
167     ## Get the book ID
168     while(1)
169     {
170         print "Enter the book ID: ";
171         chop($bid = <STDIN>);
172         $bid =~ s/[^\w-]//g;
173         if ($bid =~ /^\s*$/)
174         {
175             print "\n${beep}No ID supplied - aborting.\n";
176             return;
177         }
178         unless (&validbookID($bid))
179         {
180             print "\n${beep}Invalid checksum - try again.\n\n";
181             next;
182         }
183                 unless (&ISBN_checksum($bid)) {
184                         print "\n${beep}WARNING: Invalid ISBN: $bid.\n",
185                                   "Are you sure this is the right ID? ";
186                         $yes = <STDIN>;
187                         next unless $yes =~ /^y/i;
188                 }
189         last;
190     }
191     
192     ## Read the library file
193     dbmopen(LIB, $LIBDB, 0600) || do
194     {
195         print "\n${beep}Error opening library database: $!\n";
196         return;
197     };
198
199     ## Make a library entry for this book, if none already
200     &Lib_Newbook($bid) unless defined $LIB{$bid};
201
202     if (defined $LIB{$bid})
203     {
204         ## Does someone have the book now?
205         $LIB{$bid} =~ /W\{([^\}]*)\}/;
206         $whohad = $1;
207         if ($whohad > 0)
208         {
209             ## Who has it?
210             dbmclose(LIB);
211             eval { dbmtie($MEMDB,\%MEM) } || do
212             {
213                 print "\n${beep}Unable to open members database: $!\n";
214                 return;
215             };
216             $hasname = (split(/;/,$MEM{$whohad}))[0];
217             dbmuntie(\%MEM);
218
219             print "\n${beep}This book is presently signed out to $hasname.\n";
220             print "Please sign it back in first.\n\n";
221             return;
222         }
223
224         ## Check the flags
225         $LIB{$bid} =~ /T\{([^\}]*)\}/;
226         $flags = $1;
227         if ($flags =~ /r/i)
228         {
229             ## Red dot
230             print "This book has a red dot.  It may not be removed from the CSC.\n";
231             dbmclose(LIB);
232             return;
233         }
234         if ($flags =~ /b/i)
235         {
236             ## Blue rectangle
237             print "This book has a blue rectangle.  It may only be taken to labs in MC and must be\n";
238             print "returned promptly.\n";
239         }
240
241         ## Mark the book as being out
242         $LIB{$bid} =~ s/W\{[^\}]*\}/W\{$memnum\}/;
243         chop($date = `date`);
244         $LIB{$bid} =~ s/D\{[^\}]*\}/D\{$date\}/;
245
246         ($btitle) = $LIB{$bid} =~ /N\{([^\}]*)\}/;
247
248         dbmclose(LIB);
249         &Backup("$LIBDB.db");
250                 &Backup("$LIBDB.dir");
251                 &Backup("$LIBDB.pag");
252
253         print "\"$btitle\" has been signed out.\n";
254
255         ## Make an entry in the library log file
256         open (LIBLOG, ">>$LIBRARYLOG") || do
257         {
258             print "\n${beep}Error writing library log file: $!\n";
259             return;
260         };
261         print LIBLOG "$date;$memnum;$thename;OUT;$bid;$btitle\n";
262         close(LIBLOG);
263
264         &Backup($LIBRARYLOG);
265         &Gopher_Outstanding;
266
267         print "Thank you.  Please return it as soon as possible.\n\n";
268     }
269 }
270
271 sub Lib_Newbook
272 {
273     local($bookid) = shift;
274     @answers = ("","","","","","N","N");
275     while(1)
276     {
277     &Editscreen(<<EOS);
278 This book is not in the library database.
279 Please enter the requested information.
280 Separate multiple entries of the same type (e.g. multiple authors)
281 by semicolons (;).
282
283 Do NOT break an entry across lines; let the line wrap.
284
285 Name/Title    : $answers[0]
286 Author/Editor : $answers[1]
287 Publisher     : $answers[2]
288 Year published: $answers[3]
289 ISBN          : $answers[4]
290 Does the book have a Red dot, Blue rectangle, or Nothing?
291        (R/B/N): $answers[5]
292 Is the book on loan to CSC?
293          (Y/N): $answers[6]
294 EOS
295     &VI;
296     @answers = split("\n",&Filterscreen);
297     grep(s/\}/\]/g,@answers);
298     if ($answers[0] =~ /^\s*$/)
299     {
300         print "\n${beep}No title given - aborting.\n\n";
301         return;
302     }
303     $answers[3] =~ s/\D//g;
304     $answers[4] =~ s/[^\dxX -]//g;
305     $answers[4] =~ s/x/X/g;
306     $answers[5] =~ s/^(.).*$/\u$1/;
307     $answers[5] =~ s/[^RBN]//g;
308     if ($answers[5] eq "")
309     {
310         print "\n${beep}Entry for R/B/N required.\n";
311         sleep 2;
312         next;
313     }
314     $answers[6] =~ s/^(.).*$/\u$1/;
315     $answers[6] =~ s/[^YN]//g;
316     if ($answers[6] eq "")
317     {
318         print "\n${beep}Entry for Y/N required.\n";
319         sleep 2;
320         next;
321     }
322     $answers[6] =~ s/N//;
323     $answers[6] =~ s/Y/L/;
324     last;
325     }
326
327     $LIB{$bookid} = "N{$answers[0]}A{$answers[1]}P{$answers[2]}Y{$answers[3]}I{$answers[4]}T{$answers[5]$answers[6]}W{0}D{Epoch}";
328
329 }
330
331
332 sub MakeOutstandFile
333 {
334  ## Read the library file
335     dbmopen(LIB, $LIBDB, 0600) || do
336     {
337         print "\n${beep}Error opening library database: $!\n";
338         return;
339     };
340     %Outstand = ();
341     foreach $bid (keys %LIB)
342     {
343         ($whohas) = $LIB{$bid} =~ /W\{(\d+)\}/;
344         next if $whohas == 0;
345         ($btitle) = $LIB{$bid} =~ /N\{([^\}]*)\}/;
346         ($bodate) = $LIB{$bid} =~ /D\{([^\}]*)\}/;
347                 $bodate =~ s/^[^ ]* (.*):\d* E.T/$1/;
348         $Outstand{$bid}="$whohas#$btitle#$bodate";
349     }
350     dbmclose(LIB);
351
352     eval { dbmtie($MEMDB,\%MEM) } || do
353     {
354         print "\n${beep}Error opening members database: $!\n";
355         return;
356     };
357     open (OUTSTAND, ">$editfile") || do
358     {
359         print "\n${beep}Unable to open outstanding books file: $!\n";
360         dbmuntie(\%MEM);
361         return;
362     };
363     select(OUTSTAND);
364     $-=0;
365     $= = shift;
366     foreach $obid (keys %Outstand)
367     {
368         ($onum,$obtitle,$odate) = $Outstand{$obid} =~ /^(.*)#(.*)#(.*)$/;
369         $oname = (split(/;/,$MEM{$onum}))[0];
370         write;
371     }
372     dbmuntie(\%MEM);
373     select(STDOUT);
374     close(OUTSTAND);
375 }
376
377 sub DisplayLibLog
378 {
379     open(LIBLOG, $LIBRARYLOG) || do
380     {
381         print "\n${beep}Unable to open library log: $!\n";
382         return;
383     };
384     open(SCRLIBLOG, ">$editfile") || do
385     {
386         print "\n${beep}Unable to open output file: $!\n";
387         close(LIBLOG);
388         return;
389     };
390     select(SCRLIBLOG);
391     $-=0;
392     $= = $ROWS - 1;
393     ##$_ = `stty size`; ($=) = /^(\d+)/; $= -= 2;
394     while(<LIBLOG>)
395     {
396         next if (/^\s*$/ || /^\s*#/);
397         ($ldate, $lnum, $lname, $ldir, $bid, $lbtitle) = split(/;/);
398         next if $lnum==0;
399                 ($ldate) = $ldate =~ /^... (.*):.. .*$/;
400         write;
401     }
402     close(LIBLOG);
403     select(STDOUT);
404     close(SCRLIBLOG);
405     &MORE;
406 }
407
408 sub Gopher_Outstanding
409 {
410  ## Read the library file
411     dbmopen(LIB, $LIBDB, 0600) || do
412     {
413         print "\n${beep}Error opening library database: $!\n";
414         return;
415     };
416     %Outstand = ();
417     foreach $bid (keys %LIB)
418     {
419         ($whohas) = $LIB{$bid} =~ /W\{(\d+)\}/;
420         next if $whohas == 0;
421         ($btitle) = $LIB{$bid} =~ /N\{([^\}]*)\}/;
422         ($bodate) = $LIB{$bid} =~ /D\{([^\}]*)\}/;
423         $Outstand{$bid}="$whohas#$btitle#$bodate";
424     }
425     dbmclose(LIB);
426
427     eval { dbmtie($MEMDB,\%MEM) } || do
428     {
429         print "\n${beep}Error opening members database: $!\n";
430         return;
431     };
432     open (OUTSTAND, ">$GOPHERDIR/library_outstand") || do
433     {
434         print "\n${beep}Unable to open outstanding books file: $!\n";
435         dbmuntie(\%MEM);
436         return;
437     };
438     select(OUTSTAND);
439     $-=0;
440     $= = 50000;
441     foreach $obid (keys %Outstand)
442     {
443         ($onum,$obtitle,$odate) = $Outstand{$obid} =~ /^(.*)#(.*)#(.*)$/;
444         $oname = (split(/;/,$MEM{$onum}))[0];
445         write;
446     }
447     dbmuntie(\%MEM);
448     select(STDOUT);
449     close(OUTSTAND);
450 #   &MakeOutstandFile(50000);
451 #   system <<EOJ;
452 #rcp $editfile csc_disk@descartes:Gopher/office_info/library_outstand
453 #EOJ
454 }
455
456 sub validbookID
457 {
458     local($bid) = shift;
459     return 1;
460 }
461
462 sub dooutstanding
463 {
464     ##$_ = `stty size`; ($height) = /^(\d+)/; $height -= 2;
465     $height = $ROWS - 2;
466     &MakeOutstandFile($height);
467     &MORE;
468 }
469
470 sub doeditdb
471 {
472     local($memnum,$thename,$thepw,$bid,$flags,$btitle);
473     ## Who wants it?
474     unless ($ENV{'CALUM'} == 1){
475                 print "Enter CSC member number: ";
476                 chop($memnum=<STDIN>);
477                 $memnum =~ s/\D//g;
478                 if ($memnum =~ /^\s*$/)
479                 {
480                         print "\n${beep}No member number supplied - aborting.\n";
481                         return;
482                 }
483                 $match = grep(/^$memnum$/,@oslist);
484                 unless (($match || $cscmem == 0) && $cscmem =~ /\d/)
485                 {
486                         print "Access denied.\n";
487                         return;
488                 }
489
490                 ## Get the info on this member
491                 eval { dbmtie($MEMDB,\%MEM) } || do
492                 {
493                         print "\n${beep}Unable to open member database: $!\n";
494                         return;
495                 };
496                 unless (defined $MEM{$memnum})
497                 {
498                         print "\n${beep}No such member number is on record - aborting\n";
499                         dbmuntie(\%MEM);
500                         return;
501                 }
502                 $match = grep(/^$TERM$/,split(/,/,(split(/;/,$MEM{$memnum}))[7]));
503                 unless ($match)
504                 {
505                         print "\n${beep}This member has not paid for the current term.\n";
506                         dbmuntie(\%MEM);
507                         return;
508                 }
509                 ($thename, $thepw) = (split(/;/,$MEM{$memnum}))[0,5];
510                 dbmuntie(\%MEM);
511
512                 if ($thepw ne "" && $ENV{'CALUM'} != 1)
513                 {
514                         print "Enter your CSC password: ";
515                         if (crypt(&GetPass, $thepw) ne $thepw)
516                         {
517                                 print "\n${beep}Incorrect password - aborting\n";
518                                 return;
519                         }
520                 }
521         }
522
523         if( !open(TMPFILE, ">lib.edit") ){
524         print "\n${beep}Error opening temporary file: $!\n";
525         }
526
527     ## Read the library file
528     dbmopen(LIB, $LIBDB, 0600) || do
529     {
530         print "\n${beep}Error opening library database: $!\n";
531                 close TMPFILE;
532         return;
533     };
534
535         for (keys %LIB){
536                 print TMPFILE "$_#$LIB{$_}\n";
537         }
538
539         close TMPFILE;
540
541         system( "rm -f lib.backup;cp lib.edit lib.backup" );
542         system( "/opt/bin/nvi lib.edit" );
543
544         if( open(TMPFILE, "lib.edit") ){
545                 %LIB = ();
546                 while( $_ = <TMPFILE> ){
547                         chomp $_;
548                         /^([^ ]*)#(.*)$/;
549                         $LIB{$1} = $2;
550                 }
551                 close TMPFILE;
552         } else {
553         print "\n${beep}Error opening temporary file: $!\n";
554         }
555
556         dbmclose(LIB);
557         &Backup("$LIBDB.db");
558         &Backup("$LIBDB.dir");
559         &Backup("$LIBDB.pag");
560
561         &Gopher_Outstanding;
562 }
563 1;