|
|
1.1 root 1: #include <stdio.h>
2: #include <curses.h>
3: #include "contents.h"
4:
5:
6:
7: main(argc, argv)
8: int argc;
9: char *argv[];
10: {
11:
12: int x;
13:
14:
15: if(argc < 2)
16: {
17: printf("Usage: mwcbbs [adr] filename\n");
18: printf("[a] add\n[d] download\n[r] remove\n");
19: exit(1);
20: }
21:
22:
23: if(argv[1][0] != 'a')
24: if(argv[1][0] != 'd')
25: if(argv[1][0] != 'r')
26: {
27: printf("Option %c not recognized!\n",argv[1][0]);
28: exit(1);
29: }
30:
31: initscr();
32: raw();
33:
34: open_mode = argv[1][0];
35:
36: screen_num = 0;
37:
38: do {
39: getfilename();
40:
41: /* if we did NOT select the mail option, then read the indicated
42: * Content file.
43: */
44:
45: if (strcmp(workfile,"QUIT")==0)
46: break;
47:
48: if (strcmp(workfile,FILE4)!=0)
49: x = rfile();
50: if ((open_mode == 'a') && (strcmp(workfile,MAILFILE) == 0))
51: x = rfile();
52: if ((open_mode == 'r') && (strcmp(workfile,MAILFILE) == 0))
53: x = rfile();
54:
55: show_files(x);
56:
57: }
58: while( strcmp(workfile,FILE6) != 0);
59:
60: echo();
61: noraw();
62: endwin();
63:
64: }
65:
66:
67:
68:
69: /* show_files()
70: * This function will display the filenames read to a curses
71: * screen.
72: */
73:
74:
75: void show_files(EOF_FLAG)
76: int EOF_FLAG;
77:
78: {
79: char arrow;
80: int prevcol =1;
81: int prevrow =0; /* prevcol = column before arrow */
82: int newrow =0; /* prevrow = row before arrow */
83: int newcol =1; /* newrow = row after arrow */
84: int counter = 0; /* newcol = column after arrow */
85:
86:
87: WINDOW *win1, *win2;
88:
89:
90:
91: /* if QUIT was selected from the main menu, exit this function */
92:
93: if (strcmp(workfile,FILE6)==0)
94: return;
95:
96:
97: noecho();
98:
99: /* allocate memory for window. print message on failure. */
100:
101: if((win1=newwin(20, 79, 0,0)) == NULL)
102: {
103: printf("\007Window Memroy allocation for win1 failed!\n");
104: exit(1);
105: }
106:
107: if((win2=newwin(20, 79, 0,0)) == NULL)
108: {
109: printf("\007Window Memroy allocation for win2 failed!\n");
110: exit(1);
111: }
112:
113:
114: /* if the mail option was selected, print the states to the window,
115: * else print the filenames from the read Contents file to the window.
116: */
117:
118: /* if we are in add/remove mode, then we want to print mail accounts
119: * by SITE to the workscreen, NOT the list of states.
120: */
121:
122: if ( (strcmp(workfile,FILE4) == 0) && (open_mode == 'd'))
123: print_states(win1);
124: else
125: write_win(win1);
126:
127: menu();
128:
129:
130: /* highlite a filename. This is accomplished by going to a designated
131: * row and column, as determined by the row and counter nested loops.
132: * The innermost loop gets the character found, copies the retrieved
133: * character into a string and deletes the character from the screen.
134: * When the filename has been deleted from the screen, it is reprinted
135: * to the screen with highliting turned on. Padding for spaces must be
136: * accounted for since deleting chars shifts everything on the line one
137: * space to the left.
138: */
139:
140: /* print the first file in inverse video */
141:
142: lite (win1, prevrow, prevcol, 1,0);
143:
144: do
145: {
146:
147: /* now we need to get a key (preferably an arrow) */
148:
149:
150:
151: arrow = getch(); /* This stupid code should allow to use arrows keys */
152: if (arrow == 27) /* that looks more frendly than hjkl. Vlad 8/15/91 */
153: {
154: getch();
155: arrow = getch(); /* When an arrow key is pressed, an escape */
156: if (arrow == 68) /* sequence is returned. The value '27' */
157: arrow = 'h'; /* begins the sequence and the relevant */
158: if (arrow == 67) /* values needed end the sequence. The */
159: arrow = 'l'; /* middle value is not needed, so it is */
160: if (arrow == 66) /* skipped over with a getch() statement */
161: arrow = 'j';
162: if (arrow == 65)
163: arrow = 'k';
164: }
165:
166:
167: /* each movement case in the following switch...case will test to see if the
168: * new position returns a space. If a space is returned, then we will hit
169: * an empty field, which we don't want to do. If we hit an empty space,
170: * then don't move the cursor.
171: */
172:
173: switch(arrow)
174: {
175: case 'h': /* move left */
176: newcol = prevcol - 15;
177: if (newcol < 1)
178: newcol = 61;
179: if (' ' == mvwinch(win1,newrow,newcol))
180: newcol = 1;
181: break;
182:
183:
184: case 'l': /* move right */
185: newcol = prevcol + 15;
186: if (newcol > 61)
187: newcol = 1;
188: if (' ' == mvwinch(win1,newrow,newcol))
189: newcol = 1;
190: break;
191:
192:
193: case 'j': /* move down */
194: newrow = prevrow + 1;
195: if (newrow == 20)
196: newrow = 0;
197: if (' ' == mvwinch(win1,newrow,newcol))
198: newrow = 0;
199: break;
200:
201:
202: case 'k': /* move up */
203: newrow = prevrow -1;
204: if (newrow == -1)
205: newrow = 19;
206: if (' ' == mvwinch(win1,newrow,newcol))
207: newrow = 0;
208: break;
209:
210:
211: case 'p':
212: screen_num --;
213: newrow = 0;
214: newcol = 1;
215: if (screen_num < 0)
216: screen_num = 0;
217: else
218: {
219: EOF_FLAG = rfile();
220: write_win(win1);
221: }
222: break;
223:
224:
225: case 'n':
226: newrow = 0;
227: newcol = 1;
228: if (EOF_FLAG == -1)
229: break;
230: else
231: {
232: screen_num ++;
233: EOF_FLAG = rfile();
234: write_win(win1);
235: }
236: break;
237:
238: /* when we 'quit', we need to make sure that the screen number
239: * is set to 0 so that when the next file is selected, we begin
240: * at the start of the file. If not, we run the risk of reading
241: * something and causing a dump, or worse, system corruption.
242: */
243:
244: case 'Q':
245: case 'q':
246: screen_num = 0;
247: delwin(win1);
248: delwin(win2);
249: break;
250:
251: case 13:
252: case 'S':
253: case 's':
254: wclear(win1);
255: wrefresh(win1);
256: wclear(win2);
257:
258: if((strcmp(workfile,mapfile[0])==0) || (strcmp(workfile,mapfile[1])==0) || (strcmp(workfile,mapfile[2])==0))
259: {
260: map_command(win2,prevrow,prevcol,screen_num);
261: wclear(win1);
262: rfile();
263: write_win(win1);
264: wrefresh(win1);
265: break;
266: }
267:
268: if( strcmp(workfile,MAILFILE) == 0)
269: {
270: if (open_mode == 'd')
271: {
272: print_mail_states(win2);
273: wclear(win2);
274: wrefresh(win2);
275: refresh();
276: wrefresh(win1);
277: wclear(win1);
278: print_states(win1);
279: wrefresh(win1);
280: break;
281: }
282: if ((open_mode == 'a') || (open_mode == 'r'))
283: {
284: add_mail(win2,prevrow,prevcol,screen_num);
285: wclear(win2);
286: wmove(win2,0,1);
287: waddstr(win2,"Reading file. Please wait...");
288: wrefresh(win2);
289: rfile();
290: write_win(win1);
291: wrefresh(win1);
292: break;
293: }
294: }
295:
296:
297: /* if we're not working on a mailfile record, display the Contents
298: * form.
299: */
300: if(strcmp(workfile,MAILFILE)!=0)
301: {
302: if (open_mode == 'r')
303: {
304: display_form(win2);
305: display_record(win2,prevrow,prevcol,screen_num);
306: wclear(win2);
307: wmove(win2,0,0);
308: waddstr(win2,"Reading file... please wait");
309: wrefresh(win2);
310: rfile();
311: }
312: if (open_mode == 'a')
313: {
314: display_form(win2);
315: add_rec(win2,prevrow,prevcol,screen_num);
316: wclear(win2);
317: wmove(win2,0,0);
318: waddstr(win2,"Reading file... please wait");
319: wrefresh(win2);
320: rfile();
321: }
322: else
323: {
324: display_form(win2);
325: display_record(win2,prevrow,prevcol,screen_num);
326: }
327: write_win(win1);
328: wclear(win2);
329: wrefresh(win2);
330: menu();
331: refresh();
332: wrefresh(win1);
333: break;
334: }
335:
336: default:
337: newcol = prevcol;
338: newrow = prevrow;
339: break;
340:
341: }
342:
343: /* print previous file highlited in normal video */
344: lite (win1, prevrow, prevcol, 0,0);
345:
346: /* print new filename selection in inverse video */
347:
348: lite (win1, newrow, newcol, 1,0);
349:
350: /* set our previous coordinates so that we can go back
351: * and unlite a field when the next directin is given.
352: */
353:
354: prevrow = newrow;
355: prevcol = newcol;
356:
357:
358: }
359: while (arrow != 'q');
360:
361: echo();
362:
363: }
364:
365:
366:
367:
368: int rfile()
369:
370: {
371:
372: struct mail mailrec;
373: FILE *infp;
374: int EOF_FLAG;
375:
376:
377: /* if the selected file is QUIT, exit this function */
378:
379: if( strcmp(workfile,"QUIT") == 0 )
380: return;
381:
382: /* open file, abort on error */
383:
384: if ((infp = fopen(workfile,"r")) == NULL)
385: {
386: printf("\007ERROR opening file %s for input!\n", workfile);
387: exit(1);
388: }
389:
390: /* open a file then go to a an offset calculated by a
391: * value passed from the calling program. Once we hit
392: * the max number of records that can be held by a screen,
393: * terminate the read and set a flag to show that we did
394: * not hit EOF. If we did hit EOF, terminate the loop
395: * and set a flag to show that we did hit EOF.
396: */
397:
398: /* start reading from a specified point in the file */
399:
400: if((strcmp(workfile,mapfile[0])==0) || (strcmp(workfile,mapfile[1])==0) || (strcmp(workfile,mapfile[2])==0))
401: fseek(infp,(sizeof (struct map) * (screen_num * 100)),0l);
402: else
403: {
404: if(strcmp(workfile,MAILFILE)==0)
405: fseek(infp, (sizeof (struct mail) * (screen_num * 100)), 0l);
406: else
407: fseek(infp, (sizeof (struct entry) * (screen_num * 100)), 0l);
408: }
409:
410: limit = 0;
411:
412:
413: if((strcmp(workfile,mapfile[0])==0) || (strcmp(workfile,mapfile[1])==0) || (strcmp(workfile,mapfile[2])==0))
414: {
415: while((fread(&map_rec,sizeof(struct map),1,infp)) != 0)
416: {
417: strcpy(filenames[limit], map_rec.name);
418: place[limit] = limit;
419: limit ++;
420: if (limit == 100)
421: break;
422: }
423: }
424: else
425: {
426: if(strcmp(workfile,MAILFILE)==0)
427: {
428: while((fread(&mailrec,sizeof(struct mail),1,infp)) != 0)
429: {
430: strcpy(filenames[limit], mailrec.site);
431: place[limit] = limit;
432: limit ++;
433: if (limit == 100)
434: break;
435: }
436: }
437:
438: else
439: {
440: while((fread(&record, sizeof(struct entry),1, infp)) != 0)
441: {
442: strcpy(filenames[limit], record.filename);
443: place[limit] = limit;
444: limit++;
445: if (limit == 100)
446: break;
447: }
448: }
449: }
450:
451:
452: /* if x made it to 100, then we did NOT hit EOF */
453:
454: if((strcmp(workfile,mapfile[0])==0) || (strcmp(workfile,mapfile[1])==0) || (strcmp(workfile,mapfile[2])==0))
455: {
456: if ( (limit == 100) && (fread (&map_rec,sizeof(struct map),1,infp)) != 0)
457: EOF_FLAG = 0;
458: else
459: EOF_FLAG = -1;
460: }
461: else
462: {
463: if(strcmp(workfile,MAILFILE)==0)
464: {
465: if ( (limit == 100) && (fread (&mailrec,sizeof(struct mail),1,infp)) != 0)
466: EOF_FLAG = 0;
467: else
468: EOF_FLAG = -1;
469: }
470: else
471: {
472: if ( (limit == 100) && (fread (&record,sizeof(struct entry),1,infp)) != 0)
473: EOF_FLAG = 0;
474: else
475: EOF_FLAG = -1;
476: }
477: }
478: fclose(infp);
479: return (EOF_FLAG);
480:
481: }
482:
483:
484:
485: /*
486: * writewin();
487: * this routine does the actual work of writing filenames to a window
488: */
489:
490: void write_win(win1)
491:
492: WINDOW *win1;
493:
494: {
495:
496: int r,c; /* these are our rows and columns */
497: int counter = 0; /* this counts the number of files written */
498:
499:
500:
501: /* clear the window */
502: wclear(win1);
503: wrefresh(win1);
504:
505: /* the following loop will write the filenames to the window.
506: * 15 characters per screen field are allowed, since a filename
507: * can only be 14 chars in length. This will leave at least one
508: * space between filenames.
509: */
510:
511: for (r = 0; r < 20; r++)
512: {
513:
514: /* if we've run out of files, terminate loop */
515:
516: if (counter == limit)
517: break;
518:
519: /* increment column by 15 positions. This
520: * will cause the filenames to line up
521: * on the window.
522: */
523:
524: for (c = 1; c < 75; c+= 15)
525: {
526: wmove(win1, r, c);
527: waddstr(win1, filenames[counter]);
528:
529: /* increment counter. When it equals the number of
530: * records, passed as 'limit', the loop should
531: * terminate.
532: */
533:
534: counter ++;
535: if (counter == limit)
536: break;
537: }
538: }
539:
540:
541: }
542:
543: /* this function will draw a template for the selected record */
544:
545: void display_form(win2)
546: WINDOW *win2;
547:
548:
549: {
550: int x;
551:
552: clear();
553: wclear(win2);
554:
555: /* print field labels */
556:
557: wmove (win2, NAMELOCATE );
558: waddstr (win2,"Filename:");
559:
560: wmove (win2, DESCLOCATE);
561: waddstr(win2,"Description:");
562:
563: wmove(win2, DATELOCATE );
564: waddstr(win2,"Date added/modified:");
565:
566: wmove(win2, SIZELOCATE);
567: waddstr(win2,"File size:");
568:
569: if(open_mode != 'd')
570: {
571: wmove(win2, PARTLOCATE);;
572: waddstr(win2,"Number of parts to download:");
573: }
574:
575: wmove(win2, REQLOCATE );
576: waddstr(win2,"Requires these other files:");
577:
578: wmove(win2, NOTELOCATE);
579: waddstr(win2,"Other notes:");
580:
581: if(open_mode != 'd')
582: {
583: wmove(win2, PATHLOCATE);
584: waddstr(win2, "Path to download file... Must give complete path including filename.");
585: wmove (win2, PATHLOCATE2);
586: waddstr(win2,"If a file is split into several parts, enter the first filename part");
587: wmove (win2, PATHLOCATE3);
588: waddstr(win2,"leaving the LAST character off of the filename:");
589: }
590:
591:
592: /* highlite available fields */
593:
594: wstandout(win2);
595:
596: wmove (win2, NAMEHI);
597: waddstr(win2," ");
598:
599: wmove (win2,DESCHI);
600: for (x=1;x<79;x++)
601: waddstr(win2," ");
602:
603: wmove(win2, DATEHI);
604: waddstr(win2," ");
605:
606: wmove(win2, SIZEHI);
607: waddstr(win2," ");
608:
609: if (open_mode != 'd')
610: {
611: wmove(win2,PARTHI);
612: waddstr(win2," ");
613: }
614:
615: wmove (win2,REQHI);
616: for (x=1;x<61;x++)
617: waddstr(win2," ");
618:
619: wmove (win2,NOTEHI);
620: for (x=1;x<69;x++)
621: waddstr(win2," ");
622:
623: if(open_mode != 'd')
624: {
625: wmove (win2, PATHHI);
626: waddstr(win2,PATHNAME);
627: for (x=23;x<61;x++)
628: waddstr(win2," ");
629: }
630:
631: wstandend(win2);
632: refresh();
633: wrefresh(win2);
634:
635:
636:
637: }
638:
639: /* following function prints the menu at the bottom of stdscr */
640:
641: void menu()
642:
643: {
644: /* print a menu of options to stdscr. They will appear at the bottom of
645: * the screen with the first letter highlited as an indication to
646: * the user that pressing the highlited key will result in the indicated
647: * action.
648: */
649:
650: if(open_mode =='r')
651: {
652: move (21,0);
653: printw("Select file to delete");
654: refresh();
655: }
656:
657: if(open_mode == 'a')
658: {
659: move (21,0);
660: printw("select file that will FOLLOW");
661: move (22,0);
662: printw("the file to be added.");
663: refresh();
664: }
665:
666: if(open_mode == 'd')
667: {
668: move (21,0);
669: if(strcmp(workfile,MAILFILE)==0)
670: printw("Select state/other to view.");
671: else
672: printw("Select file to download. ");
673: refresh();
674: }
675:
676: move(21, 50);
677: standout();
678: printw("Options:");
679: move(22,46);
680: printw("n");
681: move(23,46);
682: printw("p");
683: move(22,60);
684: printw("q");
685: move(23,60);
686: printw("s");
687: standend();
688: move(22,47);
689: addstr("ext page");
690: move(23,47);
691: addstr("rev. page");
692: move(22,61);
693: addstr("uit");
694: move(23,61);
695: addstr("elect file");
696:
697:
698: }
699:
700:
701: void del_rec(win3,row,col,screen_num)
702: WINDOW *win3;
703: int row,col,screen_num;
704:
705: {
706: int x;
707: FILE *infp,*outfp;
708: int rec_mark = POS_FORMULA;
709:
710: if ( (infp=fopen(workfile,"r"))==NULL)
711: {
712: printf("Error opening file %s for input!\n",workfile);
713: exit(1);
714: }
715:
716: /* delete any previous temporary file that may be here */
717:
718: if (unlink(TEMPFILE)==-1);
719:
720: if ( (outfp=fopen(TEMPFILE,"a"))==NULL)
721: {
722: printf("Error opening \"mwcbbs.tmp\" for output!\n");
723: exit(1);
724: }
725:
726:
727: /* we will now read each record until we hit the record number
728: * calculated by rec_mark. to delete, we will simply exit the
729: * loop when we hit the correct record, skip the record with a
730: * read, then follow that with another read/write loop to finish
731: * off the file.
732: */
733:
734:
735: for(x=0;x<rec_mark;x++)
736: {
737: if(strcmp(workfile,MAILFILE)==0)
738: fread(&mail_rec, sizeof(struct mail),1,infp);
739: else
740: fread(&record, sizeof(struct entry),1,infp);
741: wmove(win3,1,0);
742: wprintw(win3,"Reading:");
743: wrefresh(win3);
744: if(strcmp(workfile,MAILFILE)==0)
745: fwrite(&mail_rec, sizeof(struct mail),1,outfp);
746: else
747: fwrite(&record, sizeof(struct entry),1,outfp);
748: wmove(win3,1,0);
749: wprintw(win3,"Writing:");
750: wrefresh(win3);
751: }
752:
753: /* this will delete the record by using a dummy record to skip it */
754:
755: if(open_mode == 'r')
756: if(strcmp(workfile,MAILFILE)==0)
757: fread(&mail_rec, sizeof(struct mail),1,infp);
758: else
759: fread(&record, sizeof(struct entry),1,infp);
760:
761:
762: /* this will write in a new record, if invoked in 'add' mode */
763: if(open_mode == 'a')
764: if(strcmp(workfile,MAILFILE)==0)
765: fwrite(&new_mail_rec, sizeof(struct mail),1,outfp);
766: else
767: fwrite(&new_record, sizeof(struct entry),1,outfp);
768:
769: /* this will finish off the file. */
770:
771: if(strcmp(workfile,MAILFILE)==0)
772: {
773: while((fread(&mail_rec, sizeof(struct mail),1,infp)) != 0)
774: {
775: wmove(win3,1,0);
776: wprintw(win3,"Reading");
777: wrefresh(win3);
778: fwrite(&mail_rec, sizeof(struct mail),1,outfp);
779: wmove(win3,1,0);
780: wprintw(win3,"Writing:");
781: wrefresh(win3);
782: }
783: }
784: else
785: {
786: while((fread(&record, sizeof(struct entry),1,infp)) != 0)
787: {
788: wmove(win3,1,0);
789: wprintw(win3,"Reading");
790: wrefresh(win3);
791: fwrite(&record, sizeof(struct entry),1,outfp);
792: wmove(win3,1,0);
793: wprintw(win3,"Writing:");
794: wrefresh(win3);
795: }
796: }
797:
798:
799: /* close the files and move around as appropriate (delete the old then
800: * move the new to old
801: */
802:
803: fclose(infp);
804: fclose(outfp);
805: if(unlink(workfile) == -1)
806: {
807: endwin();
808: printf("Could not remove old file!\n");
809: printf("Updated file could be found as %s\n",TEMPFILE);
810: exit(1);
811: }
812:
813: if( link(TEMPFILE,workfile) == -1)
814: {
815: endwin();
816: printf("Could not link new file!\n");
817: exit(1);
818: }
819:
820: if( unlink(TEMPFILE) == -1)
821: {
822: endwin();
823: printf("Could not remove temporary file!\n");
824: exit(1);
825: }
826:
827: }
828:
829: /* this function will take the pathname and append the necessary
830: * character(s) to generate the multiple requests necessary to
831: * download multipart files.
832: */
833:
834: void build_uucp(record)
835:
836:
837: {
838: int x,y;
839:
840: y = strlen(record.pathname);
841:
842: for(x=0;x< record.noparts;x++)
843: {
844: strcpy(getfiles[x],HOST);
845: record.pathname[y] = 97 + x;
846: strcat(getfiles[x],record.pathname);
847: strcat(getfiles[x],RECEIVER);
848: }
849: }
850:
851:
852:
853:
854:
855:
856:
857:
858:
859:
860:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.