|
|
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: ! 13: WINDOW *win1, *win2; ! 14: int x; ! 15: char dummy[50]; ! 16: ! 17: printflag = 0; ! 18: strcpy(recdir,RECEIVER); ! 19: if(argc > 3) ! 20: { ! 21: printf("Too many arguments!\n"); ! 22: exit(1); ! 23: } ! 24: ! 25: /* parse the command line argument for a 'p' or a 'P' so ! 26: * that we know to PRINT a file. If we hit a '?', then ! 27: * print a usage: message. ! 28: */ ! 29: ! 30: bbsdatafile(); /* read the .mwcbbs data file, if it exists */ ! 31: ! 32: if((argc==2)||(argc==3)) ! 33: { ! 34: for(x=0;x<strlen(argv[1]);x++) ! 35: { ! 36: ! 37: /* test for v */ if( argv[1][x] == 'v' ){ ! 38: printf("mwcbbs interface version %s\n", ! 39: VERSION); ! 40: exit(0); ! 41: } ! 42: /* test for pP */ if((argv[1][x] == 112) || (argv[1][x] == 80)) ! 43: break; ! 44: ! 45: /* test for dD */ if((argv[1][x] == 100) || (argv[1][x] == 68)) ! 46: { ! 47: strcpy(dummy,argv[2]); ! 48: if(argc < 3) ! 49: { ! 50: printf("No directory specified!\n"); ! 51: exit(1); ! 52: } ! 53: if (strlen(dummy) < 2) ! 54: { ! 55: printf("Invalid destination specified!\n"); ! 56: exit(1); ! 57: } ! 58: strcpy(recdir," "); ! 59: strcat(recdir,dummy); ! 60: break; ! 61: } ! 62: ! 63: if(argv[1][x] == '?') ! 64: { ! 65: printf("Usage:\tmwcbbs [options] directory\n"); ! 66: printf("\tOptions:\n"); ! 67: printf("\t -[Pp] print Contents files\n"); ! 68: printf("\t -[Dd] specify destination directory\n"); ! 69: printf("\t -[v] specify interface version\n"); ! 70: printf("\t -[?] usage message\n"); ! 71: exit(1); ! 72: } ! 73: } ! 74: } ! 75: ! 76: /* the following should only be executed if the above ! 77: * loop went all the way thru the argument passed, which means ! 78: * that we did not find a [pP]. ! 79: */ ! 80: ! 81: if ((argc==2) && (x==strlen(argv[1]))) ! 82: { ! 83: printf("Unknown option %s\n",argv[1]); ! 84: exit(1); ! 85: } ! 86: else ! 87: ! 88: /* we found that there is one argument and that it is [pP], ! 89: * so set a printflag. We should only set this flag if argc = 2. ! 90: * The if statement ensures that printflag will only be set ! 91: * if there was one argument passed. ! 92: */ ! 93: { ! 94: if(argc==2) ! 95: printflag = 1; ! 96: } ! 97: ! 98: initscr(); ! 99: raw(); ! 100: noecho(); ! 101: ! 102: /* allocate memory for windows. print message on failure. */ ! 103: ! 104: if((win1=newwin(20, 79, 0,0)) == NULL) ! 105: { ! 106: printf("\007Window Memroy allocation for win1 failed!\n"); ! 107: exit(1); ! 108: } ! 109: ! 110: if((win2=newwin(20, 79, 0,0)) == NULL) ! 111: { ! 112: printf("\007Window Memroy allocation for win2 failed!\n"); ! 113: exit(1); ! 114: } ! 115: ! 116: screen_num = 0; ! 117: ! 118: ! 119: /* now we get the user's choice of file to process */ ! 120: ! 121: do { ! 122: getfilename(); ! 123: ! 124: ! 125: /* if we're printing, call the print function. After ! 126: * completion, exit the program. We want to exit the ! 127: * because we don't want the user to automatically ! 128: * run the print function again and overwrite the ! 129: * data file written by the previous run-through. ! 130: */ ! 131: ! 132: ! 133: /* added 11/21/91: If 'quit' was selected from the ! 134: * menu, we don't want to run the print option. Beta ! 135: * version 3 would allow the print routine to be entered ! 136: * and would later exit with a 'cannot find QUIT' message. ! 137: */ ! 138: ! 139: if((printflag == 1) && (strcmp(workfile,"QUIT") != 0)) ! 140: { ! 141: print(win2); ! 142: strcpy(workfile,"QUIT"); ! 143: } ! 144: ! 145: /* if we did NOT select the mail option, then read the indicated ! 146: * Content file. ! 147: */ ! 148: ! 149: if (strcmp(workfile,"QUIT")==0) ! 150: break; ! 151: ! 152: if (strstr(workfile,MAILFILE) == NULL) ! 153: x = rfile(); ! 154: show_files(win1, win2, x); ! 155: ! 156: } ! 157: while( strcmp(workfile,FILE6) != 0); ! 158: ! 159: noraw(); ! 160: endwin(); ! 161: ! 162: } ! 163: ! 164: ! 165: ! 166: ! 167: /* show_files() ! 168: * This function will display the filenames read to a curses ! 169: * screen. ! 170: */ ! 171: ! 172: ! 173: void show_files(win1, win2, EOF_FLAG) ! 174: WINDOW *win1, *win2; ! 175: int EOF_FLAG; ! 176: ! 177: { ! 178: char arrow; ! 179: int prevcol =1; ! 180: int prevrow =0; /* prevcol = column before arrow */ ! 181: int newrow =0; /* prevrow = row before arrow */ ! 182: int newcol =1; /* newrow = row after arrow */ ! 183: int counter = 0; /* newcol = column after arrow */ ! 184: ! 185: ! 186: ! 187: ! 188: /* if the mail option was selected, print the states to the window, ! 189: * else print the filenames from the read Contents file to the window. ! 190: */ ! 191: ! 192: /* if we are in add/remove mode, then we want to print mail accounts ! 193: * by SITE to the workscreen, NOT the list of states. ! 194: */ ! 195: ! 196: if ( (strstr(workfile,FILE4) != NULL) ) ! 197: { ! 198: print_states(win1); ! 199: EOF_FLAG = -1; ! 200: } ! 201: ! 202: else ! 203: write_win(win1); ! 204: ! 205: menu(); ! 206: ! 207: ! 208: /* highlite a filename. This is accomplished by going to a designated ! 209: * row and column, as determined by the row and counter nested loops. ! 210: * The innermost loop gets the character found, copies the retrieved ! 211: * character into a string and deletes the character from the screen. ! 212: * When the filename has been deleted from the screen, it is reprinted ! 213: * to the screen with highliting turned on. Padding for spaces must be ! 214: * accounted for since deleting chars shifts everything on the line one ! 215: * space to the left. ! 216: */ ! 217: ! 218: /* print the first file in inverse video */ ! 219: ! 220: lite (win1, prevrow, prevcol, 1,0); ! 221: ! 222: do ! 223: { ! 224: noecho(); ! 225: ! 226: /* now we need to get a key (preferably an arrow) */ ! 227: ! 228: ! 229: ! 230: arrow = getch(); /* This stupid code should allow to use arrows keys */ ! 231: if (arrow == 27) /* that looks more frendly than hjkl. Vlad 8/15/91 */ ! 232: { ! 233: getch(); ! 234: arrow = getch(); /* When an arrow key is pressed, an escape */ ! 235: if (arrow == 68) /* sequence is returned. The value '27' */ ! 236: arrow = 'h'; /* begins the sequence and the relevant */ ! 237: if (arrow == 67) /* values needed end the sequence. The */ ! 238: arrow = 'l'; /* middle value is not needed, so it is */ ! 239: if (arrow == 66) /* skipped over with a getch() statement */ ! 240: arrow = 'j'; ! 241: if (arrow == 65) ! 242: arrow = 'k'; ! 243: } ! 244: ! 245: ! 246: /* each movement case in the following switch...case will test to see if the ! 247: * new position returns a space. If a space is returned, then we will hit ! 248: * an empty field, which we don't want to do. If we hit an empty space, ! 249: * then don't move the cursor. ! 250: */ ! 251: ! 252: switch(arrow) ! 253: { ! 254: case 'h': /* move left */ ! 255: newcol = prevcol - 15; ! 256: if (newcol < 1) ! 257: newcol = 61; ! 258: if (' ' == mvwinch(win1,newrow,newcol)) ! 259: newcol = 1; ! 260: break; ! 261: ! 262: ! 263: case 'l': /* move right */ ! 264: newcol = prevcol + 15; ! 265: if (newcol > 61) ! 266: newcol = 1; ! 267: if (' ' == mvwinch(win1,newrow,newcol)) ! 268: newcol = 1; ! 269: break; ! 270: ! 271: ! 272: case 'j': /* move down */ ! 273: newrow = prevrow + 1; ! 274: if (newrow == 20) ! 275: newrow = 0; ! 276: if (' ' == mvwinch(win1,newrow,newcol)) ! 277: newrow = 0; ! 278: break; ! 279: ! 280: ! 281: case 'k': /* move up */ ! 282: newrow = prevrow -1; ! 283: if (newrow == -1) ! 284: newrow = 19; ! 285: if (' ' == mvwinch(win1,newrow,newcol)) ! 286: newrow = 0; ! 287: break; ! 288: ! 289: ! 290: case 'p': ! 291: screen_num --; ! 292: newrow = 0; ! 293: newcol = 1; ! 294: if (screen_num < 0) ! 295: screen_num = 0; ! 296: else ! 297: { ! 298: EOF_FLAG = rfile(); ! 299: write_win(win1); ! 300: } ! 301: break; ! 302: ! 303: ! 304: case 'n': ! 305: newrow = 0; ! 306: newcol = 1; ! 307: if (EOF_FLAG == -1) ! 308: break; ! 309: else ! 310: { ! 311: screen_num ++; ! 312: EOF_FLAG = rfile(); ! 313: write_win(win1); ! 314: } ! 315: break; ! 316: ! 317: /* when we 'quit', we need to make sure that the screen number ! 318: * is set to 0 so that when the next file is selected, we begin ! 319: * at the start of the file. If not, we run the risk of reading ! 320: * something and causing a dump, or worse, system corruption. ! 321: */ ! 322: ! 323: case 'Q': ! 324: case 'q': ! 325: screen_num = 0; ! 326: break; ! 327: ! 328: case 13: ! 329: case 'S': ! 330: case 's': ! 331: wclear(win1); ! 332: wrefresh(win1); ! 333: wclear(win2); ! 334: ! 335: if((strstr(workfile,mapfile[0]) != NULL) || (strstr(workfile,mapfile[1])!= NULL) || (strstr(workfile,mapfile[2])!= NULL)) ! 336: { ! 337: map_command(win2,prevrow,prevcol,screen_num); ! 338: wclear(win1); ! 339: rfile(); ! 340: write_win(win1); ! 341: wrefresh(win1); ! 342: break; ! 343: } ! 344: ! 345: if( strstr(workfile,MAILFILE) != NULL) ! 346: { ! 347: print_mail_states(win2); ! 348: wclear(win2); ! 349: wrefresh(win2); ! 350: refresh(); ! 351: wrefresh(win1); ! 352: wclear(win1); ! 353: print_states(win1); ! 354: wrefresh(win1); ! 355: break; ! 356: } ! 357: ! 358: /* if we're not working on a mailfile record, display the Contents ! 359: * form. ! 360: */ ! 361: if(strstr(workfile,MAILFILE) == NULL) ! 362: { ! 363: display_form(win2); ! 364: display_record(win2,prevrow,prevcol,screen_num); ! 365: ! 366: write_win(win1); ! 367: wclear(win2); ! 368: wrefresh(win2); ! 369: menu(); ! 370: refresh(); ! 371: wrefresh(win1); ! 372: break; ! 373: } ! 374: ! 375: default: ! 376: newcol = prevcol; ! 377: newrow = prevrow; ! 378: break; ! 379: ! 380: } ! 381: ! 382: /* print previous file highlited in normal video */ ! 383: lite (win1, prevrow, prevcol, 0,0); ! 384: ! 385: /* print new filename selection in inverse video */ ! 386: ! 387: lite (win1, newrow, newcol, 1,0); ! 388: ! 389: /* set our previous coordinates so that we can go back ! 390: * and unlite a field when the next directin is given. ! 391: */ ! 392: ! 393: prevrow = newrow; ! 394: prevcol = newcol; ! 395: ! 396: ! 397: } ! 398: while (arrow != 'q'); ! 399: ! 400: } ! 401: ! 402: ! 403: ! 404: ! 405: int rfile() ! 406: ! 407: { ! 408: ! 409: FILE *infp; ! 410: int EOF_FLAG; ! 411: ! 412: ! 413: /* open file, abort on error */ ! 414: ! 415: if ((infp = fopen(workfile,"r")) == NULL) ! 416: { ! 417: printf("\007ERROR opening file %s for input!\n", workfile); ! 418: exit(1); ! 419: } ! 420: ! 421: /* open a file then go to a an offset calculated by a ! 422: * value passed from the calling program. Once we hit ! 423: * the max number of records that can be held by a screen, ! 424: * terminate the read and set a flag to show that we did ! 425: * not hit EOF. If we did hit EOF, terminate the loop ! 426: * and set a flag to show that we did hit EOF. ! 427: */ ! 428: ! 429: /* start reading from a specified point in the file */ ! 430: ! 431: if((strstr(workfile,mapfile[0])!= NULL) || (strstr(workfile,mapfile[1])!= NULL) || (strstr(workfile,mapfile[2])!= NULL)) ! 432: fseek(infp,(sizeof (struct map) * (screen_num * 100)),0l); ! 433: else ! 434: fseek(infp, (sizeof (struct entry) * (screen_num * 100)), 0l); ! 435: ! 436: limit = 0; ! 437: ! 438: ! 439: if((strstr(workfile,mapfile[0])!= NULL) || (strstr(workfile,mapfile[1])!= NULL) || (strstr(workfile,mapfile[2])!= NULL)) ! 440: { ! 441: while((fread(&map_rec,sizeof(struct map),1,infp)) != 0) ! 442: { ! 443: strcpy(filenames[limit], map_rec.name); ! 444: place[limit] = limit; ! 445: limit ++; ! 446: if (limit == 100) ! 447: break; ! 448: } ! 449: } ! 450: else ! 451: { ! 452: while((fread(&record, sizeof(struct entry),1, infp)) != 0) ! 453: { ! 454: strcpy(filenames[limit], record.filename); ! 455: place[limit] = limit; ! 456: limit++; ! 457: if (limit == 100) ! 458: break; ! 459: } ! 460: } ! 461: ! 462: ! 463: ! 464: /* if x made it to 100, then we did NOT hit EOF */ ! 465: ! 466: if((strstr(workfile,mapfile[0])!= NULL) || (strstr(workfile,mapfile[1])!= NULL) || (strstr(workfile,mapfile[2])!= NULL)) ! 467: { ! 468: if ( (limit == 100) && (fread (&map_rec,sizeof(struct map),1,infp)) != 0) ! 469: EOF_FLAG = 0; ! 470: else ! 471: EOF_FLAG = -1; ! 472: } ! 473: else ! 474: { ! 475: if ( (limit == 100) && (fread (&record,sizeof(struct entry),1,infp)) != 0) ! 476: EOF_FLAG = 0; ! 477: else ! 478: EOF_FLAG = -1; ! 479: } ! 480: fclose(infp); ! 481: return (EOF_FLAG); ! 482: ! 483: } ! 484: ! 485: ! 486: ! 487: /* ! 488: * writewin(); ! 489: * this routine does the actual work of writing filenames to a window ! 490: */ ! 491: ! 492: void write_win(win1) ! 493: ! 494: WINDOW *win1; ! 495: ! 496: { ! 497: ! 498: int r,c; /* these are our rows and columns */ ! 499: int counter = 0; /* this counts the number of files written */ ! 500: ! 501: ! 502: ! 503: /* clear the window */ ! 504: wclear(win1); ! 505: ! 506: /* the following loop will write the filenames to the window. ! 507: * 15 characters per screen field are allowed, since a filename ! 508: * can only be 14 chars in length. This will leave at least one ! 509: * space between filenames. ! 510: */ ! 511: ! 512: for (r = 0; r < 20; r++) ! 513: { ! 514: ! 515: /* if we've run out of files, terminate loop */ ! 516: ! 517: if (counter == limit) ! 518: break; ! 519: ! 520: /* increment column by 15 positions. This ! 521: * will cause the filenames to line up ! 522: * on the window. ! 523: */ ! 524: ! 525: for (c = 1; c < 75; c+= 15) ! 526: { ! 527: wmove(win1, r, c); ! 528: waddstr(win1, filenames[counter]); ! 529: ! 530: /* increment counter. When it equals the number of ! 531: * records, passed as 'limit', the loop should ! 532: * terminate. ! 533: */ ! 534: ! 535: counter ++; ! 536: if (counter == limit) ! 537: break; ! 538: } ! 539: } ! 540: ! 541: ! 542: } ! 543: ! 544: /* this function will draw a template for the selected record */ ! 545: ! 546: void display_form(win2) ! 547: WINDOW *win2; ! 548: ! 549: ! 550: { ! 551: int x; ! 552: ! 553: clear(); ! 554: wclear(win2); ! 555: ! 556: /* print field labels */ ! 557: ! 558: wmove (win2, NAMELOCATE ); ! 559: waddstr (win2,"Filename:"); ! 560: ! 561: wmove (win2, DESCLOCATE); ! 562: waddstr(win2,"Description:"); ! 563: ! 564: wmove(win2, DATELOCATE ); ! 565: waddstr(win2,"Date added/modified:"); ! 566: ! 567: wmove(win2, SIZELOCATE); ! 568: waddstr(win2,"File size:"); ! 569: ! 570: wmove(win2, REQLOCATE ); ! 571: waddstr(win2,"Requires these other files:"); ! 572: ! 573: wmove(win2, NOTELOCATE); ! 574: waddstr(win2,"Other notes:"); ! 575: ! 576: ! 577: /* highlite available fields */ ! 578: ! 579: wstandout(win2); ! 580: ! 581: wmove (win2, NAMEHI); ! 582: waddstr(win2," "); ! 583: ! 584: wmove (win2,DESCHI); ! 585: for (x=1;x<79;x++) ! 586: waddstr(win2," "); ! 587: ! 588: wmove(win2, DATEHI); ! 589: waddstr(win2," "); ! 590: ! 591: wmove(win2, SIZEHI); ! 592: waddstr(win2," "); ! 593: ! 594: wmove (win2,REQHI); ! 595: for (x=1;x<61;x++) ! 596: waddstr(win2," "); ! 597: ! 598: wmove (win2,NOTEHI); ! 599: for (x=1;x<69;x++) ! 600: waddstr(win2," "); ! 601: ! 602: wstandend(win2); ! 603: refresh(); ! 604: wrefresh(win2); ! 605: ! 606: ! 607: ! 608: } ! 609: ! 610: /* following function prints the menu at the bottom of stdscr */ ! 611: ! 612: void menu() ! 613: ! 614: { ! 615: /* print a menu of options to stdscr. They will appear at the bottom of ! 616: * the screen with the first letter highlited as an indication to ! 617: * the user that pressing the highlited key will result in the indicated ! 618: * action. ! 619: */ ! 620: ! 621: move (21,0); ! 622: if(strstr(workfile,MAILFILE) != NULL) ! 623: printw("Select state/other to view."); ! 624: else ! 625: printw("Select file to download. "); ! 626: refresh(); ! 627: ! 628: ! 629: move(21, 50); ! 630: standout(); ! 631: printw("Options:"); ! 632: move(22,46); ! 633: printw("n"); ! 634: move(23,46); ! 635: printw("p"); ! 636: move(22,60); ! 637: printw("q"); ! 638: move(23,60); ! 639: printw("s"); ! 640: standend(); ! 641: move(22,47); ! 642: addstr("ext page"); ! 643: move(23,47); ! 644: addstr("rev. page"); ! 645: move(22,61); ! 646: addstr("uit"); ! 647: move(23,61); ! 648: addstr("elect file"); ! 649: ! 650: ! 651: } ! 652: ! 653: ! 654: ! 655: /* this function will take the pathname and append the necessary ! 656: * character(s) to generate the multiple requests necessary to ! 657: * download multipart files. ! 658: */ ! 659: ! 660: void build_uucp(record) ! 661: ! 662: ! 663: { ! 664: int x,y,z; ! 665: ! 666: y = strlen(record.pathname); ! 667: ! 668: for(x=0;x< record.noparts;x++){ ! 669: strcpy(getfiles[x],HOST); ! 670: record.pathname[y] = 97 + x; ! 671: record.pathname[y+1] = '\0'; ! 672: strcat(getfiles[x],record.pathname); ! 673: strcat(getfiles[x],recdir); ! 674: ! 675: for(z=strlen(getfiles[x]) ; z < sizeof(getfiles[x]) ; z++){ ! 676: getfiles[x][z] = '\0'; ! 677: } ! 678: ! 679: } ! 680: ! 681: ! 682: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.