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