/* James Davis (jedavis@ucdavis.edu) c. 1991 */ /* 6708 Austin Way, Sacramento CA 95823 */ /* */ /* Written as part of a number of scripts to make ftping easier. THere */ /* are a huge number of improvements that could be made, but I havent */ /* time. If you'd like to change something, go ahead. But send me a */ /* copy so Ill know. Feel free to distribute. */ /* */ /* -- This is the code that produces the ftpmenubase program. It relies */ /* -- on curses, so make sure you have that package. Also since different */ /* -- versions of curses use differnt things for cbreak mode you may have to */ /* -- change the define. e.g. on a vax 11/785 here I had to change it to */ /* -- crmode and nocrmode. */ /* -- The pager define should be set to the complete path of you're pager */ /* -- I DONT check your environment variable, since I rely on some options */ /* -- In 'less'. Specifically if you say 'less +/word file' less will open */ /* -- file and immediately search for word. My version of more works the same*/ /* -- but I suppose the only way you'll know is try. Its only important for */ /* -- the ability to look up abstracts. So stick to less or more, and forget */ /* other pagers. You could always modify the code I suppose. */ /* The long FTPMENUCBREAK is because CBREAK itself is a macro, and I */ /* didnt want to take a chance on interfering. */ /* Apologies for the lack of comments, but... If you have questions */ /* drop a line, Ill try to explain. */ /* Compile with 'cc ftpmenu.c -lcurses -ltermcap' */ /* The important point here is the 'cc'. For some reason if you use */ /* 'gcc' then wait() corrupts my data. If you notice that when you */ /* try to look at an abstract by hitting 'a' and when you exit the pager */ /* Something behaves strangely please report it. I never tracked down */ /* Why 'gcc' didnt work, so it may be my bug, but I prefer to blame */ /* Someone else. For that matter please report any bugs */ #define PAGER "/usr/local/less" #define FTPMENUCBREAK cbreak #define FTPMENUNOCBREAK nocbreak #include #include #include struct myrec { struct myrec *nextthis; struct myrec *nextlower; char fsize[8]; char month[4]; char day[3]; char name[50]; char mark; } ; char line[85]; FILE *datafile; FILE *outfile; char cursite[85]; char curdir[85]; int simple; int usedsite, useddir; struct myrec *curlvlptr[4]; int pos[4]; int lps; int cdone =0; int gargc; char **gargv; int thisdirect () { printf ("Directory :"); fscanf (datafile,"%s",line); printf ("%s\n",line); strcpy (curdir,line); useddir = 0; return (0); } void usesite () { fprintf (outfile, "close\n"); fprintf (outfile,"o %s\n",cursite); usedsite = 1; } void usedir () { fprintf (outfile,"cd %s\n",curdir); useddir =1; } int thissite () { fscanf (datafile,"%s",line); if (!(line[0]=='*')) { printf ("\n"); printf ("Site: %s\n",line); strcpy (cursite,line); usedsite = 0; } return (0); } int thisfile () { int i; char resp[80]; char response; printf ("Get file: "); for (i=0;i<7;i++) { fscanf (datafile,"%s",line); if (i>1) printf ("\t%s",line); } printf ("\t: "); gets(resp); response = resp[0]; if (response=='y' || response=='Y') { if (usedsite==0) usesite(); if (0==useddir) usedir(); fprintf (outfile,"get %s\n",line); } if (response=='d' || response=='D') return (1); if (response=='s' || response=='S') return (2); return (0); } void generalmethod () { int mode; while (fscanf (datafile,"%s",line) != EOF) { if ((!strcmp(line,"257")) && (mode<2)) mode = thisdirect(); if ((!strcmp(line,"SITE")) ) mode = thissite(); if ((line[0]=='-') && (line[1]=='r') && (!mode)) mode = thisfile (); } } int loadsite () { fscanf (datafile,"%s",line); if (!(line[0]=='*')) { printf ("\nLoading : %s ",line); curlvlptr[1]->nextthis = (struct myrec *) malloc (sizeof (struct myrec)); curlvlptr[1] = curlvlptr[1]->nextthis; curlvlptr[1]->nextlower = (struct myrec *) malloc (sizeof (struct myrec)); curlvlptr[2] = curlvlptr[1]->nextlower; strcpy (curlvlptr[2]->name,".."); curlvlptr[1]->nextthis = NULL; curlvlptr[2]->nextlower = NULL; strcpy (curlvlptr[1]->name,line); return(1); } else return (0); } void loaddirect () { fscanf (datafile,"%s",line); addstr ("."); refresh(); curlvlptr[2]->nextthis = (struct myrec *) malloc (sizeof (struct myrec)); curlvlptr[2] = curlvlptr[2]->nextthis; curlvlptr[2]->nextlower = (struct myrec *) malloc (sizeof (struct myrec)); curlvlptr[3] = curlvlptr[2]->nextlower; strcpy (curlvlptr[3]->name,".."); curlvlptr[3]->mark=0; /*curlvlptrdirptr->nextdir = NULL; curfileptr->nextfile = NULL; */ strcpy (curlvlptr[2]->name,line); } void loadfile () { curlvlptr[3]->nextthis = (struct myrec *) malloc (sizeof(struct myrec)); curlvlptr[3] = curlvlptr[3]->nextthis; curlvlptr[3]->nextthis = NULL; curlvlptr[3]->mark=0; fscanf (datafile,"%s",line); fscanf (datafile,"%s",line); fscanf (datafile,"%s",line); strcpy (curlvlptr[3]->fsize,line); fscanf (datafile,"%s",line); strcpy (curlvlptr[3]->month,line); fscanf (datafile,"%s",line); strcpy (curlvlptr[3]->day,line); fscanf (datafile,"%s",line); fscanf (datafile,"%s",line); strcpy (curlvlptr[3]->name,line); } void loadstruct() { int fc,dc,sc; curlvlptr[0] = (struct myrec *) malloc (sizeof (struct myrec)); curlvlptr[0]->nextlower = (struct myrec *) malloc (sizeof (struct myrec)); curlvlptr[1] = curlvlptr[0]->nextlower; strcpy (curlvlptr[1]->name,".."); sc=0; dc=0; fc=0; while (fscanf (datafile,"%s",line) != EOF) { if ((!strcmp(line,"257")) && (sc < (LINES)) && (dc < (LINES-5))) { dc++; fc=0; loaddirect(); } if ((!strcmp(line,"SITE")) && (sc<(LINES-1) )) { sc += loadsite(); dc=0; } if ((line[0]=='-') && (line[1]=='r') && (sc<(LINES)) && (dc<(LINES-4)) && (fc<(LINES-5))) { loadfile (); fc++; } } } void savetofile() { curlvlptr[1]=curlvlptr[0]->nextlower->nextthis; while (curlvlptr[1] != NULL) { usedsite=0; strcpy(cursite,curlvlptr[1]->name); curlvlptr[2]=curlvlptr[1]->nextlower->nextthis; while (curlvlptr[2] != NULL) { useddir=0; strcpy(curdir,curlvlptr[2]->name); curlvlptr[3]=curlvlptr[2]->nextlower->nextthis; while (curlvlptr[3] != NULL) { if (curlvlptr[3]->mark) { if (!usedsite) usesite(); if (!useddir) usedir(); fprintf (outfile,"get %s\n",curlvlptr[3]->name); } curlvlptr[3]=curlvlptr[3]->nextthis; } curlvlptr[2] = curlvlptr[2]->nextthis; } curlvlptr[1]=curlvlptr[1]->nextthis; } } dispbottom (level) int level; { if (level == 2) { move (LINES-2,10); addstr (curlvlptr[1]->name); } if (level == 3) { move (LINES-2,10); addstr (curlvlptr[1]->name); addstr (" : "); addstr (curlvlptr[2]->name); } } void displine(level,cntr) int level,cntr; { move (cntr,10); addstr (curlvlptr[level]->name); if (level == 3) { move (cntr,40); addstr (curlvlptr[3]->month); move (cntr,44); addstr (curlvlptr[3]->day); move (cntr,50); addstr (curlvlptr[3]->fsize); if (curlvlptr[3]->mark) { move (cntr,9); addstr("*"); } } } void helpnote() { clear(); move (2,4); addstr ("j - move pointer down"); move (3,4); addstr ("J - move pointer down faster"); move (4,4); addstr ("k - move pointer up"); move (5,4); addstr ("K - move pointer up faster"); move (6,4); addstr ("a - look at the abstract for this file"); move (7,4); addstr ("u - takes you one step up the hierarchy: file->directory; directory->site"); move (8,4); addstr ("n - next directory"); move (9,4); addstr ("N - next site"); move (10,4); addstr ("x - quit, and get the marked files"); move (11,4); addstr ("X - quit, but dont get anything"); move (12,4); addstr ("h or ? - this help message"); move (13,4); addstr ("space - show the indicated site or directory, or mark a file for retrieval"); refresh(); getch(); } int menu(level) int level; { char key; char k[80]; int cntr; int maxitem,npos; int ref; ref = 1; pos[level] =1; do { if (ref==1) /*refresh*/ { clear(); cntr = 1; curlvlptr[level] = curlvlptr[(level-1)]->nextlower; if (level==1) curlvlptr[1] = curlvlptr[1]->nextthis; while (curlvlptr[level] != NULL) { displine(level,cntr); curlvlptr[level] = curlvlptr[level]->nextthis; cntr++; } maxitem = --cntr; move (pos[level],6); addstr ("-->"); dispbottom(level); move (0,0); refresh(); ref=0; } key=getch(); if ((key=='j') || (key=='J')) { lps=1; if (key=='J') lps=4; for (cntr=0;cntr"); pos[level] = npos; } move (0,0); refresh(); } if ((key=='k') || (key=='K') ) { lps=1; if (key=='K') lps=4; for (cntr=0;cntr"); pos[level] = npos; } move (0,0); refresh(); } if (((key=='d') || (key==' ')) ) { curlvlptr[level] = curlvlptr[level-1]->nextlower; for (cntr=(level!=1);cntrnextthis; if (level == 1) menu (2); if (level == 2) { if (curlvlptr[2] == curlvlptr[1]->nextlower) key='u'; else { menu(3); ref=1; } } if (level ==3) { if (curlvlptr[3] == curlvlptr[2]->nextlower) key='u'; else { curlvlptr[3]->mark=(-((curlvlptr[3]->mark)-1)); move (pos[3],9); if (curlvlptr[3]->mark) addstr ("*"); else addstr(" "); move (0,0); refresh(); } } if (level<3) ref=1; } if (((key=='n') || (key=='N')) && (level==2)) { curlvlptr[1]=curlvlptr[1]->nextthis; pos[1]++; if (curlvlptr[1]==NULL) { curlvlptr[1]=curlvlptr[0]->nextlower->nextthis; pos[1]=1; } curlvlptr[2]=curlvlptr[1]->nextlower; pos[2]=1; ref=1; } if ((key=='N') && (level==3)) { curlvlptr[1]=curlvlptr[1]->nextthis; pos[1]++; if (curlvlptr[1]==NULL) { curlvlptr[1]=curlvlptr[0]->nextlower->nextthis; pos[1]=1; } curlvlptr[2]=curlvlptr[1]->nextlower->nextthis; pos[2]=2; curlvlptr[3]=curlvlptr[2]->nextlower; pos[3]=1; ref=1; } if ((key=='n') && (level==3)) { /*printf ("%s%s%s\n",curlvlptr[1]->name,curlvlptr[2]->name,curlvlptr[3]->name); gets (); */ curlvlptr[2]=curlvlptr[2]->nextthis; pos[2]++; if (curlvlptr[2]==NULL) { curlvlptr[2]=curlvlptr[1]->nextlower->nextthis; pos[2]=2; } pos[3]=1; ref=1; } if ((key=='a') && (pos[3]!=1) && (gargc>3) && (level==3)) { clear(); refresh(); curlvlptr[3] = curlvlptr[2]->nextlower; for (cntr =1;cntrnextthis; strcpy(line,"+/"); strcat(line,curlvlptr[3]->name); if (fork()==0) execl (PAGER,PAGER,line,gargv[3],(char *) 0); else wait(0); ref=1; } if ((key=='h') || (key=='?')) { helpnote(); ref=1; } if (key=='x') cdone = 1; if (key=='X') cdone = 2; } while ((!cdone) && (key !='u')); return (cdone); } void init (argc,argv) int argc; char **argv; { gargc = argc; gargv = argv; datafile = fopen (argv[1],"r"); outfile = fopen (argv[2],"w"); initscr(); clear(); refresh(); FTPMENUCBREAK(); noecho(); } void finish () { FTPMENUNOCBREAK(); endwin(); fclose (datafile); fclose (outfile); } void usagemessage (argv) char **argv; { printf ("Usage: %s [abstractFile]\n",argv[0]); } void main (argc,argv) int argc; char **argv; { if (argc<3) {usagemessage(argv); return;} init(argc,argv); loadstruct(); menu(1); if (cdone>0) savetofile(); finish(); } .