/* * * reg.c - Lysators medlemsregister. A few things to remember are 1. when * answering a question be sure to answer with the first letter * typed, 2. all reports are local to connected directory and are * always appended to whatever was in them before. * * * usage: reg [file] * * * jp 891218 - the original * jp 901112 - added sending mail (using program "mail" within system()) * to members being late. * jp 901116 - minor changes: LINELEN;Member# in decimal also. * jp 901127 - made it unix-compatible using fork(),exec(),time(),etc. also * a check on 'operator' is made (sending mail + updating the * register on disk), consisting of check of access(read+write) on * the datafile. * jp 910411 - A few minor changes concerning payment and editing. * */ #include #include #include #include /* ***** declarations ***** */ #define VERSION "jp 910411" /* guess what! */ #ifndef NULL #define NULL 0 #endif /* the maximum no of members in the struct[] */ #ifndef MEMBERS #define MEMBERS 1024 #endif /* LINELEN = how many chars on a line (in datatype 'line'), has it's dependencies during printout also! (%65s %-65s ... ) */ #ifndef LINELEN #define LINELEN 65 #endif /* MEMBERFEE is the default memberfee, remenber that the fee is NOT saved! */ #ifndef MEMBERFEE #define MEMBERFEE 128 #endif /* just in case */ #ifndef __STDC__ #ifndef void #define void int #endif #endif /* our datafile on disk */ /* @elinor: PS:MEMBERS.LYS @lage: members.lys @nanny: /usr/adm/reg/members.lys */ #ifndef DATAFILE #define DATAFILE "/users/ceder/Lysator/kassor/members.lys" #endif /* our reportfile, here goes all printouts to reports */ #ifndef REPORTFILE #define REPORTFILE "lys.rpt" #endif /* our POSTGIRO-file, is used to generate pay-bills (with or without name) */ #ifndef POSTGIROFILE #define POSTGIROFILE "lys.pg" #endif /* our mailfile, this is the letter that will be sent to all who are late paying their memberfee */ #ifndef MAILFILE #define MAILFILE "lys.pay" #endif /* the number of fields in struct {} reg[]; */ #define NFIELDS 8 /* guess what! */ #define UPC(x) (((x >= 'a') && (x <= '}'))?(x & ~0x20):(x)) #define EQUAL(a,b) (UPC(a) == UPC(b)) /* our variables etc. */ typedef char line[LINELEN]; struct { line name,adr[2],tel,email,remark; int active,expdate,index; } reg[MEMBERS+1]; /* remember: reg[0] == dummy record! */ struct { int no_of_members,date,memberfee,sorted,operator; line df_filename; FILE *df,*rf,*pg; /* df=datafile,rf=reportfile,pg=postgiro */ } regstatus; void newreg(); /* ***** help routines ***** */ int get_line(f,s) /* get line from file 'f' and put into 's', do some checking also */ FILE *f; char *s; { int c,n=0; while (1) { if ( (c=getc(f)) == EOF) return 1; n++; if ((c=='\n')||(c=='\r')) { *s='\0'; return 0; } if (n==LINELEN-1) { *s='\0'; while ( (c=getc(f)) != EOF) if ((c=='\n')||(c=='\r')) break; printf("\n***ERROR: too long input - cut off!\n\n"); return 0; } *s++ = (char) c; } } void str_copy(s,t) /* copy string 't' into 's' */ char *s,*t; { while ( (*s++ = *t++) != (char)NULL); } int str_less(i,j) /* return (s=1) { printf("."); fflush(stdout); for(i=1;i<=n-d;i++) { j=i; while (j>=1) { if (!str_less(j+d,j)) break; reg[0].index = reg[j+d].index; reg[j+d].index = reg[j].index; reg[j].index = reg[0].index; j-=d; } } d/=2; } regstatus.sorted=1; /* indicate that it is sorted */ } void clear_record(i) /* clear record# 'i' */ int i; { str_copy(reg[i].name,""); str_copy(reg[i].adr[0],""); str_copy(reg[i].adr[1],""); str_copy(reg[i].tel,""); str_copy(reg[i].email,""); str_copy(reg[i].remark,""); reg[i].active=0; reg[i].expdate=0; if (i) regstatus.sorted=0; /* indicate register not sorted */ } int ascii_to_int(s,n) /* convert string in 's' into an integer and put in '*n' , return 0=ok, 1=error */ char *s; int *n; { int res=0; while (*s) { if ((*s<'0')||(*s>'9')) return 1; res=res*10+((int)*s++ & ~'0'); if (res<0) return 1; /* overflow! */ } *n = res; return 0; } void int_to_bin(s,n) /* convert integer 'n' into string 's' of binary numbers */ char *s; int n; { line tmp; char *t=tmp,*p=s; int i=n; str_copy(s,"0"); if (!n) return; while (i) { *t++ = (char)((i&1)|'0'); i>>=1; } while (t!=tmp) *p++ = *--t; *p='\0'; } int bin_to_int(s,n) /* convert binary string in 's' into integer in '*n', return 0=ok, 1=error */ char *s; int *n; { *n=0; while (*s) { if ((*s<'0')||(*s>'1')) return 1; *n<<=1; *n|=(*s++ & ~'0'); } return 0; } int get_record() /* get record from regstatus.df_filename, save in temporary buffer (reg[0], return 0=ok, 1=error */ { int i; line tmp[NFIELDS]; clear_record(0); for(i=0;iregstatus.no_of_members) regstatus.no_of_members=i; if (i > MEMBERS) { printf("***ERROR: register has grown too large, please "); printf("recompile with larger value\n on MEMBERS "); printf("(now: %d)\n",MEMBERS); regstatus.no_of_members=MEMBERS; newreg(); exit(1); } str_copy(reg[i].name,reg[0].name); str_copy(reg[i].adr[0],reg[0].adr[0]); str_copy(reg[i].adr[1],reg[0].adr[1]); str_copy(reg[i].tel,reg[0].tel); str_copy(reg[i].email,reg[0].email); reg[i].active=reg[0].active; reg[i].expdate=reg[0].expdate; str_copy(reg[i].remark,reg[0].remark); regstatus.sorted=0; /* indicate register not sorted */ } void status() /* show some status on this register */ { int i,m=0; for(i=1;i<=regstatus.no_of_members;i++) if (reg[i].active) m++; printf("\nRegister status: Date=%d Members=%d (%d active) Fee=%d\n\n",regstatus.date,regstatus.no_of_members,m,regstatus.memberfee); printf("Files: Data='%s', Report='%s'\n",regstatus.df_filename,REPORTFILE); printf(" Postgiro='%s', Mail='%s'\n",POSTGIROFILE,MAILFILE); printf("Status: Register is %ssorted in name-order\n",regstatus.sorted?"":"NOT "); printf(" User is %san operator (mail + update register)\n",regstatus.operator?"":"NOT "); printf(" Maximum linelength=%d\n",LINELEN); } void show_verbose(f,i,tmp) /* show verbose info in report */ FILE *f; int i; char *tmp; { fprintf(f,"%15s (#%5d) %s\n",tmp,i,reg[i].name); fprintf(f,"%24s %s\n","",reg[i].adr[0]); fprintf(f,"%24s %s\n","",reg[i].adr[1]); fprintf(f,"%24s %s\n","",reg[i].tel); fprintf(f,"%24s %s\n","",reg[i].email); fprintf(f,"%24s %s\n","",reg[i].remark); fprintf(f,"%24s %sctive member\tExpdate: %d\n\n","",reg[i].active?"A":"Ina",reg[i].expdate); } void show_brief(f,i,tmp) /* show brief info in report */ FILE *f; int i; char *tmp; { line z; str_copy(z,reg[i].name); z[40]='\0'; if (f==stdout) fprintf(f,"%15s (#%5d) %s\n",tmp,i,z); else fprintf(f,"%15s (#%5d) %-40s %s\n",tmp,i,z,reg[i].email); } void pay_brief(f,i,tmp) /* show brief info on payments */ FILE *f; int i; char *tmp; { line z; str_copy(z,reg[i].name); z[40]='\0'; if (f==stdout) fprintf(f,"%15s (#%5d) %-40s %6d\n",tmp,i,z,reg[i].expdate); else fprintf(f,"%15s (#%5d) %-40s %6d %s\n",tmp,i,z,reg[i].expdate,reg[i].email); } void hdr_line(f,m) /* output a headerline, m=1 if in payments */ FILE *f; int m; { fprintf(f,"------------------------ "); fprintf(f,"----------------------------------------"); fprintf(f,"%s",m?" ---------":""); fprintf(f,"%s\n",(f!=stdout)?" ---------------":""); } void hdr_verbose(f,s) /* give verbose report header */ FILE *f; char *s; { fprintf(f,"\n\n%s, date=%d, %d members\n\n",s,regstatus.date,regstatus.no_of_members); fprintf(f,"\n%-24s Name\n","Member#"); fprintf(f,"%24s Address\n",""); fprintf(f,"%24s Tel\n",""); fprintf(f,"%24s Email\n",""); fprintf(f,"%24s Remark\n",""); fprintf(f,"%24s Activity \tExpdate\n",""); hdr_line(f,0); } void hdr_brief(f,s,l,m) /* give brief header */ FILE *f; char *s; int l,m; { fprintf(f,"\n\n%s, date=%d, %d members\n\n",s,regstatus.date,regstatus.no_of_members); fprintf(f,"\n%-24s %-40s%s","Member#","Name",l?" Expdate":""); fprintf(f,"%s\n",(f!=stdout)?" Email":""); hdr_line(f,m); } int match(t,s) /* try to find a match of the string 's' in 't' */ char *s,*t; { char *a=s,*b; while (*t) { while (*t) { if (EQUAL(*t,*s)) break; t++; } if (!*t) break; b=t; while (*s) { s++; t++; if (!EQUAL(*s,*t)) break; } if (!*s) return(1); if (!*t) break; s=a; t= ++b; } return(0); } void match_name(s) /* show all who match string 's' */ char *s; { line tmp; int cnt=0,i; sprintf(tmp,"Report on members matching '%s'",s); hdr_brief(stdout,tmp,0,0); for(i=1;i<=regstatus.no_of_members;i++) if (match(reg[i].name,s)) { int_to_bin(tmp,i); cnt++; show_brief(stdout,i,tmp); } hdr_line(stdout,0); printf("\nNumber of matching names: %d\n",cnt); return; } void adjust(s) /* names in POSTGIRO can't be more than 29 chars! */ char *s; { int n=0; while (*s) { n++; s++; if (n==29) { *s='\0'; return; } } } void postgiro(s,n) /* write POSTGIRO */ char *s; int n; { line tmp; fprintf(regstatus.pg," 88 56 69 - 2 88 56 69 - 2\n"); fprintf(regstatus.pg,"\n Medlemsavgift f|r tolv m}nader\n"); fprintf(regstatus.pg," ( vid felaktiga uppgifter, Datorf|reningen\n"); fprintf(regstatus.pg," tag ny blankett! ) Lysator vid LiTH\n"); fprintf(regstatus.pg,"\n\n%s%s\n",*s?" Medlemsnr: ":"",s); str_copy(tmp,reg[n].name); adjust(tmp); fprintf(regstatus.pg," Namn: %-30s %s\n",tmp,*s?tmp:"Namn:"); str_copy(tmp,reg[n].adr[0]); adjust(tmp); fprintf(regstatus.pg," Adr: %-30s %s\n",tmp,*s?tmp:"Adr:"); str_copy(tmp,reg[n].adr[1]); adjust(tmp); fprintf(regstatus.pg," %-30s %s\n",tmp,tmp); str_copy(tmp,reg[n].tel); adjust(tmp); fprintf(regstatus.pg," Tel: %s\n",tmp); str_copy(tmp,reg[n].email); adjust(tmp); fprintf(regstatus.pg," Email: %s\n",tmp); fprintf(regstatus.pg,"\n"); fprintf(regstatus.pg,"%30s%3d -- %11s%3d --\n","",regstatus.memberfee,"",regstatus.memberfee); fprintf(regstatus.pg,"\n\n\n\n\n\n\n\n\n"); } /* ***** main routines ***** */ void init_reg() /* initiate the register from regstatus.df_filename */ { int i; long int c; struct tm *tp,*localtime(); regstatus.no_of_members=0; regstatus.date=0; regstatus.memberfee=MEMBERFEE; regstatus.sorted=0; regstatus.operator=0; if ( (access(regstatus.df_filename,R_OK)==0) && (access(regstatus.df_filename,W_OK)==0) ) regstatus.operator=1; time(&c); tp=localtime(&c); tp->tm_mon++; regstatus.date= 10000*(tp->tm_year) + 100*(tp->tm_mon) + (tp->tm_mday); for(i=0;i<=MEMBERS;i++) clear_record(i); regstatus.df=fopen(regstatus.df_filename,"r"); if (regstatus.df==(FILE *)NULL) { printf("***ERROR: cannot open the datafile '%s'!\n",regstatus.df_filename); return; } while (!get_record()) newrecord(++regstatus.no_of_members); fclose(regstatus.df); status(); } void newreg() /* save this register in regstatus.df_filename */ { int i; regstatus.df=fopen(regstatus.df_filename,"w"); if (regstatus.df==(FILE *)NULL) { printf("***ERROR: cannot update the datafile '%s'!\n",regstatus.df_filename); return; } for(i=1;i<=regstatus.no_of_members;i++) { fprintf(regstatus.df,"%s\n",reg[i].name); fprintf(regstatus.df,"%s\n",reg[i].adr[0]); fprintf(regstatus.df,"%s\n",reg[i].adr[1]); fprintf(regstatus.df,"%s\n",reg[i].tel); fprintf(regstatus.df,"%s\n",reg[i].email); fprintf(regstatus.df,"%d\n",reg[i].active); fprintf(regstatus.df,"%d\n",reg[i].expdate); fprintf(regstatus.df,"%s\n",reg[i].remark); } fclose(regstatus.df); printf("\nDatafile has been updated.\n"); } void payment() /* menu alternative 1 */ { int i,rfile,brief,pgiro,future,indirect,i_save,mail; char buf[BUFSIZ]; line tmp; char x_mailbuf[2*BUFSIZ]; int firstday, lastday, exptime; future=regstatus.date+150; /* 1.5 month ahead! */ i=(future%10000)/100; /* cryptic? simply including next month in expdate! */ if (i==13) future+=8800; /* date == YYMMDD == YY*10000 + MM*100 + DD */ printf("\n\nReport on file '%s'? (y/n) (n) ",REPORTFILE); get_line(stdin,tmp); rfile=(*tmp=='y' || *tmp=='Y'); if (rfile) printf("Print report on file '%s'\n",REPORTFILE); printf("\nShow only a brief listing? (y/n) (y) "); get_line(stdin,tmp); brief=(*tmp!='n' && *tmp!='N'); if (!brief) printf("Show verbose listing\n"); printf("\nReport on POSTGIRO-file '%s'? (y/n) (n) ",POSTGIROFILE); get_line(stdin,tmp); pgiro=(*tmp=='y' || *tmp=='Y'); if (pgiro) printf("Print report to POSTGIRO-file '%s'\n",POSTGIROFILE); mail=0; if (regstatus.operator) { /* not available to everyone... */ printf("\nSend mail to remind? (using file '%s')? (y/n) (n) ", MAILFILE); get_line(stdin,tmp); mail=(*tmp=='y' || *tmp=='Y'); if (mail) printf("Send mail to remind using file '%s'\n",MAILFILE); } printf("\nSort output in name-order? (y/n) (n) "); get_line(stdin,tmp); indirect=(*tmp=='Y' || *tmp=='y'); if (indirect) { printf("Sort in name-order:"); fflush(stdout); /* This line added by ceder 1991-11-04. */ if (!regstatus.sorted) do_sort(); printf(" ok.\n"); } printf("\nMake selections on expdate? (y/n) (n) "); get_line(stdin,tmp); exptime=(*tmp=='y' || *tmp=='Y'); if (exptime) { firstday = lastday = (-1); /* no restriction */ printf("First day (yymmdd) (RETURN for no selection) : "); get_line(stdin,tmp); if (*tmp) { if (ascii_to_int(&tmp[0],&firstday)) { firstday = (-1); printf("***ERROR: illegal date entered: %s\n",tmp); } } printf("Last day (yymmdd) (RETURN for no selection) : "); get_line(stdin,tmp); if (*tmp) { if (ascii_to_int(&tmp[0],&lastday)) { lastday = (-1); printf("***ERROR: illegal date entered: %s\n",tmp); } } } if (pgiro) { regstatus.pg=fopen(POSTGIROFILE,"a"); if (regstatus.pg==(FILE *)NULL) { printf("***ERROR: cannot append to postgirofile "); printf("'%s'!\n",POSTGIROFILE); return; } } if (rfile) { regstatus.rf=fopen(REPORTFILE,"a"); if (regstatus.rf==(FILE *)NULL) { printf("***ERROR: cannot append to reportfile "); printf("'%s'!\n",REPORTFILE); return; } if (brief) hdr_brief(regstatus.rf,"Check on payments",1,1); else hdr_verbose(regstatus.rf,"Check on payments"); } if (brief) hdr_brief(stdout,"Check on payments",1,1); else hdr_verbose(stdout,"Check on payments"); for(i=2;i<=regstatus.no_of_members;i++) { /* never charge #1 == TJH */ i_save=i; if (indirect) i=reg[i].index; if (exptime) { if (firstday >= 0) { if (reg[i].expdate < firstday) { i = i_save; continue; } } if (lastday >= 0) { if (reg[i].expdate > lastday) { i = i_save; continue; } } } if (!reg[i].active) { i=i_save; continue; } if (!exptime && !(reg[i].expdate <= future)) { i=i_save; continue; } int_to_bin(tmp,i); if (pgiro) postgiro(tmp,i); if (brief) { pay_brief(stdout,i,tmp); if (rfile) pay_brief(regstatus.rf,i,tmp); } else { show_verbose(stdout,i,tmp); if (rfile) show_verbose(regstatus.rf,i,tmp); } if (mail) { if (reg[i].email[0]=='\0') { printf("***ERROR: Member without email: '%s'\n",reg[i].name); } else { sprintf(x_mailbuf,"mail %s < %s",reg[i].email,MAILFILE); if (system(x_mailbuf)!=0) { printf("***ERROR: error executing mail!\n"); } sleep(2); /* Don't raise the load too much... */ } } i=i_save; } if (pgiro) fclose(regstatus.pg); if (rfile) { hdr_line(regstatus.rf,brief); fprintf(regstatus.rf,"\f\n"); fclose(regstatus.rf); } hdr_line(stdout,brief); printf("\n\nPress RETURN to continue "); get_line(stdin,tmp); } void edit_members() /* menu alternative 2 */ { line tmp; int no,i; printf("\nInstructions to edit members\n\n"); printf("- Always press RETURN to accept default values\n"); printf("- In 'Member#'-field, press RETURN to register new member,\n"); printf(" 'bbb' or '#ddd' to enter other member#, '?' to do a name-\n"); printf(" match on the members in the register, 'E' or 'Q' to exit."); while (1) { printf("\n\nEdit members, date=%d\n\n",regstatus.date); no=regstatus.no_of_members+1; int_to_bin(tmp,no); printf("Member# : %s (#%d)\n",tmp,no); printf("Member# : "); get_line(stdin,tmp); if ((*tmp=='E'||*tmp=='e'||*tmp=='Q'||*tmp=='q')&&!tmp[1]) return; if (*tmp=='?') { printf("\nName-matching: "); get_line(stdin,tmp); if (*tmp) match_name(tmp); continue; } if (*tmp == '#') { /* decimal no */ if (ascii_to_int(&tmp[1],&no)) { printf("***ERROR: illegal number entered: %s\n",tmp); return; } } else if (*tmp) { /* binary no */ if (bin_to_int(tmp,&no)) { printf("***ERROR: illegal number entered: %s\n",tmp); return; } } if (no>MEMBERS) { printf("***ERROR: member# too large!\n"); return; } if (no<1) { printf("***ERROR: member# too small!\n"); return; } if (reg[no].name[0]!=(char)NULL) { printf("\nThis is an existing member\n\n"); int_to_bin(tmp,no); printf("Member# : %s (#%d)\n",tmp,no); printf("Name : %s\n",reg[no].name); printf("Address : %s\n",reg[no].adr[0]); printf("Address : %s\n",reg[no].adr[1]); printf("Tel : %s\n",reg[no].tel); printf("Email : %s\n",reg[no].email); printf("Remark : %s\n",reg[no].remark); printf("Active : %d (0=inactive,1=active)\n",reg[no].active); printf("Expdate : %d\n\n",reg[no].expdate); printf("\nEdit this member? (y=yes) "); get_line(stdin,tmp); if ((*tmp!='y') && (*tmp!='Y')) continue; } else printf("\nThis is a new member.\n\n"); printf("Name : "); str_copy(reg[0].name,reg[no].name); get_line(stdin,tmp); if (*tmp) str_copy(reg[0].name,tmp); printf("Address : "); str_copy(reg[0].adr[0],reg[no].adr[0]); get_line(stdin,tmp); if (*tmp) str_copy(reg[0].adr[0],tmp); printf("Address : "); str_copy(reg[0].adr[1],reg[no].adr[1]); get_line(stdin,tmp); if (*tmp) str_copy(reg[0].adr[1],tmp); printf("Tel : "); str_copy(reg[0].tel,reg[no].tel); get_line(stdin,tmp); if (*tmp) str_copy(reg[0].tel,tmp); printf("Email : "); str_copy(reg[0].email,reg[no].email); get_line(stdin,tmp); if (*tmp) str_copy(reg[0].email,tmp); printf("Remark : "); str_copy(reg[0].remark,reg[no].remark); get_line(stdin,tmp); if (*tmp) str_copy(reg[0].remark,tmp); printf("Active : "); reg[0].active=reg[no].active; get_line(stdin,tmp); if (*tmp) { if (ascii_to_int(tmp,&i)) printf("***ERROR: wrong input!\n"); else if ((i<0)||(i>1)) printf("***ERROR: wrong input!\n"); else reg[0].active=i; } printf("Expdate : "); reg[0].expdate=reg[no].expdate; get_line(stdin,tmp); if (*tmp) { if (ascii_to_int(tmp,&i)) printf("***ERROR: wrong input!\n"); else if (i<0) printf("***ERROR: wrong input!\n"); else reg[0].expdate=i; } printf("\nVerification of input\n\n"); int_to_bin(tmp,no); printf("Member# : %s (#%d)\n",tmp,no); printf("Name : %s\n",reg[0].name); printf("Adr : %s\n",reg[0].adr[0]); printf("Adr : %s\n",reg[0].adr[1]); printf("Tel : %s\n",reg[0].tel); printf("Email : %s\n",reg[0].email); printf("Remark : %s\n",reg[0].remark); printf("Active : %d (0=inactive,1=active)\n",reg[0].active); printf("Expdate : %d\n",reg[0].expdate); printf("\nSave in register? (y/n) (y) "); get_line(stdin,tmp); if ((*tmp!='n') && (*tmp!='N')) newrecord(no); } } void report() /* menu alternative 3 */ { int i,brief,rfile,inactive,j,indirect,i_save; line tmp,name_match; printf("\n\nReport on file '%s'? (y/n) (n) ",REPORTFILE); get_line(stdin,tmp); rfile=(*tmp=='y' || *tmp=='Y'); if (rfile) printf("Print report on file '%s'\n",REPORTFILE); printf("\nShow only a brief listing? (y/n) (y) "); get_line(stdin,tmp); brief=(*tmp!='n' && *tmp!='N'); if (!brief) printf("Show verbose listing\n"); printf("\nShow inactive members also? (y/n) (n) "); get_line(stdin,tmp); inactive=(*tmp=='y' || *tmp=='Y'); if (inactive) printf("Show inactive members\n"); printf("\nName-matching (press RETURN for no matching) : "); get_line(stdin,name_match); if (*name_match) printf("Show only members whose names match '%s'\n",name_match); printf("\nSort output in name-order? (y/n) (n) "); get_line(stdin,tmp); indirect=(*tmp=='Y' || *tmp=='y'); if (indirect) { printf("Sort in name-order:"); if (!regstatus.sorted) do_sort(); printf(" ok.\n"); } if (rfile) { regstatus.rf=fopen(REPORTFILE,"a"); if (regstatus.rf==(FILE *)NULL) { printf("***ERROR: cannot append to reportfile "); printf("'%s'!\n",REPORTFILE); return; } if (brief) hdr_brief(regstatus.rf,"Report on members in Lysator",0,0); else hdr_verbose(regstatus.rf,"Report on members in Lysator"); } if (brief) hdr_brief(stdout,"Report on members in Lysator",0,0); else hdr_verbose(stdout,"Report on members in Lysator"); for(i=1;i<=regstatus.no_of_members;i++) { i_save=i; if (indirect) i=reg[i].index; j=1; if (!inactive && !reg[i].active) j--; if (j && *name_match && !match(reg[i].name,name_match)) j--; if (j) { int_to_bin(tmp,i); if (brief) { show_brief(stdout,i,tmp); if (rfile) show_brief(regstatus.rf,i,tmp); } else { show_verbose(stdout,i,tmp); if (rfile) show_verbose(regstatus.rf,i,tmp); } } i=i_save; } hdr_line(stdout,0); if (rfile) { hdr_line(regstatus.rf,0); fprintf(regstatus.rf,"\f\n"); fclose(regstatus.rf); } printf("\n\nPress RETURN to continue "); get_line(stdin,tmp); } void pg_blanks() /* menu alternative 4 */ { int i; regstatus.pg=fopen(POSTGIROFILE,"a"); if (regstatus.pg==(FILE *)NULL) { printf("***ERROR: cannot create postgirofile "); printf("'%s'!\n",POSTGIROFILE); return; } clear_record(0); for(i=0;i<12;i++) postgiro("",0); fclose(regstatus.pg); } void change_fee() { line tmp; int i; printf("\n\nOld memberfee: %d, please enter new (RETURN to keep old) ",regstatus.memberfee); get_line(stdin,tmp); if (*tmp) { if (ascii_to_int(tmp,&i)) printf("***ERROR: wrong input!\n"); else if (i<0) printf("***ERROR: wrong input!\n"); else regstatus.memberfee=i; } printf("\nNew memberfee: %d\n\n",regstatus.memberfee); } void menu() /* guess what? */ { line tmp; while (1) { printf("\n\nMembers in Lysator (%s), date=%d,",VERSION,regstatus.date); printf(" %d members\n\n",regstatus.no_of_members); printf("0. Register status\n"); printf("1. Check payment of members\n"); printf("2. Edit Members\n"); printf("3. Report on members\n"); printf("4. Postgiro - print a dozen blanks\n"); printf("5. Change memberfee\n"); if (regstatus.operator) printf("6. Exit and update datafile\n"); printf("7. Exit immediately\n"); printf("\n\nChoice (0-7) "); get_line(stdin,tmp); if (*tmp=='0') status(); if (*tmp=='1') payment(); if (*tmp=='2') edit_members(); if (*tmp=='3') report(); if (*tmp=='4') pg_blanks(); if (*tmp=='5') change_fee(); if (regstatus.operator) { if (*tmp=='6') break; } if (*tmp=='7') exit(0); } status(); } void main(argc,argv) int argc; char **argv; { sprintf(regstatus.df_filename,DATAFILE); if (argc==2) sprintf(regstatus.df_filename,argv[1]); if (argc>2) { fprintf(stderr,"usage: %s [file]\n",argv[0]); exit(1); } init_reg(); menu(); if (regstatus.operator) newreg(); }