home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 22 gnu / 22-gnu.zip / gnunet10.zip / source / ftp / ruserpass.c < prev   
C/C++ Source or Header  |  1996-07-27  |  8KB  |  290 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. #ifndef __EMX__
  43. # include <err.h>
  44. #endif
  45. #include <errno.h>
  46. #include <stdio.h>
  47. #include <stdlib.h>
  48. #include <string.h>
  49. #include <unistd.h>
  50.  
  51. #include "ftp_var.h"
  52.  
  53. static    int token __P((void));
  54. static    FILE *cfile;
  55.  
  56. #define    DEFAULT    1
  57. #define    LOGIN    2
  58. #define    PASSWD    3
  59. #define    ACCOUNT 4
  60. #define MACDEF  5
  61. #define    ID    10
  62. #define    MACH    11
  63.  
  64. static char tokval[100];
  65.  
  66. static struct toktab {
  67.     char *tokstr;
  68.     int tval;
  69. } toktab[]= {
  70.     { "default",    DEFAULT },
  71.     { "login",    LOGIN },
  72.     { "password",    PASSWD },
  73.     { "passwd",    PASSWD },
  74.     { "account",    ACCOUNT },
  75.     { "machine",    MACH },
  76.     { "macdef",    MACDEF },
  77.     { NULL,        0 }
  78. };
  79.  
  80. int
  81. ruserpass(host, aname, apass, aacct)
  82.     char *host, **aname, **apass, **aacct;
  83. {
  84.     char *hdir, buf[BUFSIZ], *tmp;
  85.     char *myname = 0, *mydomain;
  86.     int t, i, c, usedefault = 0;
  87.     struct stat stb;
  88.  
  89.     hdir = getenv("HOME");
  90.     if (hdir == NULL)
  91.         hdir = ".";
  92.     (void) sprintf(buf, "%s/.netrc", hdir);
  93.     cfile = fopen(buf, "r");
  94.     if (cfile == NULL) {
  95.         if (errno != ENOENT)
  96.             warn("%s", buf);
  97.         return (0);
  98.     }
  99.  
  100.     myname = localhost ();
  101.     if (! myname)
  102.         myname = "";
  103.  
  104.     if ((mydomain = strchr(myname, '.')) == NULL)
  105.         mydomain = "";
  106. next:
  107.     while ((t = token())) switch(t) {
  108.  
  109.     case DEFAULT:
  110.         usedefault = 1;
  111.         /* FALL THROUGH */
  112.  
  113.     case MACH:
  114.         if (!usedefault) {
  115.             if (token() != ID)
  116.                 continue;
  117.             /*
  118.              * Allow match either for user's input host name
  119.              * or official hostname.  Also allow match of 
  120.              * incompletely-specified host in local domain.
  121.              */
  122.             if (strcasecmp(host, tokval) == 0)
  123.                 goto match;
  124.             if (strcasecmp(hostname, tokval) == 0)
  125.                 goto match;
  126.             if ((tmp = strchr(hostname, '.')) != NULL &&
  127.                 strcasecmp(tmp, mydomain) == 0 &&
  128.                 strncasecmp(hostname, tokval, tmp-hostname) == 0 &&
  129.                 tokval[tmp - hostname] == '\0')
  130.                 goto match;
  131.             if ((tmp = strchr(host, '.')) != NULL &&
  132.                 strcasecmp(tmp, mydomain) == 0 &&
  133.                 strncasecmp(host, tokval, tmp - host) == 0 &&
  134.                 tokval[tmp - host] == '\0')
  135.                 goto match;
  136.             continue;
  137.         }
  138.     match:
  139.         while ((t = token()) && t != MACH && t != DEFAULT) switch(t) {
  140.  
  141.         case LOGIN:
  142.             if (token())
  143.                 if (*aname == 0) { 
  144.                     *aname = malloc((unsigned) strlen(tokval) + 1);
  145.                     (void) strcpy(*aname, tokval);
  146.                 } else {
  147.                     if (strcmp(*aname, tokval))
  148.                         goto next;
  149.                 }
  150.             break;
  151.         case PASSWD:
  152.             if ((*aname == NULL || strcmp(*aname, "anonymous")) &&
  153.                 fstat(fileno(cfile), &stb) >= 0 &&
  154.                 (stb.st_mode & 077) != 0) {
  155.     warnx("Error: .netrc file is readable by others.");
  156.     warnx("Remove password or make file unreadable by others.");
  157.                 goto bad;
  158.             }
  159.             if (token() && *apass == 0) {
  160.                 *apass = malloc((unsigned) strlen(tokval) + 1);
  161.                 (void) strcpy(*apass, tokval);
  162.             }
  163.             break;
  164.         case ACCOUNT:
  165.             if (fstat(fileno(cfile), &stb) >= 0
  166.                 && (stb.st_mode & 077) != 0) {
  167.     warnx("Error: .netrc file is readable by others.");
  168.     warnx("Remove account or make file unreadable by others.");
  169.                 goto bad;
  170.             }
  171.             if (token() && *aacct == 0) {
  172.                 *aacct = malloc((unsigned) strlen(tokval) + 1);
  173.                 (void) strcpy(*aacct, tokval);
  174.             }
  175.             break;
  176.         case MACDEF:
  177.             if (proxy) 
  178.                 goto done;
  179.  
  180.             while ((c=getc(cfile)) != EOF && c == ' ' || c == '\t');
  181.             if (c == EOF || c == '\n') {
  182.                 printf("Missing macdef name argument.\n");
  183.                 goto bad;
  184.             }
  185.             if (macnum == 16) {
  186.                 printf("Limit of 16 macros have already been defined\n");
  187.                 goto bad;
  188.             }
  189.             tmp = macros[macnum].mac_name;
  190.             *tmp++ = c;
  191.             for (i=0; i < 8 && (c=getc(cfile)) != EOF &&
  192.                 !isspace(c); ++i) {
  193.                 *tmp++ = c;
  194.             }
  195.             if (c == EOF) {
  196.                 printf("Macro definition missing null line terminator.\n");
  197.                 goto bad;
  198.             }
  199.             *tmp = '\0';
  200.             if (c != '\n') {
  201.                 while ((c=getc(cfile)) != EOF && c != '\n');
  202.             }
  203.             if (c == EOF) {
  204.                 printf("Macro definition missing null line terminator.\n");
  205.                 goto bad;
  206.             }
  207.             if (macnum == 0) {
  208.                 macros[macnum].mac_start = macbuf;
  209.             }
  210.             else {
  211.                 macros[macnum].mac_start = macros[macnum-1].mac_end + 1;
  212.             }
  213.             tmp = macros[macnum].mac_start;
  214.             while (tmp != macbuf + 4096) {
  215.                 if ((c=getc(cfile)) == EOF) {
  216.                 printf("Macro definition missing null line terminator.\n");
  217.                     goto bad;
  218.                 }
  219.                 *tmp = c;
  220.                 if (*tmp == '\n') {
  221.                     if (*(tmp-1) == '\0') {
  222.                        macros[macnum++].mac_end = tmp - 1;
  223.                        break;
  224.                     }
  225.                     *tmp = '\0';
  226.                 }
  227.                 tmp++;
  228.             }
  229.             if (tmp == macbuf + 4096) {
  230.                 printf("4K macro buffer exceeded\n");
  231.                 goto bad;
  232.             }
  233.             break;
  234.         default:
  235.             warnx("Unknown .netrc keyword %s", tokval);
  236.             break;
  237.         }
  238.         goto done;
  239.     }
  240. done:
  241.     (void) fclose(cfile);
  242.     if (myname && *myname)
  243.         free (myname);
  244.     return (0);
  245. bad:
  246.     (void) fclose(cfile);
  247.     if (myname && *myname)
  248.         free (myname);
  249.     return (-1);
  250. }
  251.  
  252. static int
  253. token()
  254. {
  255.     char *cp;
  256.     int c;
  257.     struct toktab *t;
  258.  
  259.     if (feof(cfile) || ferror(cfile))
  260.         return (0);
  261.     while ((c = getc(cfile)) != EOF &&
  262.         (c == '\n' || c == '\t' || c == ' ' || c == ','))
  263.         continue;
  264.     if (c == EOF)
  265.         return (0);
  266.     cp = tokval;
  267.     if (c == '"') {
  268.         while ((c = getc(cfile)) != EOF && c != '"') {
  269.             if (c == '\\')
  270.                 c = getc(cfile);
  271.             *cp++ = c;
  272.         }
  273.     } else {
  274.         *cp++ = c;
  275.         while ((c = getc(cfile)) != EOF
  276.             && c != '\n' && c != '\t' && c != ' ' && c != ',') {
  277.             if (c == '\\')
  278.                 c = getc(cfile);
  279.             *cp++ = c;
  280.         }
  281.     }
  282.     *cp = 0;
  283.     if (tokval[0] == 0)
  284.         return (0);
  285.     for (t = toktab; t->tokstr; t++)
  286.         if (!strcmp(t->tokstr, tokval))
  287.             return (t->tval);
  288.     return (ID);
  289. }
  290.