/[inetutils]/inetutils/telnet/commands.c
ViewVC logotype

Diff of /inetutils/telnet/commands.c

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 1.17 by gray, Sun Aug 31 22:31:59 2003 UTC revision 1.18 by ams, Mon Jun 20 08:20:37 2005 UTC
# Line 27  Line 27 
27   * SUCH DAMAGE.   * SUCH DAMAGE.
28   */   */
29    
30  #ifndef lint  #if 0
31  static char sccsid[] = "@(#)commands.c  8.4 (Berkeley) 5/30/95";  static char sccsid[] = "@(#)commands.c  8.4 (Berkeley) 5/30/95";
32  #endif /* not lint */  #endif
33    
34  #ifdef HAVE_CONFIG_H  #ifdef HAVE_CONFIG_H
35  #include <config.h>  #include <config.h>
# Line 72  static char sccsid[] = "@(#)commands.c 8 Line 72  static char sccsid[] = "@(#)commands.c 8
72  #include <malloc.h>  #include <malloc.h>
73  #endif  #endif
74    
75    #include <arpa/inet.h>
76  #include <arpa/telnet.h>  #include <arpa/telnet.h>
77    
78  #include "general.h"  #include "general.h"
# Line 95  static char sccsid[] = "@(#)commands.c 8 Line 96  static char sccsid[] = "@(#)commands.c 8
96  #include <netinet/ip.h>  #include <netinet/ip.h>
97  #endif  #endif
98    
99  #if     defined(IPPROTO_IP) && defined(IP_TOS)  char    *hostname = 0;
 int tos = -1;  
 #endif  /* defined(IPPROTO_IP) && defined(IP_TOS) */  
   
 char    *hostname;  
 static char *_hostname = 0;  
100    
101  extern char *getenv __P((const char *));  extern char *getenv __P((const char *));
102    
# Line 2199  ayt_status() Line 2195  ayt_status()
2195  }  }
2196  #endif  #endif
2197    
 unsigned long inet_addr();  
   
