/* * env.c -- small service routines * * Copyright 1998 by Eric S. Raymond * For license terms, see the file COPYING in this directory. */ #include "config.h" #include #include #if defined(STDC_HEADERS) #include #endif #if defined(HAVE_UNISTD_H) #include #endif #include #include #ifdef HAVE_NET_SOCKET_H #include #endif #include #include #include #include "fetchmail.h" #include "getaddrinfo.h" #include "i18n.h" #if defined(HAVE_SETLOCALE) && defined(ENABLE_NLS) && defined(HAVE_STRFTIME) #include #endif extern char *getenv(const char *); /* needed on sysV68 R3V7.1. */ void envquery(int argc, char **argv) /* set up basic stuff from the environment (including the rc file name) */ { struct passwd by_name, by_uid, *pwp; (void)argc; (void)argc; if (!(user = getenv("FETCHMAILUSER"))) { if (!(user = getenv("LOGNAME"))) { user = getenv("USER"); } } if ((program_name = strrchr(argv[0], '/')) != NULL) ++program_name; else program_name = argv[0]; if (getenv("QMAILINJECT") && strcmp(getenv("QMAILINJECT"), "")) { fprintf(stderr, GT_("%s: The QMAILINJECT environment variable is set.\n" "This is dangerous as it can make qmail-inject or qmail's sendmail wrapper\n" "tamper with your From: or Message-ID: headers.\n" "Try \"env QMAILINJECT= %s YOUR ARGUMENTS HERE\"\n" "%s: Abort.\n"), program_name, program_name, program_name); exit(PS_UNDEFINED); } if (getenv("NULLMAILER_FLAGS") && strcmp(getenv("NULLMAILER_FLAGS"), "")) { fprintf(stderr, GT_("%s: The NULLMAILER_FLAGS environment variable is set.\n" "This is dangerous as it can make nullmailer-inject or nullmailer's\n" "sendmail wrapper tamper with your From:, Message-ID: or Return-Path: headers.\n" "Try \"env NULLMAILER_FLAGS= %s YOUR ARGUMENTS HERE\"\n" "%s: Abort.\n"), program_name, program_name, program_name); exit(PS_UNDEFINED); } if (!(pwp = getpwuid(getuid()))) { fprintf(stderr, GT_("%s: You don't exist. Go away.\n"), program_name); exit(PS_UNDEFINED); } else { memcpy(&by_uid, pwp, sizeof(struct passwd)); if (!user || !(pwp = getpwnam(user))) pwp = &by_uid; else { /* * This logic is needed to handle gracefully the possibility * that multiple names might be mapped to one UID. */ memcpy(&by_name, pwp, sizeof(struct passwd)); if (by_name.pw_uid == by_uid.pw_uid) pwp = &by_name; else pwp = &by_uid; } user = xstrdup(pwp->pw_name); } /* compute user's home directory */ home = getenv("HOME_ETC"); if (!home && !(home = getenv("HOME"))) home = pwp->pw_dir; /* compute fetchmail's home directory */ if (!(fmhome = getenv("FETCHMAILHOME"))) fmhome = home; #define RCFILE_NAME "fetchmailrc" /* * The (fmhome==home) leaves an extra character for a . at the * beginning of the rc file's name, iff fetchmail is using $HOME * for its files. We don't want to do that if fetchmail has its * own home ($FETCHMAILHOME), however. */ rcfile = (char *)xmalloc(strlen(fmhome)+sizeof(RCFILE_NAME)+(fmhome==home)+2); /* avoid //.fetchmailrc */ if (strcmp(fmhome, "/") != 0) strcpy(rcfile, fmhome); else *rcfile = '\0'; if (rcfile[strlen(rcfile) - 1] != '/') strcat(rcfile, "/"); if (fmhome==home) strcat(rcfile, "."); strcat(rcfile, RCFILE_NAME); } char *host_fqdn(int required) { char tmpbuf[HOSTLEN+1]; char *result; if (gethostname(tmpbuf, sizeof(tmpbuf))) { fprintf(stderr, GT_("%s: can't determine your host!"), program_name); exit(PS_DNS); } /* if we got a . in the hostname assume it is a FQDN */ if (strchr(tmpbuf, '.') == NULL) { /* if we got a basename (as we do in Linux) make a FQDN of it */ struct addrinfo hints, *res; int e; memset(&hints, 0, sizeof hints); hints.ai_family = AF_UNSPEC; hints.ai_socktype = SOCK_STREAM; hints.ai_flags=AI_CANONNAME; e = getaddrinfo(tmpbuf, NULL, &hints, &res); if (e) { /* exit with error message */ fprintf(stderr, GT_("gethostbyname failed for %s\n"), tmpbuf); fprintf(stderr, "%s", gai_strerror(e)); fprintf(stderr, GT_("Cannot find my own host in hosts database to qualify it!\n")); if (required) exit(PS_DNS); else { fprintf(stderr, GT_("Trying to continue with unqualified hostname.\nDO NOT report broken Received: headers, HELO/EHLO lines or similar problems!\nDO repair your /etc/hosts, DNS,