1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202
|
/*
** context_read.c -- find and read profile and context files
**
** This code is Copyright (c) 2002, by the authors of nmh. See the
** COPYRIGHT file in the root directory of the nmh distribution for
** complete copyright information.
**
** This function must be called early on in any nmh utility, and
** may only be called once. It does the following:
**
** o Sets the global variables to absolute paths:
** - "mypath": home directory (HOME)
** - "mmhpath": mmh directory (MMH)
** - "defpath": profile file (MMHP)
** - "ctxpath": context file (MMHC)
**
** o Reads in the profile file. Bails out if it can't.
**
** o Makes sure that the mail directory exists, prompting for
** creation if it doesn't.
**
** o Reads the context file.
**
** You might need to adjust uip/mmh.sh if you make changes here.
*/
#include <h/mh.h> /* mh internals */
#include <h/utils.h>
#include <errno.h> /* system call errors */
#include <pwd.h> /* structure for getpwuid() results */
#include <unistd.h>
#include <sys/stat.h>
#include <sysexits.h>
void
context_read(void)
{
char buf[BUFSIZ]; /* path name buffer */
char *cp; /* miscellaneous pointer */
char *nd; /* nmh directory pointer */
struct stat st; /* stat() results */
struct passwd *pw; /* getpwuid() results */
FILE *ib; /* profile and context file pointer */
/*
** If this routine _is_ called again (despite the wanings in the
** comments above), return immediately.
*/
if (m_defs) {
return;
}
/*
** Find user's home directory. Try the HOME environment variable first,
** the home directory field in the password file if that's not found.
*/
if (!(mypath = getenv("HOME"))) {
if (!(pw = getpwuid(getuid())) || !*pw->pw_dir) {
adios(EX_OSERR, NULL, "cannot determine your home directory");
}
mypath = pw->pw_dir;
}
/*
** set mmhpath
*/
if ((cp = getenv("MMH")) && *cp) {
mmhpath = mh_xstrdup(expanddir(cp)); /* rel to cwd */
if (stat(mmhpath, &st) != -1 && (st.st_mode & S_IFDIR) == 0) {
adios(EX_CONFIG, NULL, "`%s' specified by your MMH environment variable is not a directory", cp);
}
} else {
mmhpath = concat(mypath, "/", mmhdir, NULL);
if (stat(mmhpath, &st) == -1 || (st.st_mode & S_IFDIR) == 0) {
adios(EX_CONFIG, NULL, "Doesn't look like mmh is set up for your account. Run `mmh' to do so.");
}
}
/*
** Find and read user's profile. Check for the existence of
** a non-empty MMHP environment variable first. Look for the
** profile in the mmh directory otherwise.
*/
if ((cp = getenv("MMHP")) && *cp) {
if (*cp == '/') {
defpath = mh_xstrdup(cp);
} else {
defpath = concat(mmhpath, "/", cp, NULL);
}
if (stat(defpath, &st) != -1 && (st.st_mode & S_IFREG) == 0) {
adios(EX_CONFIG, NULL, "Your profile `%s', specified by the MMHP environment variable, is not a normal file", cp);
}
if ((ib = fopen(defpath, "r")) == (FILE *)0) {
adios(EX_IOERR, NULL, "Unable to read your profile `%s', specified by the MMHP environment variable", defpath);
}
} else {
defpath = concat(mmhpath, "/", profile, NULL);
if ((ib = fopen(defpath, "r")) == (FILE *)0) {
adios(EX_CONFIG, NULL, "No profile found. Please create `%s' first.", defpath);
}
cp = profile;
}
readconfig(&m_defs, ib, cp, 0);
fclose(ib);
/*
** Find the user's mail storage directory, which is specified by
** the `Path' profile component. Convert a relative path name
** to an absolute one rooted in the home directory.
*/
if ((cp = context_find("path")) == NULL) {
adios(EX_CONFIG, NULL, "Your profile `%s' does not contain the required path entry.", defpath);
}
if (!*cp) {
adios(EX_CONFIG, NULL, "The Path entry of your profile `%s' must be non-empty.", defpath);
}
if (*cp == '/') {
nd = cp;
} else {
snprintf(nd = buf, sizeof buf, "%s/%s", mypath, cp);
}
if (stat(nd, &st) == -1) {
if (errno != ENOENT) {
adios(EX_IOERR, nd, "error opening");
}
cp = concat("Your mail storage directory `", nd, "' doesn't exist; Create it? ", NULL);
if (!getanswer(cp)) {
adios(EX_NOPERM, NULL, "Unable to access the mail storage directory `%s'", nd);
}
mh_free0(&cp);
if (!makedir(nd)) {
adios(EX_CANTCREAT, nd, "unable to create");
}
} else if ((st.st_mode & S_IFDIR) == 0) {
adios(EX_DATAERR, NULL, "Your mail storage `%s' is not a directory", nd);
}
/*
** Create the default folder (inbox)
*/
cp = toabsdir(getdeffol());
if (stat(cp, &st) == -1) {
if (!makedir(cp)) {
adios(EX_CANTCREAT, cp, "Unable to create the default folder");
}
} else if ((st.st_mode & S_IFDIR) == 0) {
adios(EX_DATAERR, NULL, "The default folder `%s' is not a directory", cp);
}
/*
** Open and read user's context file. The name of the context
** file comes from the profile unless overridden by the MMHC
** environment variable.
*/
if (!(cp = getenv("MMHC")) || !*cp) {
if (!(cp = context_find("context")) || !*cp) {
cp = context;
}
}
/*
** context is NULL if the use of the context was diabled.
** We also support users setting explicitly setting
** MMHC to /dev/null. (If this wasn't special-cased then the
** locking would be liable to fail.)
*/
if (!context || (strcmp(cp, "/dev/null") == 0)) {
ctxpath = NULL;
return;
}
if (*cp == '/') {
ctxpath = mh_xstrdup(cp);
} else {
ctxpath = concat(mmhpath, "/", cp, NULL);
}
if ((ib = lkfopen(ctxpath, "r"))) {
readconfig((struct node **) 0, ib, cp, 1);
lkfclose(ib, ctxpath);
}
/* Set editor */
if (!(cp = getenv("MMHEDITOR")) || !*cp) {
if (!(cp = context_find("editor")) || !*cp) {
if (!(cp = getenv("VISUAL")) || !*cp) {
if (!(cp = getenv("EDITOR")) || !*cp) {
cp = defaulteditor;
}
}
}
}
defaulteditor = cp;
/* Set pager */
if (!(cp = getenv("MMHPAGER")) || !*cp) {
if (!(cp = context_find("pager")) || !*cp) {
if (!(cp = getenv("PAGER")) || !*cp) {
cp = defaultpager;
}
}
}
defaultpager = cp;
}
|