-/* netrc.c -- parse the .netrc file to get hosts, accounts, and passwords
- Copyright (C) 1996, Free Software Foundation, Inc.
+/*
+ * netrc.c -- parse the .netrc file to get hosts, accounts, and passwords
+ *
Gordon Matzigkeit <gord@gnu.ai.mit.edu>, 1996
+ Copyright assigned to Eric S. Raymond, October 2001.
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
+ For license terms, see the file COPYING in this directory.
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
-
-/* Compile with -DSTANDALONE to test this module. */
+ Compile with -DSTANDALONE to test this module.
+ (Makefile.am should have a rule so you can just type "make netrc")
+*/
#include <stdio.h>
#include <ctype.h>
#include "config.h"
#include "fetchmail.h"
#include "netrc.h"
+#include "i18n.h"
#ifdef STANDALONE
/* Normally defined in xstrdup.c. */
/* Normally defined in xmalloc.c */
# define xmalloc malloc
# define xrealloc realloc
+
+char *program_name = "netrc";
#endif
/* Maybe add NEWENTRY to the account information list, LIST. NEWENTRY is
set to a ready-to-use netrc_entry, in any event. */
static void
-maybe_add_to_list (newentry, list)
- netrc_entry **newentry;
- netrc_entry **list;
+maybe_add_to_list (netrc_entry **newentry, netrc_entry **list)
{
netrc_entry *a, *l;
a = *newentry;
l = *list;
- /* We need an account name in order to add the entry to the list. */
- if (a && ! a->account)
+ /* We need a login name in order to add the entry to the list. */
+ if (a && ! a->login)
{
/* Free any allocated space. */
if (a->host)
list of entries. NULL is returned if the file could not be
parsed. */
netrc_entry *
-parse_netrc (file)
- char *file;
+parse_netrc (char *file)
{
FILE *fp;
- char buf[POPBUFSIZE+1], *p, *tok, *premature_token;
+ char buf[POPBUFSIZE+1], *p, *tok;
+ const char *premature_token;
netrc_entry *current, *retval;
int ln;
premature_token = NULL;
/* While there are lines in the file... */
- while (fgets(buf, POPBUFSIZE, fp))
+ while (fgets(buf, sizeof(buf) - 1, fp))
{
- ln ++;
+ ln++;
/* Strip trailing CRLF */
- p = buf + strlen(buf) - 1;
- while (*p && isspace(*p))
- *p-- = '\0';
+ for (p = buf + strlen(buf) - 1; (p >= buf) && isspace((unsigned char)*p); p--)
+ *p = '\0';
/* Parse the line. */
p = buf;
/* If the line is empty... */
if (!*p)
+ {
if (last_token == tok_macdef) /* end of macro */
last_token = tok_nothing;
else
continue; /* otherwise ignore it */
+ }
/* If we are defining macros, then skip parsing the line. */
while (*p && last_token != tok_macdef)
{
+ char quote_char = 0;
+ char *pp;
+
/* Skip any whitespace. */
- while (*p && isspace (*p))
+ while (*p && isspace ((unsigned char)*p))
p++;
/* Discard end-of-line comments. */
if (*p == '#')
break;
- tok = p;
+ tok = pp = p;
/* Find the end of the token. */
- while (*p && !isspace (*p))
- p ++;
-
+ while (*p && (quote_char || !isspace ((unsigned char)*p)))
+ {
+ if (quote_char)
+ {
+ if (quote_char == *p)
+ {
+ quote_char = 0;
+ p ++;
+ }
+ else
+ {
+ *pp = *p;
+ p ++;
+ pp ++;
+ }
+ }
+ else
+ {
+ if (*p == '"' || *p == '\'')
+ quote_char = *p;
+ else
+ {
+ *pp = *p;
+ pp ++;
+ }
+ p ++;
+ }
+ }
/* Null-terminate the token, if it isn't already. */
if (*p)
*p ++ = '\0';
+ *pp = 0;
switch (last_token)
{
case tok_login:
if (current)
- current->account = (char *) xstrdup (tok);
+ current->login = (char *) xstrdup (tok);
else
premature_token = "login";
break;
if (premature_token)
{
-#ifdef HAVE_ERROR
- error_at_line (0, 0, file, ln,
- _("warning: found \"%s\" before any host names"),
- premature_token);
-#else
fprintf (stderr,
- "%s:%d: warning: found \"%s\" before any host names\n",
+ GT_("%s:%d: warning: found \"%s\" before any host names\n"),
file, ln, premature_token);
-#endif
premature_token = NULL;
}
else
{
/* Fetch the next token. */
- if (!strcmp (tok, "account"))
- last_token = tok_account;
-
if (!strcmp (tok, "default"))
{
maybe_add_to_list (¤t, &retval);
else if (!strcmp (tok, "login"))
last_token = tok_login;
+ else if (!strcmp (tok, "user"))
+ last_token = tok_login;
+
else if (!strcmp (tok, "macdef"))
last_token = tok_macdef;
else if (!strcmp (tok, "password"))
last_token = tok_password;
+ else if (!strcmp (tok, "passwd"))
+ last_token = tok_password;
+
+ else if (!strcmp (tok, "account"))
+ last_token = tok_account;
+
else
{
- fprintf (stderr, "%s:%d: warning: unknown token \"%s\"\n",
+ fprintf (stderr, GT_("%s:%d: warning: unknown token \"%s\"\n"),
file, ln, tok);
}
}
/* Return the netrc entry from LIST corresponding to HOST. NULL is
returned if no such entry exists. */
netrc_entry *
-search_netrc (list, host)
- netrc_entry *list;
- char *host;
+search_netrc (netrc_entry *list, char *host, char *login)
{
/* Look for the HOST in LIST. */
while (list)
{
- if (!list->host)
- /* We hit the default entry. */
- break;
-
- else if (!strcmp (list->host, host))
- /* We found a matching entry. */
- break;
+ if (list->host && !strcmp(list->host, host))
+ if (!list->login || !strcmp(list->login, login))
+ /* We found a matching entry. */
+ break;
list = list->next;
}
return list;
}
+void
+free_netrc(netrc_entry *a) {
+ while(a) {
+ netrc_entry *n = a->next;
+ if (a->password != NULL) {
+ memset(a->password, 0x55, strlen(a->password));
+ free(a->password);
+ }
+ xfree(a->login);
+ xfree(a->host);
+ xfree(a);
+ a = n;
+ }
+}
#ifdef STANDALONE
#include <sys/types.h>
#include <sys/stat.h>
-extern int errno;
+#include <errno.h>
-int
-main (argc, argv)
- int argc;
- char **argv;
+int main (int argc, char **argv)
{
struct stat sb;
- char *program_name, *file, *target;
+ char *program_name, *file, *host, *login;
netrc_entry *head, *a;
- if (argc < 2)
- {
- fprintf (stderr, "Usage: %s NETRC [HOSTNAME]...\n", argv[0]);
- exit (1);
- }
-
program_name = argv[0];
file = argv[1];
- target = argv[2];
+ host = argv[2];
+ login = argv[3];
+
+ switch (argc) {
+ case 2:
+ case 4:
+ break;
+ default:
+ fprintf (stderr, "Usage: %s <file> [<host> <login>]\n", argv[0]);
+ exit(EXIT_FAILURE);
+ }
if (stat (file, &sb))
{
exit (1);
}
- if (argc > 2)
+ if (host && login)
{
- int i, status;
- status = 0;
- for (i = 2; i < argc; i++)
- {
- /* Print out the host that we are checking for. */
- fputs (argv[i], stdout);
+ int status;
+ status = EXIT_SUCCESS;
- a = search_netrc (head, argv[i]);
- if (a)
+ printf("Host: %s, Login: %s\n", host, login);
+
+ a = search_netrc (head, host, login);
+ if (a)
+ {
+ /* Print out the password (if any). */
+ if (a->password)
{
- /* Print out the account and password (if any). */
- fputc (' ', stdout);
- fputs (a->account, stdout);
- if (a->password)
- {
- fputc (' ', stdout);
- fputs (a->password, stdout);
- }
+ printf("Password: %s\n", a->password);
}
- else
- status = 1;
+ } else
+ status = EXIT_FAILURE;
+ fputc ('\n', stdout);
- fputc ('\n', stdout);
- }
exit (status);
}
fputc (' ', stdout);
- /* Print the account name. */
- fputs (a->account, stdout);
+ /* Print the login name. */
+ fputs (a->login, stdout);
if (a->password)
{
a = a->next;
}
+ free_netrc(head);
+
exit (0);
}
#endif /* STANDALONE */