home *** CD-ROM | disk | FTP | other *** search
/ HAM Radio 3 / hamradioversion3.0examsandprograms1992.iso / packet / n17jsrc / session.c < prev    next >
C/C++ Source or Header  |  1991-06-19  |  9KB  |  452 lines

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