home *** CD-ROM | disk | FTP | other *** search
/ High Voltage Shareware / high1.zip / high1 / DIR3 / KA9Q212.ZIP / SESSION.C < prev    next >
C/C++ Source or Header  |  1993-07-16  |  9KB  |  446 lines

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