| 1 | /* Read and parse the .netrc file to get hosts, accounts, and passwords.
|
|---|
| 2 | Copyright (C) 1996, Free Software Foundation, Inc.
|
|---|
| 3 |
|
|---|
| 4 | This file is part of GNU Wget.
|
|---|
| 5 |
|
|---|
| 6 | GNU Wget is free software; you can redistribute it and/or modify
|
|---|
| 7 | it under the terms of the GNU General Public License as published by
|
|---|
| 8 | the Free Software Foundation; either version 2 of the License, or
|
|---|
| 9 | (at your option) any later version.
|
|---|
| 10 |
|
|---|
| 11 | GNU Wget is distributed in the hope that it will be useful,
|
|---|
| 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|---|
| 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|---|
| 14 | GNU General Public License for more details.
|
|---|
| 15 |
|
|---|
| 16 | You should have received a copy of the GNU General Public License
|
|---|
| 17 | along with Wget; if not, write to the Free Software
|
|---|
| 18 | Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
|---|
| 19 |
|
|---|
| 20 | In addition, as a special exception, the Free Software Foundation
|
|---|
| 21 | gives permission to link the code of its release of Wget with the
|
|---|
| 22 | OpenSSL project's "OpenSSL" library (or with modified versions of it
|
|---|
| 23 | that use the same license as the "OpenSSL" library), and distribute
|
|---|
| 24 | the linked executables. You must obey the GNU General Public License
|
|---|
| 25 | in all respects for all of the code used other than "OpenSSL". If you
|
|---|
| 26 | modify this file, you may extend this exception to your version of the
|
|---|
| 27 | file, but you are not obligated to do so. If you do not wish to do
|
|---|
| 28 | so, delete this exception statement from your version. */
|
|---|
| 29 |
|
|---|
| 30 | /* This file used to be kept in synch with the code in Fetchmail, but
|
|---|
| 31 | the latter has diverged since. */
|
|---|
| 32 |
|
|---|
| 33 | #ifdef HAVE_CONFIG_H
|
|---|
| 34 | # include <config.h>
|
|---|
| 35 | #endif
|
|---|
| 36 |
|
|---|
| 37 | #include <stdio.h>
|
|---|
| 38 | #include <stdlib.h>
|
|---|
| 39 | #ifdef HAVE_STRING_H
|
|---|
| 40 | # include <string.h>
|
|---|
| 41 | #else
|
|---|
| 42 | # include <strings.h>
|
|---|
| 43 | #endif
|
|---|
| 44 | #include <sys/types.h>
|
|---|
| 45 | #include <errno.h>
|
|---|
| 46 |
|
|---|
| 47 | #include "wget.h"
|
|---|
| 48 | #include "utils.h"
|
|---|
| 49 | #include "netrc.h"
|
|---|
| 50 | #include "init.h"
|
|---|
| 51 |
|
|---|
| 52 | #ifndef errno
|
|---|
| 53 | extern int errno;
|
|---|
| 54 | #endif
|
|---|
| 55 |
|
|---|
| 56 | #define NETRC_FILE_NAME ".netrc"
|
|---|
| 57 |
|
|---|
| 58 | acc_t *netrc_list;
|
|---|
| 59 |
|
|---|
| 60 | static acc_t *parse_netrc PARAMS ((const char *));
|
|---|
| 61 |
|
|---|
| 62 | /* Return the correct user and password, given the host, user (as
|
|---|
| 63 | given in the URL), and password (as given in the URL). May return
|
|---|
| 64 | NULL.
|
|---|
| 65 |
|
|---|
| 66 | If SLACK_DEFAULT is set, allow looking for a "default" account.
|
|---|
| 67 | You will typically turn it off for HTTP. */
|
|---|
| 68 | void
|
|---|
| 69 | search_netrc (const char *host, const char **acc, const char **passwd,
|
|---|
| 70 | int slack_default)
|
|---|
| 71 | {
|
|---|
| 72 | acc_t *l;
|
|---|
| 73 | static int processed_netrc;
|
|---|
| 74 |
|
|---|
| 75 | if (!opt.netrc)
|
|---|
| 76 | return;
|
|---|
| 77 | /* Find ~/.netrc. */
|
|---|
| 78 | if (!processed_netrc)
|
|---|
| 79 | {
|
|---|
| 80 | char *home = home_dir ();
|
|---|
| 81 |
|
|---|
| 82 | netrc_list = NULL;
|
|---|
| 83 | processed_netrc = 1;
|
|---|
| 84 | if (home)
|
|---|
| 85 | {
|
|---|
| 86 | int err;
|
|---|
| 87 | struct_stat buf;
|
|---|
| 88 | char *path = (char *)alloca (strlen (home) + 1
|
|---|
| 89 | + strlen (NETRC_FILE_NAME) + 1);
|
|---|
| 90 | sprintf (path, "%s/%s", home, NETRC_FILE_NAME);
|
|---|
| 91 | xfree (home);
|
|---|
| 92 | err = stat (path, &buf);
|
|---|
| 93 | if (err == 0)
|
|---|
| 94 | netrc_list = parse_netrc (path);
|
|---|
| 95 | }
|
|---|
| 96 | }
|
|---|
| 97 | /* If nothing to do... */
|
|---|
| 98 | if (!netrc_list)
|
|---|
| 99 | return;
|
|---|
| 100 | /* Acc and password found; all OK. */
|
|---|
| 101 | if (*acc && *passwd)
|
|---|
| 102 | return;
|
|---|
| 103 | /* Some data not given -- try finding the host. */
|
|---|
| 104 | for (l = netrc_list; l; l = l->next)
|
|---|
| 105 | {
|
|---|
| 106 | if (!l->host)
|
|---|
| 107 | continue;
|
|---|
| 108 | else if (!strcasecmp (l->host, host))
|
|---|
| 109 | break;
|
|---|
| 110 | }
|
|---|
| 111 | if (l)
|
|---|
| 112 | {
|
|---|
| 113 | if (*acc)
|
|---|
| 114 | {
|
|---|
| 115 | /* Looking for password in .netrc. */
|
|---|
| 116 | if (!strcmp (l->acc, *acc))
|
|---|
| 117 | *passwd = l->passwd; /* usernames match; password OK */
|
|---|
| 118 | else
|
|---|
| 119 | *passwd = NULL; /* usernames don't match */
|
|---|
| 120 | }
|
|---|
| 121 | else /* NOT *acc */
|
|---|
| 122 | {
|
|---|
| 123 | /* If password was given, use it. The account is l->acc. */
|
|---|
| 124 | *acc = l->acc;
|
|---|
| 125 | if (l->passwd)
|
|---|
| 126 | *passwd = l->passwd;
|
|---|
| 127 | }
|
|---|
| 128 | return;
|
|---|
| 129 | }
|
|---|
| 130 | else
|
|---|
| 131 | {
|
|---|
| 132 | if (!slack_default)
|
|---|
| 133 | return;
|
|---|
| 134 | if (*acc)
|
|---|
| 135 | return;
|
|---|
| 136 | /* Try looking for the default account. */
|
|---|
| 137 | for (l = netrc_list; l; l = l->next)
|
|---|
| 138 | if (!l->host)
|
|---|
| 139 | break;
|
|---|
| 140 | if (!l)
|
|---|
| 141 | return;
|
|---|
| 142 | *acc = l->acc;
|
|---|
| 143 | if (!*passwd)
|
|---|
| 144 | *passwd = l->passwd;
|
|---|
| 145 | return;
|
|---|
| 146 | }
|
|---|
| 147 | }
|
|---|
| 148 |
|
|---|
| 149 |
|
|---|
| 150 | #ifdef STANDALONE
|
|---|
| 151 |
|
|---|
| 152 | #include <assert.h>
|
|---|
| 153 |
|
|---|
| 154 | /* Normally, these functions would be defined by your package. */
|
|---|
| 155 | # define xmalloc malloc
|
|---|
| 156 | # define xfree free
|
|---|
| 157 | # define xstrdup strdup
|
|---|
| 158 |
|
|---|
| 159 | # define xrealloc realloc
|
|---|
| 160 |
|
|---|
| 161 | /* Read a line from FP. The function reallocs the storage as needed
|
|---|
| 162 | to accomodate for any length of the line. Reallocs are done
|
|---|
| 163 | storage exponentially, doubling the storage after each overflow to
|
|---|
| 164 | minimize the number of calls to realloc() and fgets(). The newline
|
|---|
| 165 | character at the end of line is retained.
|
|---|
| 166 |
|
|---|
| 167 | After end-of-file is encountered without anything being read, NULL
|
|---|
| 168 | is returned. NULL is also returned on error. To distinguish
|
|---|
| 169 | between these two cases, use the stdio function ferror(). */
|
|---|
| 170 |
|
|---|
| 171 | char *
|
|---|
| 172 | read_whole_line (FILE *fp)
|
|---|
| 173 | {
|
|---|
| 174 | int length = 0;
|
|---|
| 175 | int bufsize = 81;
|
|---|
| 176 | char *line = (char *)xmalloc (bufsize);
|
|---|
| 177 |
|
|---|
| 178 | while (fgets (line + length, bufsize - length, fp))
|
|---|
| 179 | {
|
|---|
| 180 | length += strlen (line + length);
|
|---|
| 181 | assert (length > 0);
|
|---|
| 182 | if (line[length - 1] == '\n')
|
|---|
| 183 | break;
|
|---|
| 184 | /* fgets() guarantees to read the whole line, or to use up the
|
|---|
| 185 | space we've given it. We can double the buffer
|
|---|
| 186 | unconditionally. */
|
|---|
| 187 | bufsize <<= 1;
|
|---|
| 188 | line = xrealloc (line, bufsize);
|
|---|
| 189 | }
|
|---|
| 190 | if (length == 0 || ferror (fp))
|
|---|
| 191 | {
|
|---|
| 192 | xfree (line);
|
|---|
| 193 | return NULL;
|
|---|
| 194 | }
|
|---|
| 195 | if (length + 1 < bufsize)
|
|---|
| 196 | /* Relieve the memory from our exponential greediness. We say
|
|---|
| 197 | `length + 1' because the terminating \0 is not included in
|
|---|
| 198 | LENGTH. We don't need to zero-terminate the string ourselves,
|
|---|
| 199 | though, because fgets() does that. */
|
|---|
| 200 | line = xrealloc (line, length + 1);
|
|---|
| 201 | return line;
|
|---|
| 202 | }
|
|---|
| 203 | #endif /* STANDALONE */
|
|---|
| 204 |
|
|---|
| 205 | /* Maybe add NEWENTRY to the account information list, LIST. NEWENTRY is
|
|---|
| 206 | set to a ready-to-use acc_t, in any event. */
|
|---|
| 207 | static void
|
|---|
| 208 | maybe_add_to_list (acc_t **newentry, acc_t **list)
|
|---|
| 209 | {
|
|---|
| 210 | acc_t *a, *l;
|
|---|
| 211 | a = *newentry;
|
|---|
| 212 | l = *list;
|
|---|
| 213 |
|
|---|
| 214 | /* We need an account name in order to add the entry to the list. */
|
|---|
| 215 | if (a && ! a->acc)
|
|---|
| 216 | {
|
|---|
| 217 | /* Free any allocated space. */
|
|---|
| 218 | xfree_null (a->host);
|
|---|
| 219 | xfree_null (a->acc);
|
|---|
| 220 | xfree_null (a->passwd);
|
|---|
| 221 | }
|
|---|
| 222 | else
|
|---|
| 223 | {
|
|---|
| 224 | if (a)
|
|---|
| 225 | {
|
|---|
| 226 | /* Add the current machine into our list. */
|
|---|
| 227 | a->next = l;
|
|---|
| 228 | l = a;
|
|---|
| 229 | }
|
|---|
| 230 |
|
|---|
| 231 | /* Allocate a new acc_t structure. */
|
|---|
| 232 | a = (acc_t *)xmalloc (sizeof (acc_t));
|
|---|
| 233 | }
|
|---|
| 234 |
|
|---|
| 235 | /* Zero the structure, so that it is ready to use. */
|
|---|
| 236 | memset (a, 0, sizeof(*a));
|
|---|
| 237 |
|
|---|
| 238 | /* Return the new pointers. */
|
|---|
| 239 | *newentry = a;
|
|---|
| 240 | *list = l;
|
|---|
| 241 | return;
|
|---|
| 242 | }
|
|---|
| 243 |
|
|---|
| 244 | /* Helper function for the parser, shifts contents of
|
|---|
| 245 | null-terminated string once character to the left.
|
|---|
| 246 | Used in processing \ and " constructs in the netrc file */
|
|---|
| 247 | static void
|
|---|
| 248 | shift_left(char *string)
|
|---|
| 249 | {
|
|---|
| 250 | char *p;
|
|---|
| 251 |
|
|---|
| 252 | for (p=string; *p; ++p)
|
|---|
| 253 | *p = *(p+1);
|
|---|
| 254 | }
|
|---|
| 255 |
|
|---|
| 256 | /* Parse a .netrc file (as described in the ftp(1) manual page). */
|
|---|
| 257 | static acc_t *
|
|---|
| 258 | parse_netrc (const char *path)
|
|---|
| 259 | {
|
|---|
| 260 | FILE *fp;
|
|---|
| 261 | char *line, *p, *tok;
|
|---|
| 262 | const char *premature_token;
|
|---|
| 263 | acc_t *current, *retval;
|
|---|
| 264 | int ln, quote;
|
|---|
| 265 |
|
|---|
| 266 | /* The latest token we've seen in the file. */
|
|---|
| 267 | enum
|
|---|
| 268 | {
|
|---|
| 269 | tok_nothing, tok_account, tok_login, tok_macdef, tok_machine, tok_password
|
|---|
| 270 | } last_token = tok_nothing;
|
|---|
| 271 |
|
|---|
| 272 | current = retval = NULL;
|
|---|
| 273 |
|
|---|
| 274 | fp = fopen (path, "r");
|
|---|
| 275 | if (!fp)
|
|---|
| 276 | {
|
|---|
| 277 | fprintf (stderr, _("%s: Cannot read %s (%s).\n"), exec_name,
|
|---|
| 278 | path, strerror (errno));
|
|---|
| 279 | return retval;
|
|---|
| 280 | }
|
|---|
| 281 |
|
|---|
| 282 | /* Initialize the file data. */
|
|---|
| 283 | ln = 0;
|
|---|
| 284 | premature_token = NULL;
|
|---|
| 285 |
|
|---|
| 286 | /* While there are lines in the file... */
|
|---|
| 287 | while ((line = read_whole_line (fp)) != NULL)
|
|---|
| 288 | {
|
|---|
| 289 | ln ++;
|
|---|
| 290 |
|
|---|
| 291 | /* Parse the line. */
|
|---|
| 292 | p = line;
|
|---|
| 293 | quote = 0;
|
|---|
| 294 |
|
|---|
| 295 | /* Skip leading whitespace. */
|
|---|
| 296 | while (*p && ISSPACE (*p))
|
|---|
| 297 | p ++;
|
|---|
| 298 |
|
|---|
| 299 | /* If the line is empty, then end any macro definition. */
|
|---|
| 300 | if (last_token == tok_macdef && !*p)
|
|---|
| 301 | /* End of macro if the line is empty. */
|
|---|
| 302 | last_token = tok_nothing;
|
|---|
| 303 |
|
|---|
| 304 | /* If we are defining macros, then skip parsing the line. */
|
|---|
| 305 | while (*p && last_token != tok_macdef)
|
|---|
| 306 | {
|
|---|
| 307 | /* Skip any whitespace. */
|
|---|
| 308 | while (*p && ISSPACE (*p))
|
|---|
| 309 | p ++;
|
|---|
| 310 |
|
|---|
| 311 | /* Discard end-of-line comments; also, stop processing if
|
|---|
| 312 | the above `while' merely skipped trailing whitespace. */
|
|---|
| 313 | if (*p == '#' || !*p)
|
|---|
| 314 | break;
|
|---|
| 315 |
|
|---|
| 316 | /* If the token starts with quotation mark, note this fact,
|
|---|
| 317 | and squash the quotation character */
|
|---|
| 318 | if (*p == '"'){
|
|---|
| 319 | quote = 1;
|
|---|
| 320 | shift_left (p);
|
|---|
| 321 | }
|
|---|
| 322 |
|
|---|
| 323 | tok = p;
|
|---|
| 324 |
|
|---|
| 325 | /* Find the end of the token, handling quotes and escapes. */
|
|---|
| 326 | while (*p && (quote ? *p != '"' : !ISSPACE (*p))){
|
|---|
| 327 | if (*p == '\\')
|
|---|
| 328 | shift_left (p);
|
|---|
| 329 | p ++;
|
|---|
| 330 | }
|
|---|
| 331 |
|
|---|
| 332 | /* If field was quoted, squash the trailing quotation mark
|
|---|
| 333 | and reset quote flag. */
|
|---|
| 334 | if (quote)
|
|---|
| 335 | {
|
|---|
| 336 | shift_left (p);
|
|---|
| 337 | quote = 0;
|
|---|
| 338 | }
|
|---|
| 339 |
|
|---|
| 340 | /* Null-terminate the token, if it isn't already. */
|
|---|
| 341 | if (*p)
|
|---|
| 342 | *p ++ = '\0';
|
|---|
| 343 |
|
|---|
| 344 | switch (last_token)
|
|---|
| 345 | {
|
|---|
| 346 | case tok_login:
|
|---|
| 347 | if (current)
|
|---|
| 348 | current->acc = xstrdup (tok);
|
|---|
| 349 | else
|
|---|
| 350 | premature_token = "login";
|
|---|
| 351 | break;
|
|---|
| 352 |
|
|---|
| 353 | case tok_machine:
|
|---|
| 354 | /* Start a new machine entry. */
|
|---|
| 355 | maybe_add_to_list (¤t, &retval);
|
|---|
| 356 | current->host = xstrdup (tok);
|
|---|
| 357 | break;
|
|---|
| 358 |
|
|---|
| 359 | case tok_password:
|
|---|
| 360 | if (current)
|
|---|
| 361 | current->passwd = xstrdup (tok);
|
|---|
| 362 | else
|
|---|
| 363 | premature_token = "password";
|
|---|
| 364 | break;
|
|---|
| 365 |
|
|---|
| 366 | /* We handle most of tok_macdef above. */
|
|---|
| 367 | case tok_macdef:
|
|---|
| 368 | if (!current)
|
|---|
| 369 | premature_token = "macdef";
|
|---|
| 370 | break;
|
|---|
| 371 |
|
|---|
| 372 | /* We don't handle the account keyword at all. */
|
|---|
| 373 | case tok_account:
|
|---|
| 374 | if (!current)
|
|---|
| 375 | premature_token = "account";
|
|---|
| 376 | break;
|
|---|
| 377 |
|
|---|
| 378 | /* We handle tok_nothing below this switch. */
|
|---|
| 379 | case tok_nothing:
|
|---|
| 380 | break;
|
|---|
| 381 | }
|
|---|
| 382 |
|
|---|
| 383 | if (premature_token)
|
|---|
| 384 | {
|
|---|
| 385 | fprintf (stderr, _("\
|
|---|
| 386 | %s: %s:%d: warning: \"%s\" token appears before any machine name\n"),
|
|---|
| 387 | exec_name, path, ln, premature_token);
|
|---|
| 388 | premature_token = NULL;
|
|---|
| 389 | }
|
|---|
| 390 |
|
|---|
| 391 | if (last_token != tok_nothing)
|
|---|
| 392 | /* We got a value, so reset the token state. */
|
|---|
| 393 | last_token = tok_nothing;
|
|---|
| 394 | else
|
|---|
| 395 | {
|
|---|
| 396 | /* Fetch the next token. */
|
|---|
| 397 | if (!strcmp (tok, "account"))
|
|---|
| 398 | last_token = tok_account;
|
|---|
| 399 | else if (!strcmp (tok, "default"))
|
|---|
| 400 | {
|
|---|
| 401 | maybe_add_to_list (¤t, &retval);
|
|---|
| 402 | }
|
|---|
| 403 | else if (!strcmp (tok, "login"))
|
|---|
| 404 | last_token = tok_login;
|
|---|
| 405 |
|
|---|
| 406 | else if (!strcmp (tok, "macdef"))
|
|---|
| 407 | last_token = tok_macdef;
|
|---|
| 408 |
|
|---|
| 409 | else if (!strcmp (tok, "machine"))
|
|---|
| 410 | last_token = tok_machine;
|
|---|
| 411 |
|
|---|
| 412 | else if (!strcmp (tok, "password"))
|
|---|
| 413 | last_token = tok_password;
|
|---|
| 414 |
|
|---|
| 415 | else
|
|---|
| 416 | fprintf (stderr, _("%s: %s:%d: unknown token \"%s\"\n"),
|
|---|
| 417 | exec_name, path, ln, tok);
|
|---|
| 418 | }
|
|---|
| 419 | }
|
|---|
| 420 |
|
|---|
| 421 | xfree (line);
|
|---|
| 422 | }
|
|---|
| 423 |
|
|---|
| 424 | fclose (fp);
|
|---|
| 425 |
|
|---|
| 426 | /* Finalize the last machine entry we found. */
|
|---|
| 427 | maybe_add_to_list (¤t, &retval);
|
|---|
| 428 | xfree (current);
|
|---|
| 429 |
|
|---|
| 430 | /* Reverse the order of the list so that it appears in file order. */
|
|---|
| 431 | current = retval;
|
|---|
| 432 | retval = NULL;
|
|---|
| 433 | while (current)
|
|---|
| 434 | {
|
|---|
| 435 | acc_t *saved_reference;
|
|---|
| 436 |
|
|---|
| 437 | /* Change the direction of the pointers. */
|
|---|
| 438 | saved_reference = current->next;
|
|---|
| 439 | current->next = retval;
|
|---|
| 440 |
|
|---|
| 441 | /* Advance to the next node. */
|
|---|
| 442 | retval = current;
|
|---|
| 443 | current = saved_reference;
|
|---|
| 444 | }
|
|---|
| 445 |
|
|---|
| 446 | return retval;
|
|---|
| 447 | }
|
|---|
| 448 |
|
|---|
| 449 |
|
|---|
| 450 | /* Free a netrc list. */
|
|---|
| 451 | void
|
|---|
| 452 | free_netrc(acc_t *l)
|
|---|
| 453 | {
|
|---|
| 454 | acc_t *t;
|
|---|
| 455 |
|
|---|
| 456 | while (l)
|
|---|
| 457 | {
|
|---|
| 458 | t = l->next;
|
|---|
| 459 | xfree_null (l->acc);
|
|---|
| 460 | xfree_null (l->passwd);
|
|---|
| 461 | xfree_null (l->host);
|
|---|
| 462 | xfree (l);
|
|---|
| 463 | l = t;
|
|---|
| 464 | }
|
|---|
| 465 | }
|
|---|
| 466 |
|
|---|
| 467 | #ifdef STANDALONE
|
|---|
| 468 | #include <sys/types.h>
|
|---|
| 469 | #include <sys/stat.h>
|
|---|
| 470 |
|
|---|
| 471 | int
|
|---|
| 472 | main (int argc, char **argv)
|
|---|
| 473 | {
|
|---|
| 474 | struct_stat sb;
|
|---|
| 475 | char *program_name, *file, *target;
|
|---|
| 476 | acc_t *head, *a;
|
|---|
| 477 |
|
|---|
| 478 | if (argc < 2 || argc > 3)
|
|---|
| 479 | {
|
|---|
| 480 | fprintf (stderr, _("Usage: %s NETRC [HOSTNAME]\n"), argv[0]);
|
|---|
| 481 | exit (1);
|
|---|
| 482 | }
|
|---|
| 483 |
|
|---|
| 484 | program_name = argv[0];
|
|---|
| 485 | file = argv[1];
|
|---|
| 486 | target = argv[2];
|
|---|
| 487 |
|
|---|
| 488 | if (stat (file, &sb))
|
|---|
| 489 | {
|
|---|
| 490 | fprintf (stderr, _("%s: cannot stat %s: %s\n"), argv[0], file,
|
|---|
| 491 | strerror (errno));
|
|---|
| 492 | exit (1);
|
|---|
| 493 | }
|
|---|
| 494 |
|
|---|
| 495 | head = parse_netrc (file);
|
|---|
| 496 | a = head;
|
|---|
| 497 | while (a)
|
|---|
| 498 | {
|
|---|
| 499 | /* Skip if we have a target and this isn't it. */
|
|---|
| 500 | if (target && a->host && strcmp (target, a->host))
|
|---|
| 501 | {
|
|---|
| 502 | a = a->next;
|
|---|
| 503 | continue;
|
|---|
| 504 | }
|
|---|
| 505 |
|
|---|
| 506 | if (!target)
|
|---|
| 507 | {
|
|---|
| 508 | /* Print the host name if we have no target. */
|
|---|
| 509 | if (a->host)
|
|---|
| 510 | fputs (a->host, stdout);
|
|---|
| 511 | else
|
|---|
| 512 | fputs ("DEFAULT", stdout);
|
|---|
| 513 |
|
|---|
| 514 | fputc (' ', stdout);
|
|---|
| 515 | }
|
|---|
| 516 |
|
|---|
| 517 | /* Print the account name. */
|
|---|
| 518 | fputs (a->acc, stdout);
|
|---|
| 519 |
|
|---|
| 520 | if (a->passwd)
|
|---|
| 521 | {
|
|---|
| 522 | /* Print the password, if there is any. */
|
|---|
| 523 | fputc (' ', stdout);
|
|---|
| 524 | fputs (a->passwd, stdout);
|
|---|
| 525 | }
|
|---|
| 526 |
|
|---|
| 527 | fputc ('\n', stdout);
|
|---|
| 528 |
|
|---|
| 529 | /* Exit if we found the target. */
|
|---|
| 530 | if (target)
|
|---|
| 531 | exit (0);
|
|---|
| 532 | a = a->next;
|
|---|
| 533 | }
|
|---|
| 534 |
|
|---|
| 535 | /* Exit with failure if we had a target, success otherwise. */
|
|---|
| 536 | if (target)
|
|---|
| 537 | exit (1);
|
|---|
| 538 |
|
|---|
| 539 | exit (0);
|
|---|
| 540 | }
|
|---|
| 541 | #endif /* STANDALONE */
|
|---|