/[inetutils]/inetutils/tftp/main.c
ViewVC logotype

Diff of /inetutils/tftp/main.c

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

revision 1.9 by marcus, Fri Nov 2 21:50:13 2001 UTC revision 1.10 by gray, Thu Sep 23 08:51:29 2004 UTC
# Line 28  Line 28 
28   */   */
29    
30  #ifndef lint  #ifndef lint
31  static char copyright[] =  static char     copyright[] = "@(#) Copyright (c) 1983, 1993\n\
 "@(#) Copyright (c) 1983, 1993\n\  
32          The Regents of the University of California.  All rights reserved.\n";          The Regents of the University of California.  All rights reserved.\n";
33  #endif /* not lint */  #endif /* not lint */
34    
35  #ifndef lint  #ifndef lint
36  static char sccsid[] = "@(#)main.c      8.1 (Berkeley) 6/6/93";  static char     sccsid[] = "@(#)main.c  8.1 (Berkeley) 6/6/93";
37  #endif /* not lint */  #endif /* not lint */
38    
39  /* Many bug fixes are from Jim Guyton <guyton@rand-unix> */  /* Many bug fixes are from Jim Guyton <guyton@rand-unix> */
# Line 66  static char sccsid[] = "@(#)main.c     8.1 ( Line 65  static char sccsid[] = "@(#)main.c     8.1 (
65  #include <string.h>  #include <string.h>
66  #include <unistd.h>  #include <unistd.h>
67    
68    #include <xalloc.h>
69  #include "extern.h"  #include "extern.h"
70    
71  #define TIMEOUT         5               /* secs between rexmt's */  #define TIMEOUT         5       /* secs between rexmt's */
72    
73  struct  sockaddr_in peeraddr;  struct sockaddr_in peeraddr;
74  int     f;  int             f;
75  short   port;  short           port;
76  int     trace;  int             trace;
77  int     verbose;  int             verbose;
78  int     connected;  int             connected;
79  char    mode[32];  char            mode[32];
80  char    line[200];  char            line[200];
81  int     margc;  int             margc;
82  char    *margv[20];  char           *margv[20];
83  char    *prompt = "tftp";  char           *prompt = "tftp";
84  jmp_buf toplevel;  jmp_buf         toplevel;
85  void    intr();  void            intr ();
86  struct  servent *sp;  struct servent *sp;
87    
88  void    get __P((int, char **));  void get        __P ((int, char **));
89  void    help __P((int, char **));  void help       __P ((int, char **));
90  void    modecmd __P((int, char **));  void modecmd    __P ((int, char **));
91  void    put __P((int, char **));  void put        __P ((int, char **));
92  void    quit __P((int, char **));  void quit       __P ((int, char **));
93  void    setascii __P((int, char **));  void setascii   __P ((int, char **));
94  void    setbinary __P((int, char **));  void setbinary  __P ((int, char **));
95  void    setpeer __P((int, char **));  void setpeer    __P ((int, char **));
96  void    setrexmt __P((int, char **));  void setrexmt   __P ((int, char **));
97  void    settimeout __P((int, char **));  void settimeout __P ((int, char **));
98  void    settrace __P((int, char **));  void settrace   __P ((int, char **));
99  void    setverbose __P((int, char **));  void setverbose __P ((int, char **));
100  void    status __P((int, char **));  void status     __P ((int, char **));
101    
102  static void command __P((void));  static void command __P ((void));
103    
104  static void getusage __P((char *));  static void getusage __P ((char *));
105  static void makeargv __P((void));  static void makeargv __P ((void));
106  static void putusage __P((char *));  static void putusage __P ((char *));
107  static void settftpmode __P((char *));  static void settftpmode __P ((char *));
108    
109  #define HELPINDENT (sizeof("connect"))  #define HELPINDENT (sizeof("connect"))
110    
111  struct cmd {  struct cmd
112          char    *name;  {
113          char    *help;    char           *name;
114          void    (*handler) __P((int, char **));    char           *help;
115      void            (*handler) __P ((int, char **));
116  };  };
117    
118  char    vhelp[] = "toggle verbose mode";  char            vhelp[] = "toggle verbose mode";
119  char    thelp[] = "toggle packet tracing";  char            thelp[] = "toggle packet tracing";
120  char    chelp[] = "connect to remote tftp";  char            chelp[] = "connect to remote tftp";
121  char    qhelp[] = "exit tftp";  char            qhelp[] = "exit tftp";
122  char    hhelp[] = "print help information";  char            hhelp[] = "print help information";
123  char    shelp[] = "send file";  char            shelp[] = "send file";
124  char    rhelp[] = "receive file";  char            rhelp[] = "receive file";
125  char    mhelp[] = "set file transfer mode";  char            mhelp[] = "set file transfer mode";
126  char    sthelp[] = "show current status";  char            sthelp[] = "show current status";
127  char    xhelp[] = "set per-packet retransmission timeout";  char            xhelp[] = "set per-packet retransmission timeout";
128  char    ihelp[] = "set total retransmission timeout";  char            ihelp[] = "set total retransmission timeout";
129  char    ashelp[] = "set mode to netascii";  char            ashelp[] = "set mode to netascii";
130  char    bnhelp[] = "set mode to octet";  char            bnhelp[] = "set mode to octet";
131    
132  struct cmd cmdtab[] = {  struct cmd      cmdtab[] = {
133          { "connect",    chelp,          setpeer },    {"connect", chelp, setpeer},
134          { "mode",       mhelp,          modecmd },    {"mode", mhelp, modecmd},
135          { "put",        shelp,          put },    {"put", shelp, put},
136          { "get",        rhelp,          get },    {"get", rhelp, get},
137          { "quit",       qhelp,          quit },    {"quit", qhelp, quit},
138          { "verbose",    vhelp,          setverbose },    {"verbose", vhelp, setverbose},
139          { "trace",      thelp,          settrace },    {"trace", thelp, settrace},
140          { "status",     sthelp,         status },    {"status", sthelp, status},
141          { "binary",     bnhelp,         setbinary },    {"binary", bnhelp, setbinary},
142          { "ascii",      ashelp,         setascii },    {"ascii", ashelp, setascii},
143          { "rexmt",      xhelp,          setrexmt },    {"rexmt", xhelp, setrexmt},
144          { "timeout",    ihelp,          settimeout },    {"timeout", ihelp, settimeout},
145          { "?",          hhelp,          help },    {"?", hhelp, help},
146          { 0 }    {0}
147  };  };
148    
149  struct  cmd *getcmd();  struct cmd     *getcmd ();
150  char    *tail();  char           *tail ();
151    
152  int  int
153  main(argc, argv)  main (int argc, char *argv[])
154          int argc;  {
155          char *argv[];    struct sockaddr_in sin;
 {  
         struct sockaddr_in sin;  
   
         sp = getservbyname("tftp", "udp");  
         if (sp == 0) {  
                 fprintf(stderr, "tftp: udp/tftp: unknown service\n");  
                 exit(1);  
         }  
         f = socket(AF_INET, SOCK_DGRAM, 0);  
         if (f < 0) {  
                 perror("tftp: socket");  
                 exit(3);  
         }  
         bzero((char *)&sin, sizeof(sin));  
         sin.sin_family = AF_INET;  
         if (bind(f, (struct sockaddr *)&sin, sizeof(sin)) < 0) {  
                 perror("tftp: bind");  
                 exit(1);  
         }  
         strcpy(mode, "netascii");  
         signal(SIGINT, intr);  
         if (argc > 1) {  
                 if (setjmp(toplevel) != 0)  
                         exit(0);  
                 setpeer(argc, argv);  
         }  
         if (setjmp(toplevel) != 0)  
                 (void)putchar('\n');  
         command();  
 }  
156    
157  char    hostname[100];    sp = getservbyname ("tftp", "udp");
158      if (sp == 0)
159        {
160          fprintf (stderr, "tftp: udp/tftp: unknown service\n");
161          exit (1);
162        }
163      f = socket (AF_INET, SOCK_DGRAM, 0);
164      if (f < 0)
165        {
166          perror ("tftp: socket");
167          exit (3);
168        }
169      memset (&sin, 0, sizeof (sin));
170      sin.sin_family = AF_INET;
171      if (bind (f, (struct sockaddr *) &sin, sizeof (sin)) < 0)
172        {
173          perror ("tftp: bind");
174          exit (1);
175        }
176      strcpy (mode, "netascii");
177      signal (SIGINT, intr);
178      if (argc > 1)
179        {
180          if (setjmp (toplevel) != 0)
181            exit (0);
182          setpeer (argc, argv);
183        }
184      if (setjmp (toplevel) != 0)
185        (void) putchar ('\n');
186      command ();
187    }
188    
189    char *hostname;
190    
191    #define RESOLVE_OK            0
192    #define RESOLVE_FAIL         -1
193    #define RESOLVE_NOT_RESOLVED  1
194    
195    /* Resolve NAME. Fill in peeraddr, hostname and set connected on success.
196       Return value: RESOLVE_OK success
197                     RESOLVE_FAIL error
198                     RESOLVE_NOT_RESOLVED name is not resolved and ALLOW_NULL
199                     is true */
200    static int
201    resolve_name (char *name, int allow_null)
202    {
203      struct hostent *hp = gethostbyname (name);
204      if (hp == NULL)
205        {
206          if (allow_null)
207            return RESOLVE_NOT_RESOLVED;
208          fprintf (stderr, "tftp: %s: ", name);
209          herror ((char *) NULL);
210          return RESOLVE_FAIL;
211        }
212      else if (hp->h_length != sizeof peeraddr.sin_addr)
213        {
214          fprintf (stderr, "tftp: resolving %s returns unexpected length", name);
215          return RESOLVE_FAIL;
216        }
217      memcpy (&peeraddr.sin_addr, hp->h_addr, hp->h_length);
218      peeraddr.sin_family = hp->h_addrtype;
219      connected = 1;
220      free (hostname);
221      hostname = xstrdup (hp->h_name);
222      return RESOLVE_OK;
223    }
224    
225  /* Prompt for more arguments from the user with PROMPT, putting the results  /* Prompt for more arguments from the user with PROMPT, putting the results
226     into ARGC & ARGV, with an initial argument of ARG0.  Global variables     into ARGC & ARGV, with an initial argument of ARG0.  Global variables
227     LINE, MARGC, and MARGV are changed.  */     LINE, MARGC, and MARGV are changed.  */
228  static void  static void
229  get_args (arg0, prompt, argc, argv)  get_args (char *arg0, char *prompt, int *argc, char ***argv)
      char *arg0, *prompt;  
      int *argc;  
      char ***argv;  
230  {  {
231    size_t arg0_len = strlen (arg0);    size_t arg0_len = strlen (arg0);
232    
233    strcpy (line, arg0);    strcpy (line, arg0);
234    strcat (line, " ");    strcat (line, " ");
235    
236    printf("%s", prompt);    printf ("%s", prompt);
237    fgets (line + arg0_len + 1, sizeof line - arg0_len - 1, stdin);    fgets (line + arg0_len + 1, sizeof line - arg0_len - 1, stdin);
238    
239    makeargv();    makeargv ();
240    *argc = margc;    *argc = margc;
241    *argv = margv;    *argv = margv;
242  }  }
243    
244  void  void
245  setpeer(argc, argv)  setpeer (int argc, char *argv[])
246          int argc;  {
247          char *argv[];    if (argc < 2)
248  {      get_args ("Connect", "(to) ", &argc, &argv);
249          struct hostent *host;  
250      if (argc < 2 || argc > 3)
251          if (argc < 2)      {
252            get_args ("Connect", "(to) ", &argc, &argv);        printf ("usage: %s host-name [port]\n", argv[0]);
253          return;
254          if (argc > 3) {      }
255                  printf("usage: %s host-name [port]\n", argv[0]);    
256                  return;    switch (resolve_name (argv[1], 1))
257          }      {
258          host = gethostbyname(argv[1]);      case RESOLVE_OK:
259          if (host) {        break;
260                  peeraddr.sin_family = host->h_addrtype;  
261                  bcopy(host->h_addr, &peeraddr.sin_addr, host->h_length);      case RESOLVE_FAIL:
262                  strcpy(hostname, host->h_name);        return;
263          } else {        
264                  peeraddr.sin_family = AF_INET;      case RESOLVE_NOT_RESOLVED:
265                  peeraddr.sin_addr.s_addr = inet_addr(argv[1]);        peeraddr.sin_family = AF_INET;
266                  if (peeraddr.sin_addr.s_addr == -1) {        peeraddr.sin_addr.s_addr = inet_addr (argv[1]);
267                          connected = 0;        if (peeraddr.sin_addr.s_addr == -1)
268                          printf("%s: unknown host\n", argv[1]);          {
269                          return;            connected = 0;
270                  }            printf ("%s: unknown host\n", argv[1]);
271                  strcpy(hostname, argv[1]);            return;
272          }          }
273          port = sp->s_port;        hostname = xstrdup (argv[1]);
274          if (argc == 3) {      }
275                  port = atoi(argv[2]);    
276                  if (port < 0) {    port = sp->s_port;
277                          printf("%s: bad port number\n", argv[2]);    if (argc == 3)
278                          connected = 0;      {
279                          return;        port = atoi (argv[2]);
280                  }        if (port < 0)
281                  port = htons(port);          {
282          }            printf ("%s: bad port number\n", argv[2]);
283          connected = 1;            connected = 0;
284  }            return;
285            }
286  struct  modes {        port = htons (port);
287          char *m_name;      }
288          char *m_mode;    connected = 1;
289  } modes[] = {  }
290          { "ascii",      "netascii" },  
291          { "netascii",   "netascii" },  struct modes
292          { "binary",     "octet" },  {
293          { "image",      "octet" },    char           *m_name;
294          { "octet",     "octet" },    char           *m_mode;
295    }
296    modes[] =
297    {
298      {"ascii", "netascii"},
299      {"netascii", "netascii"},
300      {"binary", "octet"},
301      {"image", "octet"},
302      {"octet", "octet"},
303  /*      { "mail",       "mail" },       */  /*      { "mail",       "mail" },       */
304          { 0,            0 }    {0, 0}
305  };  };
306    
307  void  void
308  modecmd(argc, argv)  modecmd (int argc, char *argv[])
309          int argc;  {
310          char *argv[];    register struct modes *p;
311  {    char *sep;
312          register struct modes *p;  
313          char *sep;    if (argc < 2)
314        {
315          if (argc < 2) {        printf ("Using %s mode to transfer files.\n", mode);
316                  printf("Using %s mode to transfer files.\n", mode);        return;
317                  return;      }
318          }    if (argc == 2)
319          if (argc == 2) {      {
320                  for (p = modes; p->m_name; p++)        for (p = modes; p->m_name; p++)
321                          if (strcmp(argv[1], p->m_name) == 0)          if (strcmp (argv[1], p->m_name) == 0)
322                                  break;            break;
323                  if (p->m_name) {        if (p->m_name)
324                          settftpmode(p->m_mode);          {
325                          return;            settftpmode (p->m_mode);
326                  }            return;
                 printf("%s: unknown mode\n", argv[1]);  
                 /* drop through and print usage message */  
         }  
   
         printf("usage: %s [", argv[0]);  
         sep = " ";  
         for (p = modes; p->m_name; p++) {  
                 printf("%s%s", sep, p->m_name);  
                 if (*sep == ' ')  
                         sep = " | ";  
327          }          }
328          printf(" ]\n");        printf ("%s: unknown mode\n", argv[1]);
329          return;        /* drop through and print usage message */
330        }
331    
332      printf ("usage: %s [", argv[0]);
333      sep = " ";
334      for (p = modes; p->m_name; p++)
335        {
336          printf ("%s%s", sep, p->m_name);
337          if (*sep == ' ')
338            sep = " | ";
339        }
340      printf (" ]\n");
341      return;
342  }  }
343    
344  void  void
345  setbinary(argc, argv)  setbinary (int argc, char *argv[])
         int argc;  
         char *argv[];  
346  {  {
347      settftpmode ("octet");
         settftpmode("octet");  
348  }  }
349    
350  void  void
351  setascii(argc, argv)  setascii (int argc, char *argv[])
         int argc;  
         char *argv[];  
352  {  {
353      settftpmode ("netascii");
         settftpmode("netascii");  
354  }  }
355    
356  static void  static void
357  settftpmode(newmode)  settftpmode (char *newmode)
         char *newmode;  
358  {  {
359          strcpy(mode, newmode);    strcpy (mode, newmode);
360          if (verbose)    if (verbose)
361                  printf("mode set to %s\n", mode);      printf ("mode set to %s\n", mode);
362  }  }
363    
   
364  /*  /*
365   * Send file(s).   * Send file(s).
366   */   */
367  void  void
368  put(argc, argv)  put (int argc, char *argv[])
369          int argc;  {
370          char *argv[];    int             fd;
371  {    register int    n;
372          int fd;    register char  *cp, *targ;
373          register int n;  
374          register char *cp, *targ;    if (argc < 2)
375        get_args ("send", "(file) ", &argc, &argv);
376          if (argc < 2)  
377            get_args ("send", "(file) ", &argc, &argv);    if (argc < 2)
378        {
379          if (argc < 2) {        putusage (argv[0]);
380                  putusage(argv[0]);        return;
381                  return;      }
382          }    targ = argv[argc - 1];
383          targ = argv[argc - 1];    if (strchr (argv[argc - 1], ':'))
384          if (strchr (argv[argc - 1], ':')) {      {
385                  char *cp;        char *cp;
386                  struct hostent *hp;  
387          for (n = 1; n < argc - 1; n++)
388                  for (n = 1; n < argc - 1; n++)          if (strchr (argv[n], ':'))
389                          if (strchr (argv[n], ':')) {            {
390                                  putusage(argv[0]);              putusage (argv[0]);
391                                  return;              return;
392                          }            }
393                  cp = argv[argc - 1];        cp = argv[argc - 1];
394                  targ = strchr (cp, ':');        targ = strchr (cp, ':');
395                  *targ++ = 0;        *targ++ = 0;
396                  hp = gethostbyname(cp);        if (resolve_name (cp, 0) != RESOLVE_OK)
397                  if (hp == NULL) {          return;
398                          fprintf(stderr, "tftp: %s: ", cp);      }
399                          herror((char *)NULL);    if (!connected)
400                          return;      {
401                  }        printf ("No target machine specified.\n");
402                  bcopy(hp->h_addr, (caddr_t)&peeraddr.sin_addr, hp->h_length);        return;
403                  peeraddr.sin_family = hp->h_addrtype;      }
404                  connected = 1;    if (argc < 4)
405                  strcpy(hostname, hp->h_name);      {
406          }        cp = argc == 2 ? tail (targ) : argv[1];
407          if (!connected) {        fd = open (cp, O_RDONLY);
408                  printf("No target machine specified.\n");        if (fd < 0)
409                  return;          {
410          }            fprintf (stderr, "tftp: ");
411          if (argc < 4) {            perror (cp);
412                  cp = argc == 2 ? tail(targ) : argv[1];            return;
413                  fd = open(cp, O_RDONLY);          }
414                  if (fd < 0) {        if (verbose)
415                          fprintf(stderr, "tftp: "); perror(cp);          printf ("putting %s to %s:%s [%s]\n", cp, hostname, targ, mode);
416                          return;        peeraddr.sin_port = port ? port : sp->s_port;
417                  }        send_file (fd, targ, mode);
418                  if (verbose)        return;
419                          printf("putting %s to %s:%s [%s]\n",      }
420                                  cp, hostname, targ, mode);    /* this assumes the target is a directory */
421                  peeraddr.sin_port = port;    /* on a remote unix system.  hmmmm.  */
422                  send_file(fd, targ, mode);    cp = strchr (targ, '\0');
423                  return;    *cp++ = '/';
424          }    for (n = 1; n < argc - 1; n++)
425                                  /* this assumes the target is a directory */      {
426                                  /* on a remote unix system.  hmmmm.  */        strcpy (cp, tail (argv[n]));
427          cp = strchr (targ, '\0');        fd = open (argv[n], O_RDONLY);
428          *cp++ = '/';        if (fd < 0)
429          for (n = 1; n < argc - 1; n++) {          {
430                  strcpy(cp, tail(argv[n]));            fprintf (stderr, "tftp: ");
431                  fd = open(argv[n], O_RDONLY);            perror (argv[n]);
432                  if (fd < 0) {            continue;
433                          fprintf(stderr, "tftp: "); perror(argv[n]);          }
434                          continue;        if (verbose)
435                  }          printf ("putting %s to %s:%s [%s]\n", argv[n], hostname, targ, mode);
436                  if (verbose)        peeraddr.sin_port = port ? port : sp->s_port;
437                          printf("putting %s to %s:%s [%s]\n",        send_file (fd, targ, mode);
438                                  argv[n], hostname, targ, mode);      }
                 peeraddr.sin_port = port;  
                 send_file(fd, targ, mode);  
         }  
439  }  }
440    
441  static void  static void
442  putusage(s)  putusage (char *s)
         char *s;  
443  {  {
444          printf("usage: %s file ... host:target, or\n", s);    printf ("usage: %s file ... host:target, or\n", s);
445          printf("       %s file ... target (when already connected)\n", s);    printf ("       %s file ... target (when already connected)\n", s);
446  }  }
447    
448  /*  /*
449   * Receive file(s).   * Receive file(s).
450   */   */
451  void  void
452  get(argc, argv)  get (int argc, char *argv[])
453          int argc;  {
454          char *argv[];    int             fd;
455  {    register int    n;
456          int fd;    register char  *cp;
457          register int n;    char           *src;
458          register char *cp;  
459          char *src;    if (argc < 2)
460        get_args ("get", "(files) ", &argc, &argv);
461          if (argc < 2)  
462            get_args ("get", "(files) ", &argc, &argv);    if (argc < 2)
463        {
464          if (argc < 2) {        getusage (argv[0]);
465                  getusage(argv[0]);        return;
466                  return;      }
467          }    if (!connected)
468          if (!connected) {      {
469                  for (n = 1; n < argc ; n++)        for (n = 1; n < argc; n++)
470                          if (strchr (argv[n], ':') == 0) {          if (strchr (argv[n], ':') == 0)
471                                  getusage(argv[0]);            {
472                                  return;              getusage (argv[0]);
473                          }              return;
474          }            }
475          for (n = 1; n < argc ; n++) {      }
476                  src = strchr (argv[n], ':');    for (n = 1; n < argc; n++)
477                  if (src == NULL)      {
478                          src = argv[n];        src = strchr (argv[n], ':');
479                  else {        if (src == NULL)
480                          struct hostent *hp;          src = argv[n];
481          else
482                          *src++ = 0;          {
483                          hp = gethostbyname(argv[n]);            *src++ = 0;
484                          if (hp == NULL) {            if (resolve_name (argv[n], 0) != RESOLVE_OK)
485                                  fprintf(stderr, "tftp: %s: ", argv[n]);              continue;
486                                  herror((char *)NULL);          }
487                                  continue;        
488                          }        if (argc < 4)
489                          bcopy(hp->h_addr, (caddr_t)&peeraddr.sin_addr,          {
490                              hp->h_length);            cp = argc == 3 ? argv[2] : tail (src);
491                          peeraddr.sin_family = hp->h_addrtype;            fd = creat (cp, 0644);
492                          connected = 1;            if (fd < 0)
493                          strcpy(hostname, hp->h_name);              {
494                  }                fprintf (stderr, "tftp: ");
495                  if (argc < 4) {                perror (cp);
496                          cp = argc == 3 ? argv[2] : tail(src);                return;
497                          fd = creat(cp, 0644);              }
498                          if (fd < 0) {            if (verbose)
499                                  fprintf(stderr, "tftp: "); perror(cp);              printf ("getting from %s:%s to %s [%s]\n",
500                                  return;                      hostname, src, cp, mode);
501                          }            peeraddr.sin_port = port ? port : sp->s_port;
502                          if (verbose)            recvfile (fd, src, mode);
503                                  printf("getting from %s:%s to %s [%s]\n",            break;
504                                          hostname, src, cp, mode);          }
505                          peeraddr.sin_port = port;        cp = tail (src);          /* new .. jdg */
506                          recvfile(fd, src, mode);        fd = creat (cp, 0644);
507                          break;        if (fd < 0)
508                  }          {
509                  cp = tail(src);         /* new .. jdg */            fprintf (stderr, "tftp: ");
510                  fd = creat(cp, 0644);            perror (cp);
511                  if (fd < 0) {            continue;
512                          fprintf(stderr, "tftp: "); perror(cp);          }
513                          continue;        if (verbose)
514                  }          printf ("getting from %s:%s to %s [%s]\n", hostname, src, cp, mode);
515                  if (verbose)        peeraddr.sin_port = port ? port : sp->s_port;
516                          printf("getting from %s:%s to %s [%s]\n",        recvfile (fd, src, mode);
517                                  hostname, src, cp, mode);      }
                 peeraddr.sin_port = port;  
                 recvfile(fd, src, mode);  
         }  
518  }  }
519    
520  static void  static void
521  getusage(s)  getusage (char *s)
         char *s;  
522  {  {
523          printf("usage: %s host:file host:file ... file, or\n", s);    printf ("usage: %s host:file host:file ... file, or\n", s);
524          printf("       %s file file ... file if connected\n", s);    printf ("       %s file file ... file if connected\n", s);
525  }  }
526    
527  int     rexmtval = TIMEOUT;  int rexmtval = TIMEOUT;
528    
529  void  void
530  setrexmt(argc, argv)  setrexmt (int argc, char *argv[])
         int argc;  
         char *argv[];  
531  {  {
532          int t;    int t;
533    
534          if (argc < 2)    if (argc < 2)
535            get_args ("Rexmt-timeout", "(value) ", &argc, &argv);      get_args ("Rexmt-timeout", "(value) ", &argc, &argv);
536    
537          if (argc != 2) {    if (argc != 2)
538                  printf("usage: %s value\n", argv[0]);      {
539                  return;        printf ("usage: %s value\n", argv[0]);
540          }        return;
541          t = atoi(argv[1]);      }
542          if (t < 0)    t = atoi (argv[1]);
543                  printf("%s: bad value\n", argv[1]);    if (t < 0)
544          else      printf ("%s: bad value\n", argv[1]);
545                  rexmtval = t;    else
546        rexmtval = t;
547  }  }
548    
549  int     maxtimeout = 5 * TIMEOUT;  int maxtimeout = 5 * TIMEOUT;
550    
551  void  void
552  settimeout(argc, argv)  settimeout (int argc, char *argv[])
         int argc;  
         char *argv[];  
553  {  {
554          int t;    int t;
555    
556          if (argc < 2)    if (argc < 2)
557            get_args ("Maximum-timeout", "(value) ", &argc, &argv);      get_args ("Maximum-timeout", "(value) ", &argc, &argv);
558    
559          if (argc != 2) {    if (argc != 2)
560                  printf("usage: %s value\n", argv[0]);      {
561                  return;        printf ("usage: %s value\n", argv[0]);
562          }        return;
563          t = atoi(argv[1]);      }
564          if (t < 0)    t = atoi (argv[1]);
565                  printf("%s: bad value\n", argv[1]);    if (t < 0)
566          else      printf ("%s: bad value\n", argv[1]);
567                  maxtimeout = t;    else
568        maxtimeout = t;
569  }  }
570    
571  void  void
572  status(argc, argv)  status (int argc, char *argv[])
         int argc;  
         char *argv[];  
573  {  {
574          if (connected)    if (connected)
575                  printf("Connected to %s.\n", hostname);      printf ("Connected to %s.\n", hostname);
576          else    else
577                  printf("Not connected.\n");      printf ("Not connected.\n");
578          printf("Mode: %s Verbose: %s Tracing: %s\n", mode,    printf ("Mode: %s Verbose: %s Tracing: %s\n", mode,
579                  verbose ? "on" : "off", trace ? "on" : "off");            verbose ? "on" : "off", trace ? "on" : "off");
580          printf("Rexmt-interval: %d seconds, Max-timeout: %d seconds\n",    printf ("Rexmt-interval: %d seconds, Max-timeout: %d seconds\n",
581                  rexmtval, maxtimeout);            rexmtval, maxtimeout);
582  }  }
583    
584  void  void
585  intr()  intr ()
586  {  {
587      signal (SIGALRM, SIG_IGN);
588          signal(SIGALRM, SIG_IGN);    alarm (0);
589          alarm(0);    longjmp (toplevel, -1);
         longjmp(toplevel, -1);  
590  }  }
591    
592  char *  char *
593  tail(filename)  tail (char *filename)
         char *filename;  
594  {  {
595          register char *s;    register char  *s;
596    
597          while (*filename) {    while (*filename)
598                  s = strrchr (filename, '/');      {
599                  if (s == NULL)        s = strrchr (filename, '/');
600                          break;        if (s == NULL)
601                  if (s[1])          break;
602                          return (s + 1);        if (s[1])
603                  *s = '\0';          return (s + 1);
604          }        *s = '\0';
605          return (filename);      }
606      return filename;
607  }  }
608    
609  /*  /*
610   * Command parser.   * Command parser.
611   */   */
612  static void  static void
613  command()  command ()
614  {  {
615          register struct cmd *c;    register struct cmd *c;
616    
617          for (;;) {    for (;;)
618                  printf("%s> ", prompt);      {
619                  if (fgets (line, sizeof line, stdin) == 0) {        printf ("%s> ", prompt);
620                          if (feof(stdin)) {        if (fgets (line, sizeof line, stdin) == 0)
621                                  exit(0);          {
622                          } else {            if (feof (stdin))
623                                  continue;              exit (0);
624                          }            else
625                  }              continue;
626                  if (line[0] == 0)          }
627                          continue;        if (line[0] == 0)
628                  makeargv();          continue;
629                  if (margc == 0)        makeargv ();
630                          continue;        if (margc == 0)
631                  c = getcmd(margv[0]);          continue;
632                  if (c == (struct cmd *)-1) {        c = getcmd (margv[0]);
633                          printf("?Ambiguous command\n");        if (c == (struct cmd *) -1)
634                          continue;          {
635                  }            printf ("?Ambiguous command\n");
636                  if (c == 0) {            continue;
637                          printf("?Invalid command\n");          }
638                          continue;        if (c == 0)
639                  }          {
640                  (*c->handler)(margc, margv);            printf ("?Invalid command\n");
641              continue;
642          }          }
643          (*c->handler) (margc, margv);
644        }
645  }  }
646    
647  struct cmd *  struct cmd *
648  getcmd(name)  getcmd (register char *name)
         register char *name;  
649  {  {
650          register char *p, *q;    register char  *p, *q;
651          register struct cmd *c, *found;    register struct cmd *c, *found;
652          register int nmatches, longest;    register int nmatches, longest;
653    
654          longest = 0;    longest = 0;
655          nmatches = 0;    nmatches = 0;
656          found = 0;    found = 0;
657          for (c = cmdtab; (p = c->name) != NULL; c++) {    for (c = cmdtab; (p = c->name) != NULL; c++)
658                  for (q = name; *q == *p++; q++)      {
659                          if (*q == 0)            /* exact match? */        for (q = name; *q == *p++; q++)
660                                  return (c);          if (*q == 0)            /* exact match? */
661                  if (!*q) {                      /* the name was a prefix */            return (c);
662                          if (q - name > longest) {        
663                                  longest = q - name;        if (!*q)
664                                  nmatches = 1;          {                       /* the name was a prefix */
665                                  found = c;            if (q - name > longest)
666                          } else if (q - name == longest)              {
667                                  nmatches++;                longest = q - name;
668                  }                nmatches = 1;
669          }                found = c;
670          if (nmatches > 1)              }
671                  return ((struct cmd *)-1);            else if (q - name == longest)
672          return (found);              nmatches++;
673            }
674        }
675      if (nmatches > 1)
676        return (struct cmd *) -1;
677      return found;
678  }  }
679    
680  /*  /*
681   * Slice a string up into argc/argv.   * Slice a string up into argc/argv.
682   */   */
683  static void  static void
684  makeargv()  makeargv ()
685  {  {
686          register char *cp;    register char  *cp;
687          register char **argp = margv;    register char **argp = margv;
688    
689          margc = 0;    margc = 0;
690          for (cp = line; *cp;) {    for (cp = line; *cp;)
691                  while (isspace(*cp))      {
692                          cp++;        while (isspace (*cp))
693                  if (*cp == '\0')          cp++;
694                          break;        if (*cp == '\0')
695                  *argp++ = cp;          break;
696                  margc += 1;        *argp++ = cp;
697                  while (*cp != '\0' && !isspace(*cp))        margc += 1;
698                          cp++;        while (*cp != '\0' && !isspace (*cp))
699                  if (*cp == '\0')          cp++;
700                          break;        if (*cp == '\0')
701                  *cp++ = '\0';          break;
702          }        *cp++ = '\0';
703          *argp++ = 0;      }
704      *argp++ = 0;
705  }  }
706    
707  void  void
708  quit(argc, argv)  quit (int argc, char *argv[])
         int argc;  
         char *argv[];  
709  {  {
710      exit (0);
         exit(0);  
711  }  }
712    
713  /*  /*
714   * Help command.   * Help command.
715   */   */
716  void  void
717  help(argc, argv)  help (int argc, char *argv[])
         int argc;  
         char *argv[];  
718  {  {
719          register struct cmd *c;    register struct cmd *c;
720    
721          if (argc == 1) {    if (argc == 1)
722                  printf("Commands may be abbreviated.  Commands are:\n\n");      {
723                  for (c = cmdtab; c->name; c++)        printf ("Commands may be abbreviated.  Commands are:\n\n");
724                          printf("%-*s\t%s\n", (int)HELPINDENT, c->name, c->help);        for (c = cmdtab; c->name; c++)
725                  return;          printf ("%-*s\t%s\n", (int) HELPINDENT, c->name, c->help);
726          }        return;
727          while (--argc > 0) {      }
728                  register char *arg;    
729                  arg = *++argv;    while (--argc > 0)
730                  c = getcmd(arg);      {
731                  if (c == (struct cmd *)-1)        register char  *arg;
732                          printf("?Ambiguous help command %s\n", arg);  
733                  else if (c == (struct cmd *)0)        arg = *++argv;
734                          printf("?Invalid help command %s\n", arg);        c = getcmd (arg);
735                  else        if (c == (struct cmd *) -1)
736                          printf("%s\n", c->help);          printf ("?Ambiguous help command %s\n", arg);
737          }        else if (c == (struct cmd *) 0)
738            printf ("?Invalid help command %s\n", arg);
739          else
740            printf ("%s\n", c->help);
741        }
742  }  }
743    
744  void  void
745  settrace(argc, argv)  settrace (int argc, char **argv)
         int argc;  
         char **argv;  
746  {  {
747          trace = !trace;    trace = !trace;
748          printf("Packet tracing %s.\n", trace ? "on" : "off");    printf ("Packet tracing %s.\n", trace ? "on" : "off");
749  }  }
750    
751  void  void
752  setverbose(argc, argv)  setverbose (int argc, char **argv)
         int argc;  
         char **argv;  
753  {  {
754          verbose = !verbose;    verbose = !verbose;
755          printf("Verbose mode %s.\n", verbose ? "on" : "off");    printf ("Verbose mode %s.\n", verbose ? "on" : "off");
756  }  }

Legend:
Removed from v.1.9  
changed lines
  Added in v.1.10

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