home *** CD-ROM | disk | FTP | other *** search
/ The Datafile PD-CD 3 / PDCD_3.iso / internet / tcpipsrc / Finger / c / fingcli next >
Text File  |  1994-08-20  |  7KB  |  298 lines

  1. /*
  2.  *
  3.  *      Finger support...
  4.  *
  5.  *      Finger client routines.  Written by Michael T. Horne - KA7AXD.
  6.  *      Copyright 1988 by Michael T. Horne, All Rights Reserved.
  7.  *      Permission granted for non-commercial use and copying, provided
  8.  *      that this notice is retained.
  9.  *
  10.  */
  11.  
  12. #include <stdio.h>
  13. #include <stdlib.h>
  14. #include <string.h>
  15. #include "global.h"
  16. #include "mbuf.h"
  17. #include "domain.h"
  18. #include "timer.h"
  19. #include "internet.h"
  20. #include "icmp.h"
  21. #include "netuser.h"
  22. #include "tcp.h"
  23. #include "finger.h"
  24. #include "session.h"
  25. #include "misc.h"
  26. #include "Terminal.h"
  27. #include "vterm.h"
  28.  
  29. extern char badhost[], hostname[];
  30.  
  31. /* Open up a socket to a remote (or the local) host on its finger port. */
  32.  
  33. int dofinger(int argc, char **argv)
  34. {
  35.   struct session  *s;
  36.   struct tcb      *tcb;
  37.   struct socket   lsocket,
  38.   fsocket;
  39.   struct finger   *finger;
  40.   char            *host;
  41.  
  42.   if (argc < 2)
  43.   {
  44.     cwprintf(NULL, "usage: %s [user | user@host | @host]\r\n", argv[0]);
  45.     return(1);
  46.   }
  47.  
  48.  
  49.   lsocket.address = ip_addr;
  50.   lsocket.port = lport++;
  51.  
  52.   /* Extract user/host information.  It can be of the form:
  53.  
  54.      finger user,                    # finger local user
  55.      finger user@host,               # finger remote user
  56.      finger @host                    # finger host (give system status)
  57.     */
  58.   if ((finger = alloc_finger()) == NULLFING)
  59.     return(1);
  60.  
  61.   if ((host = strchr(argv[1], '@')) == NULL)
  62.   {
  63.     fsocket.address = ip_addr;      /* no host, use local */
  64.     if ((finger->user = malloc(strlen(argv[1]) + 3)) == NULL)
  65.     {
  66.       free_finger(finger);
  67.       return(1);
  68.     }
  69.     strcpy(finger->user, argv[1]);
  70.     strcat(finger->user, "\015\012");
  71.   }
  72.   else
  73.   {
  74.     *host++ = '\0';         /* null terminate user name */
  75.     if (*host == '\0')
  76.     {        /* must specify host */
  77.       cwprintf(NULL, "%s: no host specified\r\n", argv[0]);
  78.       cwprintf(NULL, "usage: %s [user | user@host | @host]\r\n", argv[0]);
  79.       free_finger(finger);
  80.       return(1);
  81.     }
  82.     if ((fsocket.address = resolve(host)) == 0)
  83.     {
  84.       cwprintf(NULL, "%s: ", argv[0]);
  85.       cwprintf(NULL, badhost, host);
  86.       free_finger(finger);
  87.       return(1);
  88.     }
  89.     if ((finger->user = malloc(strlen(argv[1])+3))==NULL)
  90.     {
  91.       free_finger(finger);
  92.       return 1;
  93.     }
  94.     strcpy(finger->user, argv[1]);
  95.     strcat(finger->user, "\015\012");
  96.   }
  97.  
  98.   fsocket.port = FINGER_PORT;             /* use finger wnp */
  99.  
  100.   /* Allocate a session descriptor */
  101.   if ((s = newsession()) == NULLSESSION)
  102.   {
  103.     cwprintf(NULL, "Too many sessions\r\n");
  104.     free_finger(finger);
  105.     return 1;
  106.   }
  107.   finger->window = Window_Open(s, "Finger", term_NO_INPUT);
  108.   vterm_visible(finger->window->vt, 50, 10);
  109.   vterm_parse(finger->window->vt, argc-2, argv+2);
  110.   current = s;
  111.   s->cb.finger = finger;
  112.   finger->session = s;
  113.   s->window = finger->window;
  114.  
  115.   if (!host)                        /* if no host specified */
  116.     host = hostname;                /* use local host name */
  117.   if ((s->name = malloc(strlen(host)+1)) != NULLCHAR)
  118.     strcpy(s->name, host);
  119.  
  120.   s->type  = FINGER;
  121.   s->parse = NULLVFP;
  122.  
  123.   tcb = open_tcp(&lsocket, &fsocket, TCP_ACTIVE, 0,
  124.   (void(*)())fingcli_rcv, NULLVFP, (void(*)())f_state, 0, (char *)finger);
  125.  
  126.   finger->tcb = tcb;
  127.   tcb->user   = (char *) finger;
  128.   go(s);
  129.  
  130.   return 0;
  131. }
  132.  
  133. /* Allocate a finger structure for the new session */
  134. struct finger *alloc_finger(void)
  135. {
  136.   struct finger *tmp;
  137.  
  138.   if ((tmp = (struct finger *) malloc(sizeof(struct finger))) == NULLFING)
  139.     return(NULLFING);
  140.  
  141.   tmp->session = NULLSESSION;
  142.   tmp->user    = (char *) NULL;
  143.   tmp->window  =  NULL;
  144.   return(tmp);
  145. }
  146.  
  147. /*
  148.  *      Free a finger structure
  149.  */
  150. int free_finger(struct finger *finger)
  151. {
  152.   if (finger != NULLFING)
  153.   {
  154.     if (finger->session != NULLSESSION)
  155.       freesession(finger->session);
  156.     if (finger->user != (char *) NULL)
  157.       free(finger->user);
  158.     free(finger);
  159.   }
  160.   return 0;
  161. }
  162.  
  163. /* Finger receiver upcall routine */
  164. void fingcli_rcv(register struct tcb *tcb, int16 cnt)
  165. {
  166.   extern int    ttyflow;
  167.   struct finger *finger = (struct finger *)tcb->user;
  168.   struct mbuf   *bp;
  169.   register char *buf;
  170.   register char *s;
  171.   char *line;
  172.  
  173.   /* Make sure it's a valid finger session */
  174.   if (finger == NULLFING)
  175.   {
  176.     return;
  177.   }
  178.  
  179.   /* Hold output if we're not the current session */
  180.   if (finger->window == NULL && (mode != CONV_MODE || current == NULLSESSION
  181.       || current->type != FINGER || ttyflow == 0))
  182.     return;
  183.  
  184.   /* We process the incoming data stream and make sure it
  185.      meets our requirments.  A check is made for control-Zs
  186.      since these characters lock up DoubleDos when sent to
  187.      the console (don't you just love it...). */
  188.  
  189.   if (recv_tcp(tcb, &bp, cnt) > 0)
  190.   {
  191.     if ((line = s = malloc(len_mbuf(bp) + 1)) == NULL)
  192.     {
  193.       cwprintf(finger->window, "Out of memory in FINGCLI\r\n");
  194.       free_p(bp);
  195.       return;
  196.     }
  197.     while (bp != NULLBUF)
  198.     {
  199.       buf = bp->data;
  200.       while(bp->cnt--)
  201.       {
  202.         switch(*buf)
  203.         {
  204.     /*  case '\012': */   /* ignore LF */
  205.         case '\032':      /* NO ^Z's! */
  206.           break;
  207.     /*  case '\015':
  208.           *s++ = '\n';
  209.           break; */
  210.         default:
  211.           *s++ = *buf;
  212.           break;
  213.         }
  214.         buf++;
  215.       }
  216.       bp = free_mbuf(bp);
  217.     }
  218.     *s = '\0';
  219.     cwputs(finger->window, line);
  220.     free(line);
  221.   }
  222. }
  223.  
  224. /* State change upcall routine */
  225. void f_state(register struct tcb *tcb, char old, char new)
  226. {
  227.   struct finger   *finger;
  228.   char            notify = 0;
  229.   extern char     *tcpstates[];
  230.   extern char     *reasons[];
  231.   extern char     *unreach[];
  232.   extern char     *exceed[];
  233.   struct mbuf     *bp;
  234.  
  235.   old = old;
  236.  
  237.   finger = (struct finger *)tcb->user;
  238.  
  239.   if (finger->window || (current != NULLSESSION && current->type == FINGER))
  240.     notify = 1;
  241.  
  242.   switch(new)
  243.   {
  244.   case CLOSE_WAIT:
  245.     if (notify)
  246.       cwprintf(finger->window, "%s\r\n", tcpstates[new]);
  247.     close_tcp(tcb);
  248.     break;
  249.  
  250.   case CLOSED:    /* finish up */
  251.     if(notify)
  252.     {
  253.       cwprintf(finger->window, "%s (%s", tcpstates[new], reasons[tcb->reason]);
  254.       if (tcb->reason == NETWORK)
  255.       {
  256.         switch(tcb->type)
  257.         {
  258.         case DEST_UNREACH:
  259.           cwprintf(finger->window, ": %s unreachable", unreach[tcb->code]);
  260.           break;
  261.         case TIME_EXCEED:
  262.           cwprintf(finger->window, ": %s time exceeded", exceed[tcb->code]);
  263.           break;
  264.         }
  265.       }
  266.       cwprintf(finger->window, ")\r\n");
  267.       cmdmode();
  268.     }
  269.     if (finger != NULLFING)
  270.     {
  271.       if (finger->window)
  272.       {
  273.         finger->window->Attr = ATTR_REVERSE;
  274.         finger->window->Flags.flags.dont_destroy = FALSE;
  275.         finger->window->Session = NULL;
  276.         Window_CloseDown(finger->window);
  277.       }
  278.       free_finger(finger);
  279.     }
  280.     del_tcp(tcb);
  281.     break;
  282.   case ESTABLISHED:
  283.     if (notify)
  284.     {
  285.       cwprintf(finger->window, "%s\r\n", tcpstates[new]);
  286.     }
  287.     cwprintf(finger->window, "[%s]\r\n", finger->session->name);
  288.     bp = qdata(finger->user, (int16) strlen(finger->user));
  289.     send_tcp(tcb, bp);
  290.     break;
  291.  
  292.   default:
  293.     if (notify)
  294.       cwprintf(finger->window, "%s\r\n",tcpstates[new]);
  295.     break;
  296.   }
  297. }
  298.