home *** CD-ROM | disk | FTP | other *** search
/ HAM Radio 1 / HamRadio.cdr / misc / tcpipsrc / session.c < prev    next >
C/C++ Source or Header  |  1991-01-26  |  9KB  |  430 lines

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