home *** CD-ROM | disk | FTP | other *** search
/ Media Share 9 / MEDIASHARE_09.ISO / hamradio / s920603.zip / SESSION.C < prev    next >
C/C++ Source or Header  |  1992-06-03  |  9KB  |  439 lines

  1. /* NOS User Session control
  2.  * Copyright 1991 Phil Karn, KA9Q
  3.  */
  4. #include <stdio.h>
  5. #include "global.h"
  6. #include "mbuf.h"
  7. #include "proc.h"
  8. #include "ftpcli.h"
  9. #include "icmp.h"
  10. #include "telnet.h"
  11. #include "tty.h"
  12. #include "session.h"
  13. #include "hardware.h"
  14. #include "socket.h"
  15. #include "cmdparse.h"
  16. #include "commands.h"
  17. #include "main.h"
  18.  
  19. struct session **Sessions;
  20. struct session *Command;
  21. struct session *Current;
  22. struct session *Lastcurr;
  23. char Notval[] = "Not a valid control block\n";
  24. static char Badsess[] = "Invalid session\n";
  25. char *Sestypes[] = {
  26.     "",
  27.     "Telnet",
  28.     "FTP",
  29.     "AX25",
  30.     "Finger",
  31.     "Ping",
  32.     "NET/ROM",
  33.     "Command",
  34.     "More",
  35.     "Hopcheck",
  36.     "Tip",
  37.     "PPP PAP",
  38.     "Dial",
  39.     "Query",
  40.     "Cache",
  41.     "Trace"
  42. };
  43.  
  44. /* Convert a character string containing a decimal session index number
  45.  * into a pointer. If the arg is NULLCHAR, use the current default session.
  46.  * If the index is out of range or unused, return NULLSESSION.
  47.  */
  48. struct session *
  49. sessptr(cp)
  50. char *cp;
  51. {
  52.     unsigned int i;
  53.  
  54.     if(cp == NULLCHAR)
  55.         return Lastcurr;
  56.  
  57.     i = (unsigned)atoi(cp);
  58.     if(i >= Nsessions)
  59.         return NULLSESSION;
  60.     else
  61.         return Sessions[i];
  62. }
  63.  
  64. /* Select and display sessions */
  65. int
  66. dosession(argc,argv,p)
  67. int argc;
  68. char *argv[];
  69. void *p;
  70. {
  71.     struct session *sp;
  72.     struct sockaddr fsocket;
  73.     int i,k,s,ses;
  74.     int r,t;
  75.     char *cp;
  76.  
  77.     sp = (struct session *)p;
  78.  
  79.     if(argc > 1){
  80.         if((sp = sessptr(argv[1])) != NULLSESSION){
  81.             go(0,NULL,sp);
  82.         } else
  83.             printf("Session %s not active\n",argv[1]);
  84.         return 0;
  85.     }
  86.     printf(" #  S#  Type     Rcv-Q Snd-Q State        Remote socket\n");
  87.     for(ses=0;ses<Nsessions;ses++){
  88.         sp = Sessions[ses];
  89.         if(sp == NULLSESSION || sp->type == COMMAND)
  90.             continue;
  91.  
  92.         t = 0;
  93.         cp = NULLCHAR;
  94.         if(sp->network != NULLFILE && (s = fileno(sp->network)) != -1){
  95.             i = SOCKSIZE;
  96.             s = fileno(sp->network);
  97.             k = getpeername(s,(char *)&fsocket,&i);
  98.             r = socklen(s,0);
  99.             t += socklen(s,1);
  100.             cp = sockstate(s);
  101.         } else {
  102.             s = -1;
  103.             r = t = 0;
  104.             cp = NULLCHAR;
  105.         }
  106.         printf("%c", (Lastcurr == sp)? '*':' ');
  107.         printf("%-3u",sp->index);
  108.         printf("%-4d%-8s%6d%6d %-13s",
  109.          s,
  110.          Sestypes[sp->type],
  111.          r,
  112.          t,
  113.          (cp != NULLCHAR) ? cp : "");
  114.         if(sp->name != NULLCHAR)
  115.             printf("%s ",sp->name);
  116.         if(sp->network != NULLFILE && k == 0)
  117.             printf("(%s)",psocket(&fsocket));
  118.  
  119.         printf("\n");
  120.         if(sp->type == FTP && (s = fileno(sp->cb.ftp->data)) != -1){
  121.             /* Display data channel, if any */
  122.             i = SOCKSIZE;
  123.             k = getpeername(s,(char *)&fsocket,&i);
  124.             r = socklen(s,0);
  125.             t = socklen(s,1);
  126.             cp = sockstate(s);
  127.             printf("    %-4d%-8s%6d%6d %-13s%s",
  128.              s,
  129.              Sestypes[sp->type],
  130.              r,
  131.              t,
  132.              (cp != NULLCHAR) ? cp : "",
  133.              (sp->name != NULLCHAR) ? sp->name : "");
  134.             if(k == 0)
  135.                 printf(" (%s)",psocket(&fsocket));
  136.             if(printf("\n") == EOF)
  137.                 break;
  138.         }
  139.         if(sp->record != NULLFILE)
  140.             printf("    Record: %s\n",fpname(sp->record));
  141.         if(sp->upload != NULLFILE)
  142.             printf("    Upload: %s\n",fpname(sp->upload));
  143.     }
  144.     return 0;
  145. }
  146. /* Resume current session, and wait for it */
  147. int
  148. go(argc,argv,p)
  149. int argc;
  150. char *argv[];
  151. void *p;
  152. {
  153.     struct session *sp;
  154.  
  155.     sp = (struct session *)p;
  156.     if(sp == NULLSESSION || sp->type == COMMAND)
  157.         return 0;
  158.     if(Current != Command)
  159.         Lastcurr = Current;
  160.     Current = sp;
  161.     alert(Display,1);
  162.     return 0;
  163. }
  164. int
  165. doclose(argc,argv,p)
  166. int argc;
  167. char *argv[];
  168. void *p;
  169. {
  170.     struct session *sp;
  171.  
  172.     sp = (struct session *)p;
  173.     if(argc > 1)
  174.         sp = sessptr(argv[1]);
  175.  
  176.     if(sp == NULLSESSION){
  177.         printf(Badsess);
  178.         return -1;
  179.     }
  180.     shutdown(fileno(sp->network),1);
  181.     return 0;
  182. }
  183. int
  184. doreset(argc,argv,p)
  185. int argc;
  186. char *argv[];
  187. void *p;
  188. {
  189.     struct session *sp;
  190.  
  191.     sp = (struct session *)p;
  192.     if(argc > 1)
  193.         sp = sessptr(argv[1]);
  194.  
  195.     if(sp == NULLSESSION){
  196.         printf(Badsess);
  197.         return -1;
  198.     }
  199.     /* Unwedge anyone waiting for a domain resolution, etc */
  200.     alert(sp->proc,EABORT);
  201.     shutdown(fileno(sp->network),2);
  202.     if(sp->type == FTP)
  203.         shutdown(fileno(sp->cb.ftp->data),2);
  204.     return 0;
  205. }
  206. int
  207. dokick(argc,argv,p)
  208. int argc;
  209. char *argv[];
  210. void *p;
  211. {
  212.     struct session *sp;
  213.  
  214.     sp = (struct session *)p;
  215.     if(argc > 1)
  216.         sp = sessptr(argv[1]);
  217.  
  218.     if(sp == NULLSESSION){
  219.         printf(Badsess);
  220.         return -1;
  221.     }
  222.     sockkick(fileno(sp->network));
  223.     if(sp->type == FTP)
  224.         sockkick(fileno(sp->cb.ftp->data));
  225.     return 0;
  226. }
  227.  
  228. struct session *
  229. newsession(name,type,makecur)
  230. char *name;
  231. int type;
  232. int makecur;
  233. {
  234.     register struct session *sp;
  235.     int i;
  236.  
  237.     /* Search for a free slot in the session table */
  238.     for(i=0;i < Nsessions;i++)
  239.         if(Sessions[i] == NULLSESSION)
  240.             break;
  241.     if(i == Nsessions)
  242.         return NULLSESSION;    /* All full */
  243.  
  244.     sp = Sessions[i] = (struct session *)calloc(1,sizeof(struct session));
  245.     sp->index = i;
  246.     sp->type = type;
  247.     if(name != NULLCHAR)
  248.         sp->name = strdup(name);
  249.     sp->proc = Curproc;
  250.     /* Create standard input and output sockets. Output is
  251.      * in text mode by default
  252.      */
  253.     fclose(stdin);
  254.     stdin =  sp->input = pipeopen();
  255.     setvbuf(stdin,NULLCHAR,_IONBF,0);
  256.     fclose(stdout);
  257.     stdout = sp->output = displayopen("wt",0);
  258.  
  259.     /* on by default */
  260.     sp->ttystate.crnl = sp->ttystate.edit = sp->ttystate.echo = 1;
  261.     if(makecur){
  262.         if(Current != Command)
  263.             Lastcurr = Current;
  264.         Current = sp;
  265.         alert(Display,1);
  266.     }
  267.     return sp;
  268. }
  269. void
  270. freesession(sp)
  271. struct session *sp;
  272. {
  273.     if(sp == NULLSESSION || sp != Sessions[sp->index])
  274.         return;    /* Not on session list */
  275.     pwait(NULL);    /* Wait for any pending output to go */
  276.  
  277.     Sessions[sp->index] = NULLSESSION;
  278.     if(sp->proc1 != NULLPROC)
  279.         killproc(sp->proc1);
  280.     if(sp->proc2 != NULLPROC)
  281.         killproc(sp->proc2);
  282.  
  283.     free(sp->ttystate.line);
  284.     if(sp->network != NULLFILE)
  285.         fclose(sp->network);
  286.  
  287.     if(sp->record != NULLFILE)
  288.         fclose(sp->record);
  289.  
  290.     if(sp->upload != NULLFILE)
  291.         fclose(sp->upload);
  292.  
  293.     free(sp->name);
  294.  
  295.     if(Lastcurr == sp)
  296.         Lastcurr = NULLSESSION;
  297.     if(Current == sp){
  298.         if(Lastcurr != NULLSESSION)
  299.             Current = Lastcurr;
  300.         else
  301.             Current = Command;
  302.         alert(Display,1);
  303.     }
  304.     free(sp);
  305. }
  306. /* Control session recording */
  307. int
  308. dorecord(argc,argv,p)
  309. int argc;
  310. char *argv[];
  311. void *p;
  312. {
  313.     struct session *sp;
  314.     char *mode;
  315.  
  316.     sp = (struct session *)p;
  317.     if(sp == NULLSESSION){
  318.         printf("No current session\n");
  319.         return 1;
  320.     }
  321.     if(argc > 1){
  322.         if(sp->record != NULLFILE){
  323.             fclose(sp->record);
  324.             sp->record = NULLFILE;
  325.         }
  326.         /* Open new record file, unless file name is "off", which means
  327.          * disable recording
  328.          */
  329.         if(strcmp(argv[1],"off") != 0){
  330.             if(fmode(sp->output,-1) == STREAM_ASCII)
  331.                 mode = APPEND_TEXT;
  332.             else
  333.                 mode = APPEND_BINARY;
  334.  
  335.             if((sp->record = fopen(argv[1],mode)) == NULLFILE)
  336.                 printf("Can't open %s: %s\n",argv[1],sys_errlist[errno]);
  337.         }
  338.     }
  339.     if(sp->record != NULLFILE)
  340.         printf("Recording into %s\n",fpname(sp->record));
  341.     else
  342.         printf("Recording off\n");
  343.     return 0;
  344. }
  345. /* Control file transmission */
  346. int
  347. doupload(argc,argv,p)
  348. int argc;
  349. char *argv[];
  350. void *p;
  351. {
  352.     register struct session *sp;
  353.  
  354.     sp = (struct session *)p;
  355.     if(sp == NULLSESSION){
  356.         printf("No current session\n");
  357.         return 1;
  358.     }
  359.     if(argc < 2){
  360.         if(sp->upload != NULLFILE)
  361.             printf("Uploading %s\n",fpname(sp->upload));
  362.         else
  363.             printf("Uploading off\n");
  364.         return 0;
  365.     }
  366.     if(strcmp(argv[1],"stop") == 0 && sp->upload != NULLFILE){
  367.         /* Abort upload */
  368.         fclose(sp->upload);
  369.         sp->upload = NULLFILE;
  370.         killproc(sp->proc2);
  371.         sp->proc2 = NULLPROC;
  372.         return 0;
  373.     }
  374.     /* Open upload file */
  375.     if((sp->upload = fopen(argv[1],READ_TEXT)) == NULLFILE){
  376.         printf("Can't read %s: %s\n",argv[1],sys_errlist[errno]);
  377.         return 1;
  378.     }
  379.     /* All set, invoke the upload process */
  380.     sp->proc2 = newproc("upload",1024,upload,0,sp,NULL,0);
  381.     return 0;
  382. }
  383. /* File uploading task */
  384. void
  385. upload(unused,sp1,p)
  386. int unused;
  387. void *sp1;
  388. void *p;
  389. {
  390.     struct session *sp;
  391.     char *buf;
  392.  
  393.     sp = (struct session *)sp1;
  394.  
  395.     buf = mallocw(BUFSIZ);
  396.     while(fgets(buf,BUFSIZ,sp->upload) != NULLCHAR)
  397.         if(fputs(buf,sp->network) == EOF)
  398.             break;
  399.  
  400.     free(buf);
  401.     fflush(sp->network);
  402.     fclose(sp->upload);
  403.     sp->upload = NULLFILE;
  404.     sp->proc2 = NULLPROC;
  405. }
  406.  
  407. /* Print prompt and read one character */
  408. int
  409. keywait(prompt,flush)
  410. char *prompt;    /* Optional prompt */
  411. int flush;    /* Flush queued input? */
  412. {
  413.     int c;
  414.     int i;
  415.  
  416.     if(prompt == NULLCHAR)
  417.         prompt = "Hit enter to continue"; 
  418.     printf(prompt);
  419.     fflush(stdout);
  420.     c = _fgetc(stdin);
  421.     /* Get rid of the prompt */
  422.     for(i=strlen(prompt);i != 0;i--)
  423.         putchar('\b');
  424.     for(i=strlen(prompt);i != 0;i--)
  425.         putchar(' ');
  426.     for(i=strlen(prompt);i != 0;i--)
  427.         putchar('\b');
  428.     fflush(stdout);
  429.     return (int)c;
  430. }
  431.  
  432. /* Flush the current session's standard output. Called on every clock tick */
  433. void
  434. sesflush()
  435. {
  436.     if(Current != NULLSESSION)
  437.         fflush(Current->output);
  438. }
  439.