2198  int  int
2199  tn(int argc, char *argv[])  tn(int argc, char *argv[])
2200  {  {
2201      register struct hostent *host = 0;  #ifdef IPV6
2202      struct sockaddr_in sin;    struct addrinfo *result, *aip, hints;
2203      struct servent *sp = 0;  #else
2204      unsigned long temp;    struct hostent *host = 0;
2205      extern char *inet_ntoa();    struct sockaddr_in sin;
2206  #if     defined(IP_OPTIONS) && defined(IPPROTO_IP)    struct servent *sp = 0;
2207      char *srp = 0;    in_addr_t temp;
2208  #ifndef strrchr  #endif
2209      char *strrchr();    const int on = 1;
2210  #endif    int err;
2211      unsigned long sourceroute(), srlen;    char *cmd, *hostp = 0, *portp = 0, *user = 0;
 #endif  
     char *cmd, *hostp = 0, *portp = 0, *user = 0;  
   
     /* clear the socket address prior to use */  
     memset((char *)&sin, 0, sizeof(sin));  
2212    
2213      if (connected) {  #ifdef IPV6
2214          printf("?Already connected to %s\n", hostname);    memset (&hints, 0, sizeof (hints));
2215          setuid(getuid());  #else
2216          return 0;    /* clear the socket address prior to use */
2217      }    memset ((char *)&sin, 0, sizeof(sin));
2218      if (argc < 2) {  #endif
2219          (void) strcpy(line, "open ");    
2220          printf("(to) ");    if (connected)
2221          (void) fgets(&line[strlen(line)], sizeof(line) - strlen(line), stdin);      {
2222          makeargv();        printf("?Already connected to %s\n", hostname);
2223          argc = margc;        return 0;
         argv = margv;  
2224      }      }
2225      cmd = *argv;    if (argc < 2)
2226      --argc; ++argv;      {
2227      while (argc) {        (void) strcpy(line, "open ");
2228          if (strcmp(*argv, "help") == 0 || isprefix(*argv, "?"))        printf("(to) ");
2229          (void) fgets(&line[strlen(line)], sizeof(line) - strlen(line), stdin);
2230          makeargv();
2231          argc = margc;
2232          argv = margv;
2233        }
2234      cmd = *argv;
2235      --argc; ++argv;
2236      while (argc)
2237        {
2238          if (strcmp(*argv, "help") == 0 || isprefix(*argv, "?"))
2239            goto usage;
2240          if (strcmp(*argv, "-l") == 0)
2241            {
2242              --argc; ++argv;
2243              if (argc == 0)
2244              goto usage;              goto usage;
2245          if (strcmp(*argv, "-l") == 0) {            user = *argv++;
2246              --argc; ++argv;            --argc;
2247              if (argc == 0)            continue;
                 goto usage;  
             user = *argv++;  
             --argc;  
             continue;  
2248          }          }
2249          if (strcmp(*argv, "-a") == 0) {        if (strcmp(*argv, "-a") == 0)
2250              --argc; ++argv;          {
2251              autologin = 1;            --argc; ++argv;
2252              continue;            autologin = 1;
2253              continue;
2254          }          }
2255          if (hostp == 0) {        if (strcmp(*argv, "-6") == 0)
2256              hostp = *argv++;          {
2257              --argc;            --argc; ++argv;
2258              continue;  #ifdef IPV6
2259              hints.ai_family = AF_INET6;
2260    #else
2261              puts ("IPv6 isn't supported");
2262    #endif
2263              continue;
2264          }          }
2265          if (portp == 0) {        if (strcmp(*argv, "-4") == 0)
2266              portp = *argv++;          {
2267              --argc;            --argc; ++argv;
2268              continue;  #ifdef IPV6
2269              hints.ai_family = AF_INET;
2270    #endif
2271              continue;
2272            }
2273          if (hostp == 0)
2274            {
2275              hostp = *argv++;
2276              --argc;
2277              continue;
2278            }
2279          if (portp == 0)
2280            {
2281              portp = *argv++;
2282              --argc;
2283              continue;
2284          }          }
2285      usage:      usage:
2286          printf("usage: %s [-l user] [-a] host-name [port]\n", cmd);        printf("usage: %s [-4] [-6] [-l user] [-a] host-name [port]\n", cmd);
2287          setuid(getuid());        return 0;
         return 0;  
2288      }      }
2289      if (hostp == 0)    if (hostp == 0)
2290          goto usage;      goto usage;
2291    
2292  #if     defined(IP_OPTIONS) && defined(IPPROTO_IP)    if (!portp)
2293      if (hostp[0] == '@' || hostp[0] == '!') {      {
2294          if ((hostname = strrchr(hostp, ':')) == NULL)        portp = "telnet";
2295              hostname = strrchr(hostp, '@');        telnetport = 1;
2296          hostname++;      }
2297          srp = 0;    else
2298          temp = sourceroute(hostp, &srp, &srlen);      {
2299          if (temp == 0) {        if (*portp == '-')
2300              herror(srp);          {
2301              setuid(getuid());            portp++;
2302              return 0;            telnetport = 1;
         } else if (temp == -1) {  
             printf("Bad source route option: %s\n", hostp);  
             setuid(getuid());  
             return 0;  
         } else {  
             sin.sin_addr.s_addr = temp;  
             sin.sin_family = AF_INET;  
2303          }          }
2304      } else {        else
2305            telnetport = 0;
2306        }
2307    
2308      if (hostname)
2309        free (hostname);
2310      hostname = malloc (strlen (hostp) + 1);
2311      if (hostname)
2312        strcpy (hostname, hostp);
2313      else
2314        {
2315          printf ("Can't allocate memory to copy hostname\n");
2316          return 0;
2317        }
2318    
2319    #ifdef IPV6
2320    #ifdef AI_ADDRCONFIG
2321      hints.ai_flags = AI_ADDRCONFIG;
2322  #endif  #endif
2323          temp = inet_addr(hostp);    hints.ai_socktype = SOCK_STREAM;
         if (temp != (unsigned long) -1) {  
             sin.sin_addr.s_addr = temp;  
             sin.sin_family = AF_INET;  
2324    
2325          } else {    err = getaddrinfo (hostp, portp, &hints, &result);
2326              host = gethostbyname(hostp);    if (err)
2327              if (host) {      {
2328                  sin.sin_family = host->h_addrtype;        const char *errmsg;
2329  #if     defined(h_addr)         /* In 4.3, this is a #define */  
2330                  memmove((caddr_t)&sin.sin_addr,        if (err == EAI_SYSTEM)
2331                                  host->h_addr_list[0], host->h_length);          errmsg = strerror (errno);
2332  #else   /* defined(h_addr) */        else
2333                  memmove((caddr_t)&sin.sin_addr, host->h_addr, host->h_length);          errmsg = gai_strerror (err);
2334  #endif  /* defined(h_addr) */        
2335          printf ("%s/%s: lookup failure: %s\n", hostp, portp, errmsg);
2336          return 0;
2337        }
2338    
2339      aip = result;
2340    
2341      do
2342        {
2343          char buf[256];
2344    
2345          err = getnameinfo (aip->ai_addr, aip->ai_addrlen, buf, sizeof (buf),
2346                             NULL, 0, NI_NUMERICHOST);
2347          if (err)
2348            {
2349              /* I don't know how thing can happen, but we just handle it.  */
2350              const char *errmsg;
2351              
2352              if (err == EAI_SYSTEM)
2353                errmsg = strerror (errno);
2354              else
2355                errmsg = gai_strerror (err);
2356              
2357              printf ("getnameinfo error: %s\n", errmsg);
2358              return 0;
2359            }
2360          
2361          printf ("Trying %s...\n", buf);
2362    
2363          net = socket (aip->ai_family, SOCK_STREAM, 0);
2364          if (net < 0)
2365            {
2366              perror("telnet: socket");
2367              return 0;
2368            }
2369    
2370          if (debug)
2371            {
2372              err = setsockopt (net, SOL_SOCKET, SO_DEBUG, &on, sizeof(on));
2373              if (err < 0)
2374                perror("setsockopt (SO_DEBUG)");
2375            }
2376    
2377          err = connect (net, (struct sockaddr *)aip->ai_addr, aip->ai_addrlen);
2378          if (err < 0)
2379            {
2380              if (aip->ai_next)
2381                {
2382                  perror ("Connection failed");
2383                  aip = aip->ai_next;
2384                  close (net);
2385                  continue;
2386              }              }
2387                
2388              perror("telnet: Unable to connect to remote host");
2389              return 0;
2390          }          }
2391          if (_hostname)        
2392                  free (_hostname);        connected++;
2393          _hostname = malloc (strlen (hostp) + 1);  #if     defined(AUTHENTICATION) || defined(ENCRYPTION)
2394          if (_hostname) {        auth_encrypt_connect(connected);
2395                  strcpy (_hostname, hostp);  #endif  /* defined(AUTHENTICATION) || defined(ENCRYPTION) */
2396                  hostname = _hostname;      } while (!connected);
2397          } else {  
2398                  printf ("Can't allocate memory to copy hostname\n");    freeaddrinfo (result);
2399                  setuid(getuid());  #else /* !IPV6 */
2400                  return 0;    temp = inet_addr (hostp);
2401          }    if (temp != (in_addr_t) -1)
2402  #if     defined(IP_OPTIONS) && defined(IPPROTO_IP)      {
2403          sin.sin_addr.s_addr = temp;
2404          sin.sin_family = AF_INET;
2405      }      }
2406  #endif    else
2407      if (portp) {      {
2408          if (*portp == '-') {        host = gethostbyname (hostp);
2409              portp++;        if (host)
2410              telnetport = 1;          {
2411          } else            sin.sin_family = host->h_addrtype;
2412              telnetport = 0;            memmove (&sin.sin_addr, host->h_addr_list[0], host->h_length);
         sin.sin_port = atoi(portp);  
         if (sin.sin_port == 0) {  
             sp = getservbyname(portp, "tcp");  
             if (sp)  
                 sin.sin_port = sp->s_port;  
             else {  
                 printf("%s: bad port number\n", portp);  
                 setuid(getuid());  
                 return 0;  
             }  
         } else {  
 #if !HAVE_DECL_HTONS  
 #ifndef htons  
             u_short htons __P((unsigned short));  
 #endif  
 #endif  
             sin.sin_port = htons (sin.sin_port);  
2413          }          }
2414      } else {        else
2415          if (sp == 0) {          {
2416              sp = getservbyname("telnet", "tcp");            printf ("Can't lookup hostname %s\n", hostp);
2417              if (sp == 0) {            return 0;
                 fprintf(stderr, "telnet: tcp/telnet: unknown service\n");  
                 setuid(getuid());  
                 return 0;  
             }  
             sin.sin_port = sp->s_port;  
2418          }          }
         telnetport = 1;  
2419      }      }
2420      printf("Trying %s...\n", inet_ntoa(sin.sin_addr));    
2421      do {    sin.sin_port = atoi (portp);
2422          net = socket(AF_INET, SOCK_STREAM, 0);    if (sin.sin_port == 0)
2423          setuid(getuid());      {
2424          if (net < 0) {        sp = getservbyname (portp, "tcp");
2425              perror("telnet: socket");        if (sp == 0)
2426              return 0;          {
2427              printf ("tcp/%s: unknown service\n", portp);
2428              return 0;
2429          }          }
2430  #if     defined(IP_OPTIONS) && defined(IPPROTO_IP)        sin.sin_port = sp->s_port;
2431          if (srp && setsockopt(net, IPPROTO_IP, IP_OPTIONS, (char *)srp, srlen) < 0)      }
2432                  perror("setsockopt (IP_OPTIONS)");    else
2433  #endif      sin.sin_port = htons (sin.sin_port);
2434  #if     defined(IPPROTO_IP) && defined(IP_TOS)    
2435      printf("Trying %s...\n", inet_ntoa(sin.sin_addr));
2436      do
2437        {
2438          net = socket(AF_INET, SOCK_STREAM, 0);
2439          if (net < 0)
2440          {          {
2441  # if    defined(HAS_GETTOS)            perror("telnet: socket");
2442              struct tosent *tp;            return 0;
             if (tos < 0 && (tp = gettosbyname("telnet", "tcp")))  
                 tos = tp->t_tos;  
 # endif  
             if (tos < 0)  
                 tos = 020;      /* Low Delay bit */  
             if (tos  
                 && (setsockopt(net, IPPROTO_IP, IP_TOS,  
                     (char *)&tos, sizeof(int)) < 0)  
                 && (errno != ENOPROTOOPT))  
                     perror("telnet: setsockopt (IP_TOS) (ignored)");  
2443          }          }
2444    #if defined(IPPROTO_IP) && defined(IP_TOS)
2445          {
2446    #ifdef IPTOS_LOWDELAY
2447            const int tos = IPTOS_LOWDELAY;
2448    #else
2449            const int tos = 0x10;
2450    #endif
2451    
2452            err = setsockopt (net, IPPROTO_IP, IP_TOS,
2453                              (char *)&tos, sizeof(tos));
2454            if (err < 0 && errno != ENOPROTOOPT)
2455              perror("telnet: setsockopt (IP_TOS) (ignored)");
2456          }
2457  #endif  /* defined(IPPROTO_IP) && defined(IP_TOS) */  #endif  /* defined(IPPROTO_IP) && defined(IP_TOS) */
2458    
2459          if (debug && SetSockOpt(net, SOL_SOCKET, SO_DEBUG, 1) < 0) {        if (debug && setsockopt(net, SOL_SOCKET, SO_DEBUG, &on, sizeof(on)) < 0)
2460                  perror("setsockopt (SO_DEBUG)");          perror("setsockopt (SO_DEBUG)");
         }  
2461    
2462          if (connect(net, (struct sockaddr *)&sin, sizeof (sin)) < 0) {        if (connect(net, (struct sockaddr *)&sin, sizeof (sin)) < 0)
2463  #if     defined(h_addr)         /* In 4.3, this is a #define */          {
2464              if (host && host->h_addr_list[1]) {            if (host && host->h_addr_list[1])
2465                  int oerrno = errno;              {
2466                  int oerrno = errno;
2467                  fprintf(stderr, "telnet: connect to address %s: ",  
2468                                                  inet_ntoa(sin.sin_addr));                fprintf(stderr, "telnet: connect to address %s: ",
2469                  errno = oerrno;                        inet_ntoa(sin.sin_addr));
2470                  perror((char *)0);                errno = oerrno;
2471                  host->h_addr_list++;                perror((char *)0);
2472                  memmove((caddr_t)&sin.sin_addr,                host->h_addr_list++;
2473                          host->h_addr_list[0], host->h_length);                memmove((caddr_t)&sin.sin_addr,
2474                  (void) NetClose(net);                        host->h_addr_list[0], host->h_length);
2475                  continue;                close (net);
2476                  continue;
2477              }              }
2478  #endif  /* defined(h_addr) */            perror("telnet: Unable to connect to remote host");
2479              perror("telnet: Unable to connect to remote host");            return 0;
             return 0;  
2480          }          }
2481          connected++;        connected++;
2482  #if     defined(AUTHENTICATION) || defined(ENCRYPTION)  #if     defined(AUTHENTICATION) || defined(ENCRYPTION)
2483          auth_encrypt_connect(connected);        auth_encrypt_connect(connected);
2484  #endif  /* defined(AUTHENTICATION) || defined(ENCRYPTION) */  #endif  /* defined(AUTHENTICATION) || defined(ENCRYPTION) */
2485      } while (connected == 0);      } while (connected == 0);
2486      cmdrc(hostp, hostname);  #endif /* !IPV6 */
2487      if (autologin && user == NULL) {    cmdrc(hostp, hostname);
2488          struct passwd *pw;    if (autologin && user == NULL)
2489        {
2490          user = getenv("USER");        struct passwd *pw;
2491          if (user == NULL ||  
2492              (pw = getpwnam(user)) && pw->pw_uid != getuid()) {        user = getenv("USER");
2493                  if (pw = getpwuid(getuid()))        if (user == NULL ||
2494                          user = pw->pw_name;            (pw = getpwnam(user)) && pw->pw_uid != getuid())
2495                  else          {
2496                          user = NULL;            if (pw = getpwuid(getuid()))
2497                user = pw->pw_name;
2498              else
2499                user = NULL;
2500          }          }
2501      }      }
2502      if (user) {    if (user)
2503          env_define((unsigned char *)"USER", (unsigned char *)user);      {
2504          env_export((unsigned char *)"USER");        env_define((unsigned char *)"USER", (unsigned char *)user);
2505          env_export((unsigned char *)"USER");
2506      }      }
2507      (void) call(status, "status", "notmuch", 0);    (void) call(status, "status", "notmuch", 0);
2508      if (setjmp(peerdied) == 0)    if (setjmp(peerdied) == 0)
2509          telnet(user);      telnet(user);
2510      (void) NetClose(net);  
2511      ExitString("Connection closed by foreign host.\n",1);    close (net);
2512      /*NOTREACHED*/    ExitString("Connection closed by foreign host.\n",1);
2513      /*NOTREACHED*/
2514    
2515      return 0;
2516  }  }
2517    
2518  #define HELPINDENT (sizeof ("connect"))  #define HELPINDENT (sizeof ("connect"))
# Line 2755  cmdrc(char *m1, char *m2) Line 2829  cmdrc(char *m1, char *m2)
2829      }      }
2830      fclose(rcfile);      fclose(rcfile);
2831  }  }
   
 #if     defined(IP_OPTIONS) && defined(IPPROTO_IP)  
   
 /*  
  * Source route is handed in as  
  *      [!]@hop1@hop2...[@|:]dst  
  * If the leading ! is present, it is a  
  * strict source route, otherwise it is  
  * assmed to be a loose source route.  
  *  
  * We fill in the source route option as  
  *      hop1,hop2,hop3...dest  
  * and return a pointer to hop1, which will  
  * be the address to connect() to.  
  *  
  * Arguments:  
  *      arg:    pointer to route list to decipher  
  *  
  *      cpp:    If *cpp is not equal to NULL, this is a  
  *              pointer to a pointer to a character array  
  *              that should be filled in with the option.  
  *  
  *      lenp:   pointer to an integer that contains the  
  *              length of *cpp if *cpp != NULL.  
  *  
  * Return values:  
  *  
  *      Returns the address of the host to connect to.  If the  
  *      return value is -1, there was a syntax error in the  
  *      option, either unknown characters, or too many hosts.  
  *      If the return value is 0, one of the hostnames in the  
  *      path is unknown, and *cpp is set to point to the bad  
  *      hostname.  
  *  
  *      *cpp:   If *cpp was equal to NULL, it will be filled  
  *              in with a pointer to our static area that has  
  *              the option filled in.  This will be 32bit aligned.  
  *  
  *      *lenp:  This will be filled in with how long the option  
  *              pointed to by *cpp is.  
  *  
  */  
 unsigned long  
 sourceroute(char *arg, char **cpp, int *lenp)  
 {  
         static char lsr[44];  
 #ifdef  sysV88  
         static IOPTN ipopt;  
 #endif  
         char *cp, *cp2, *lsrp, *lsrep;  
         register int tmp;  
         struct in_addr sin_addr;  
         register struct hostent *host = 0;  
         register char c;  
   
         /*  
          * Verify the arguments, and make sure we have  
          * at least 7 bytes for the option.  
          */  
         if (cpp == NULL || lenp == NULL)  
                 return((unsigned long)-1);  
         if (*cpp != NULL && *lenp < 7)  
                 return((unsigned long)-1);  
         /*  
          * Decide whether we have a buffer passed to us,  
          * or if we need to use our own static buffer.  
          */  
         if (*cpp) {  
                 lsrp = *cpp;  
                 lsrep = lsrp + *lenp;  
         } else {  
                 *cpp = lsrp = lsr;  
                 lsrep = lsrp + 44;  
         }  
   
         cp = arg;  
   
         /*  
          * Next, decide whether we have a loose source  
          * route or a strict source route, and fill in  
          * the begining of the option.  
          */  
 #ifndef sysV88  
         if (*cp == '!') {  
                 cp++;  
                 *lsrp++ = IPOPT_SSRR;  
         } else  
                 *lsrp++ = IPOPT_LSRR;  
 #else  
         if (*cp == '!') {  
                 cp++;  
                 ipopt.io_type = IPOPT_SSRR;  
         } else  
                 ipopt.io_type = IPOPT_LSRR;  
 #endif  
   
         if (*cp != '@')  
                 return((unsigned long)-1);  
   
 #ifndef sysV88  
         lsrp++;         /* skip over length, we'll fill it in later */  
         *lsrp++ = 4;  
 #endif  
   
         cp++;  
   
         sin_addr.s_addr = 0;  
   
         for (c = 0;;) {  
                 if (c == ':')  
                         cp2 = 0;  
                 else for (cp2 = cp; c = *cp2; cp2++) {  
                         if (c == ',') {  
                                 *cp2++ = '\0';  
                                 if (*cp2 == '@')  
                                         cp2++;  
                         } else if (c == '@') {  
                                 *cp2++ = '\0';  
                         } else if (c == ':') {  
                                 *cp2++ = '\0';  
                         } else  
                                 continue;  
                         break;  
                 }  
                 if (!c)  
                         cp2 = 0;  
   
                 if ((tmp = inet_addr(cp)) != -1) {  
                         sin_addr.s_addr = tmp;  
                 } else if (host = gethostbyname(cp)) {  
 #if     defined(h_addr)  
                         memmove((caddr_t)&sin_addr,  
                                 host->h_addr_list[0], host->h_length);  
 #else  
                         memmove((caddr_t)&sin_addr, host->h_addr, host->h_length);  
 #endif  
                 } else {  
                         *cpp = cp;  
                         return(0);  
                 }  
                 memmove(lsrp, (char *)&sin_addr, 4);  
                 lsrp += 4;  
                 if (cp2)  
                         cp = cp2;  
                 else  
                         break;  
                 /*  
                  * Check to make sure there is space for next address  
                  */  
                 if (lsrp + 4 > lsrep)  
                         return((unsigned long)-1);  
         }  
 #ifndef sysV88  
         if ((*(*cpp+IPOPT_OLEN) = lsrp - *cpp) <= 7) {  
                 *cpp = 0;  
                 *lenp = 0;  
                 return((unsigned long)-1);  
         }  
         *lsrp++ = IPOPT_NOP; /* 32 bit word align it */  
         *lenp = lsrp - *cpp;  
 #else  
         ipopt.io_len = lsrp - *cpp;  
         if (ipopt.io_len <= 5) {                /* Is 3 better ? */  
                 *cpp = 0;  
                 *lenp = 0;  
                 return((unsigned long)-1);  
         }  
         *lenp = sizeof(ipopt);  
         *cpp = (char *) &ipopt;  
 #endif  
         return(sin_addr.s_addr);  
 }  
 #endif  

Legend:
Removed from v.1.17  
changed lines
  Added in v.1.18

savannah-hackers-public@gnu.org
ViewVC Help
Powered by ViewVC 1.1.26