2 ** context_read.c -- find and read profile and context files
4 ** This code is Copyright (c) 2002, by the authors of nmh. See the
5 ** COPYRIGHT file in the root directory of the nmh distribution for
6 ** complete copyright information.
8 ** This function must be called early on in any nmh utility, and
9 ** may only be called once. It does the following:
11 ** o Sets the global variables to absolute paths:
12 ** - "mypath": home directory (HOME)
13 ** - "mmhpath": mmh directory (MMH)
14 ** - "defpath": profile file (MMHP)
15 ** - "ctxpath": context file (MMHC)
17 ** o Reads in the profile file. Bails out if it can't.
19 ** o Makes sure that the mail directory exists, prompting for
20 ** creation if it doesn't.
22 ** o Reads the context file.
24 ** You might need to adjust uip/mmh.sh if you make changes here.
27 #include <h/mh.h> /* mh internals */
29 #include <errno.h> /* system call errors */
30 #include <pwd.h> /* structure for getpwuid() results */
38 char buf[BUFSIZ]; /* path name buffer */
39 char *cp; /* miscellaneous pointer */
40 char *nd; /* nmh directory pointer */
41 struct stat st; /* stat() results */
42 struct passwd *pw; /* getpwuid() results */
43 FILE *ib; /* profile and context file pointer */
46 ** If this routine _is_ called again (despite the wanings in the
47 ** comments above), return immediately.
54 ** Find user's home directory. Try the HOME environment variable first,
55 ** the home directory field in the password file if that's not found.
57 if (!(mypath = getenv("HOME"))) {
58 if (!(pw = getpwuid(getuid())) || !*pw->pw_dir) {
59 adios(EX_OSERR, NULL, "cannot determine your home directory");
67 if ((cp = getenv("MMH")) && *cp) {
68 mmhpath = mh_xstrdup(expanddir(cp)); /* rel to cwd */
69 if (stat(mmhpath, &st) != -1 && (st.st_mode & S_IFDIR) == 0) {
70 adios(EX_CONFIG, NULL, "`%s' specified by your MMH environment variable is not a directory", cp);
73 mmhpath = concat(mypath, "/", mmhdir, NULL);
74 if (stat(mmhpath, &st) == -1 || (st.st_mode & S_IFDIR) == 0) {
75 adios(EX_CONFIG, NULL, "Doesn't look like mmh is set up for your account. Run `mmh' to do so.");
80 ** Find and read user's profile. Check for the existence of
81 ** a non-empty MMHP environment variable first. Look for the
82 ** profile in the mmh directory otherwise.
84 if ((cp = getenv("MMHP")) && *cp) {
86 defpath = mh_xstrdup(cp);
88 defpath = concat(mmhpath, "/", cp, NULL);
90 if (stat(defpath, &st) != -1 && (st.st_mode & S_IFREG) == 0) {
91 adios(EX_CONFIG, NULL, "Your profile `%s', specified by the MMHP environment variable, is not a normal file", cp);
93 if ((ib = fopen(defpath, "r")) == (FILE *)0) {
94 adios(EX_IOERR, NULL, "Unable to read your profile `%s', specified by the MMHP environment variable", defpath);
97 defpath = concat(mmhpath, "/", profile, NULL);
98 if ((ib = fopen(defpath, "r")) == (FILE *)0) {
99 adios(EX_CONFIG, NULL, "No profile found. Please create `%s' first.", defpath);
103 readconfig(&m_defs, ib, cp, 0);
107 ** Find the user's mail storage directory, which is specified by
108 ** the `Path' profile component. Convert a relative path name
109 ** to an absolute one rooted in the home directory.
111 if ((cp = context_find("path")) == NULL) {
112 adios(EX_CONFIG, NULL, "Your profile `%s' does not contain the required path entry.", defpath);
115 adios(EX_CONFIG, NULL, "The Path entry of your profile `%s' must be non-empty.", defpath);
120 snprintf(nd = buf, sizeof buf, "%s/%s", mypath, cp);
122 if (stat(nd, &st) == -1) {
123 if (errno != ENOENT) {
124 adios(EX_IOERR, nd, "error opening");
126 cp = concat("Your mail storage directory `", nd, "' doesn't exist; Create it? ", NULL);
127 if (!getanswer(cp)) {
128 adios(EX_NOPERM, NULL, "Unable to access the mail storage directory `%s'", nd);
132 adios(EX_CANTCREAT, nd, "unable to create");
134 } else if ((st.st_mode & S_IFDIR) == 0) {
135 adios(EX_DATAERR, NULL, "Your mail storage `%s' is not a directory", nd);
138 ** Create the default folder (inbox)
140 cp = toabsdir(defaultfolder);
141 if (stat(cp, &st) == -1) {
143 adios(EX_CANTCREAT, cp, "Unable to create the default folder");
145 } else if ((st.st_mode & S_IFDIR) == 0) {
146 adios(EX_DATAERR, NULL, "The default folder `%s' is not a directory", cp);
150 ** Open and read user's context file. The name of the context
151 ** file comes from the profile unless overridden by the MMHC
152 ** environment variable.
154 if (!(cp = getenv("MMHC")) || !*cp) {
155 if (!(cp = context_find("context")) || !*cp) {
161 ** context is NULL if the use of the context was diabled.
162 ** We also support users setting explicitly setting
163 ** MMHC to /dev/null. (If this wasn't special-cased then the
164 ** locking would be liable to fail.)
166 if (!context || (strcmp(cp, "/dev/null") == 0)) {
172 ctxpath = mh_xstrdup(cp);
174 ctxpath = concat(mmhpath, "/", cp, NULL);
176 if ((ib = lkfopen(ctxpath, "r"))) {
177 readconfig((struct node **) 0, ib, cp, 1);
178 lkfclose(ib, ctxpath);
182 if (!(cp = getenv("MMHEDITOR")) || !*cp) {
183 if (!(cp = context_find("editor")) || !*cp) {
184 if (!(cp = getenv("VISUAL")) || !*cp) {
185 if (!(cp = getenv("EDITOR")) || !*cp) {
194 if (!(cp = getenv("MMHPAGER")) || !*cp) {
195 if (!(cp = context_find("pager")) || !*cp) {
196 if (!(cp = getenv("PAGER")) || !*cp) {