home *** CD-ROM | disk | FTP | other *** search
/ Geek Gadgets 1 / ADE-1.bin / ade-dist / inetutils-1.2-src.tgz / tar.out / fsf / inetutils / ftp / ruserpass.c < prev   
C/C++ Source or Header  |  1996-09-28  |  7KB  |  295 lines

  1. /*
  2.  * Copyright (c) 1985, 1993, 1994
  3.  *    The Regents of the University of California.  All rights reserved.
  4.  *
  5.  * Redistribution and use in source and binary forms, with or without
  6.  * modification, are permitted provided that the following conditions
  7.  * are met:
  8.  * 1. Redistributions of source code must retain the above copyright
  9.  *    notice, this list of conditions and the following disclaimer.
  10.  * 2. Redistributions in binary form must reproduce the above copyright
  11.  *    notice, this list of conditions and the following disclaimer in the
  12.  *    documentation and/or other materials provided with the distribution.
  13.  * 3. All advertising materials mentioning features or use of this software
  14.  *    must display the following acknowledgement:
  15.  *    This product includes software developed by the University of
  16.  *    California, Berkeley and its contributors.
  17.  * 4. Neither the name of the University nor the names of its contributors
  18.  *    may be used to endorse or promote products derived from this software
  19.  *    without specific prior written permission.
  20.  *
  21.  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
  22.  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  23.  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  24.  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
  25.  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  26.  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  27.  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  28.  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  29.  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  30.  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  31.  * SUCH DAMAGE.
  32.  */
  33.  
  34. #ifndef lint
  35. static char sccsid[] = "@(#)ruserpass.c    8.4 (Berkeley) 4/27/95";
  36. #endif /* not lint */
  37.  
  38. #include <sys/types.h>
  39. #include <sys/stat.h>
  40.  
  41. #include <ctype.h>
  42. #include <errno.h>
  43. #include <stdio.h>
  44. #include <stdlib.h>
  45. #include <string.h>
  46. #include <unistd.h>
  47. #ifdef HAVE_STDARG_H
  48. #include <stdarg.h>
  49. #else
  50. #include <varargs.h>
  51. #endif
  52. #include <err.h>
  53.  
  54. #include "ftp_var.h"
  55.  
  56. extern char *localhost __P((void));
  57.  
  58. static    int token __P((void));
  59. static    FILE *cfile;
  60.  
  61. #define    DEFAULT    1
  62. #define    LOGIN    2
  63. #define    PASSWD    3
  64. #define    ACCOUNT 4
  65. #define MACDEF  5
  66. #define    ID    10
  67. #define    MACH    11
  68.  
  69. static char tokval[100];
  70.  
  71. static struct toktab {
  72.     char *tokstr;
  73.     int tval;
  74. } toktab[]= {
  75.     { "default",    DEFAULT },
  76.     { "login",    LOGIN },
  77.     { "password",    PASSWD },
  78.     { "passwd",    PASSWD },
  79.     { "account",    ACCOUNT },
  80.     { "machine",    MACH },
  81.     { "macdef",    MACDEF },
  82.     { NULL,        0 }
  83. };
  84.  
  85. int
  86. ruserpass(host, aname, apass, aacct)
  87.     char *host, **aname, **apass, **aacct;
  88. {
  89.     char *hdir, buf[BUFSIZ], *tmp;
  90.     char *myname = 0, *mydomain;
  91.     int t, i, c, usedefault = 0;
  92.     struct stat stb;
  93.  
  94.     hdir = getenv("HOME");
  95.     if (hdir == NULL)
  96.         hdir = ".";
  97.     (void) sprintf(buf, "%s/.netrc", hdir);
  98.     cfile = fopen(buf, "r");
  99.     if (cfile == NULL) {
  100.         if (errno != ENOENT)
  101.             warn("%s", buf);
  102.         return (0);
  103.     }
  104.  
  105.     myname = localhost ();
  106.     if (! myname)
  107.         myname = "";
  108.  
  109.     if ((mydomain = strchr(myname, '.')) == NULL)
  110.         mydomain = "";
  111. next:
  112.     while ((t = token())) switch(t) {
  113.  
  114.     case DEFAULT:
  115.         usedefault = 1;
  116.         /* FALL THROUGH */
  117.  
  118.     case MACH:
  119.         if (!usedefault) {
  120.             if (token() != ID)
  121.                 continue;
  122.             /*
  123.              * Allow match either for user's input host name
  124.              * or official hostname.  Also allow match of 
  125.              * incompletely-specified host in local domain.
  126.              */
  127.             if (strcasecmp(host, tokval) == 0)
  128.                 goto match;
  129.             if (strcasecmp(hostname, tokval) == 0)
  130.                 goto match;
  131.             if ((tmp = strchr(hostname, '.')) != NULL &&
  132.                 strcasecmp(tmp, mydomain) == 0 &&
  133.                 strncasecmp(hostname, tokval, tmp-hostname) == 0 &&
  134.                 tokval[tmp - hostname] == '\0')
  135.                 goto match;
  136.             if ((tmp = strchr(host, '.')) != NULL &&
  137.                 strcasecmp(tmp, mydomain) == 0 &&
  138.                 strncasecmp(host, tokval, tmp - host) == 0 &&
  139.                 tokval[tmp - host] == '\0')
  140.                 goto match;
  141.             continue;
  142.         }
  143.     match:
  144.         while ((t = token()) && t != MACH && t != DEFAULT) switch(t) {
  145.  
  146.         case LOGIN:
  147.             if (token())
  148.                 if (*aname == 0) { 
  149.                     *aname = malloc((unsigned) strlen(tokval) + 1);
  150.                     (void) strcpy(*aname, tokval);
  151.                 } else {
  152.                     if (strcmp(*aname, tokval))
  153.                         goto next;
  154.                 }
  155.             break;
  156.         case PASSWD:
  157.             if ((*aname == NULL || strcmp(*aname, "anonymous")) &&
  158.                 fstat(fileno(cfile), &stb) >= 0 &&
  159.                 (stb.st_mode & 077) != 0) {
  160.     warnx("Error: .netrc file is readable by others.");
  161.     warnx("Remove password or make file unreadable by others.");
  162.                 goto bad;
  163.             }
  164.             if (token() && *apass == 0) {
  165.                 *apass = malloc((unsigned) strlen(tokval) + 1);
  166.                 (void) strcpy(*apass, tokval);
  167.             }
  168.             break;
  169.         case ACCOUNT:
  170.             if (fstat(fileno(cfile), &stb) >= 0
  171.                 && (stb.st_mode & 077) != 0) {
  172.     warnx("Error: .netrc file is readable by others.");
  173.     warnx("Remove account or make file unreadable by others.");
  174.                 goto bad;
  175.             }
  176.             if (token() && *aacct == 0) {
  177.                 *aacct = malloc((unsigned) strlen(tokval) + 1);
  178.                 (void) strcpy(*aacct, tokval);
  179.             }
  180.             break;
  181.         case MACDEF:
  182.             if (proxy) 
  183.                 goto done;
  184.  
  185.             while ((c=getc(cfile)) != EOF && c == ' ' || c == '\t');
  186.             if (c == EOF || c == '\n') {
  187.                 printf("Missing macdef name argument.\n");
  188.                 goto bad;
  189.             }
  190.             if (macnum == 16) {
  191.                 printf("Limit of 16 macros have already been defined\n");
  192.                 goto bad;
  193.             }
  194.             tmp = macros[macnum].mac_name;
  195.             *tmp++ = c;
  196.             for (i=0; i < 8 && (c=getc(cfile)) != EOF &&
  197.                 !isspace(c); ++i) {
  198.                 *tmp++ = c;
  199.             }
  200.             if (c == EOF) {
  201.                 printf("Macro definition missing null line terminator.\n");
  202.                 goto bad;
  203.             }
  204.             *tmp = '\0';
  205.             if (c != '\n') {
  206.                 while ((c=getc(cfile)) != EOF && c != '\n');
  207.             }
  208.             if (c == EOF) {
  209.                 printf("Macro definition missing null line terminator.\n");
  210.                 goto bad;
  211.             }
  212.             if (macnum == 0) {
  213.                 macros[macnum].mac_start = macbuf;
  214.             }
  215.             else {
  216.                 macros[macnum].mac_start = macros[macnum-1].mac_end + 1;
  217.             }
  218.             tmp = macros[macnum].mac_start;
  219.             while (tmp != macbuf + 4096) {
  220.                 if ((c=getc(cfile)) == EOF) {
  221.                 printf("Macro definition missing null line terminator.\n");
  222.                     goto bad;
  223.                 }
  224.                 *tmp = c;
  225.                 if (*tmp == '\n') {
  226.                     if (*(tmp-1) == '\0') {
  227.                        macros[macnum++].mac_end = tmp - 1;
  228.                        break;
  229.                     }
  230.                     *tmp = '\0';
  231.                 }
  232.                 tmp++;
  233.             }
  234.             if (tmp == macbuf + 4096) {
  235.                 printf("4K macro buffer exceeded\n");
  236.                 goto bad;
  237.             }
  238.             break;
  239.         default:
  240.             warnx("Unknown .netrc keyword %s", tokval);
  241.             break;
  242.         }
  243.         goto done;
  244.     }
  245. done:
  246.     (void) fclose(cfile);
  247.     if (myname && *myname)
  248.         free (myname);
  249.     return (0);
  250. bad:
  251.     (void) fclose(cfile);
  252.     if (myname && *myname)
  253.         free (myname);
  254.     return (-1);
  255. }
  256.  
  257. static int
  258. token()
  259. {
  260.     char *cp;
  261.     int c;
  262.     struct toktab *t;
  263.  
  264.     if (feof(cfile) || ferror(cfile))
  265.         return (0);
  266.     while ((c = getc(cfile)) != EOF &&
  267.         (c == '\n' || c == '\t' || c == ' ' || c == ','))
  268.         continue;
  269.     if (c == EOF)
  270.         return (0);
  271.     cp = tokval;
  272.     if (c == '"') {
  273.         while ((c = getc(cfile)) != EOF && c != '"') {
  274.             if (c == '\\')
  275.                 c = getc(cfile);
  276.             *cp++ = c;
  277.         }
  278.     } else {
  279.         *cp++ = c;
  280.         while ((c = getc(cfile)) != EOF
  281.             && c != '\n' && c != '\t' && c != ' ' && c != ',') {
  282.             if (c == '\\')
  283.                 c = getc(cfile);
  284.             *cp++ = c;
  285.         }
  286.     }
  287.     *cp = 0;
  288.     if (tokval[0] == 0)
  289.         return (0);
  290.     for (t = toktab; t->tokstr; t++)
  291.         if (!strcmp(t->tokstr, tokval))
  292.             return (t->tval);
  293.     return (ID);
  294. }
  295.