]> diplodocus.org Git - nmh/blob - uip/install-mh.c
Makefile.am: Add test/inc/test-eom-align to XFAIL_TESTS.
[nmh] / uip / install-mh.c
1 /* install-mh.c -- initialize the nmh environment of a new user
2 *
3 * This code is Copyright (c) 2002, by the authors of nmh. See the
4 * COPYRIGHT file in the root directory of the nmh distribution for
5 * complete copyright information.
6 */
7
8 #include <h/mh.h> /* mh internals */
9 #include <h/utils.h>
10 #include "../sbr/m_maildir.h"
11 #include "../sbr/makedir.h"
12 #include <pwd.h> /* structure for getpwuid() results */
13
14 #define INSTALLMH_SWITCHES \
15 X("auto", 0, AUTOSW) \
16 X("version", 0, VERSIONSW) \
17 X("help", 0, HELPSW) \
18 X("check", 1, CHECKSW) \
19
20 #define X(sw, minchars, id) id,
21 DEFINE_SWITCH_ENUM(INSTALLMH);
22 #undef X
23
24 #define X(sw, minchars, id) { sw, minchars, id },
25 DEFINE_SWITCH_ARRAY(INSTALLMH, switches);
26 #undef X
27
28
29 int
30 main (int argc, char **argv)
31 {
32 int autof = 0;
33 char *cp, buf[BUFSIZ];
34 const char *pathname;
35 char *dp, **arguments, **argp;
36 struct node *np;
37 struct passwd *pw;
38 struct stat st;
39 FILE *in, *out;
40 int check;
41
42 if (nmh_init(argv[0], 0 /* use context_foil() */ )) { return 1; }
43
44 arguments = getarguments (invo_name, argc, argv, 0);
45 argp = arguments;
46
47 check = 0;
48
49 while ((dp = *argp++)) {
50 if (*dp == '-') {
51 switch (smatch (++dp, switches)) {
52 case AMBIGSW:
53 ambigsw (dp, switches);
54 done (1);
55 case UNKWNSW:
56 adios (NULL, "-%s unknown\n", dp);
57
58 case HELPSW:
59 snprintf (buf, sizeof(buf), "%s [switches]", invo_name);
60 print_help (buf, switches, 0);
61 done (0);
62 case VERSIONSW:
63 print_version(invo_name);
64 done (0);
65
66 case AUTOSW:
67 autof++;
68 continue;
69
70 case CHECKSW:
71 check = 1;
72 continue;
73 }
74 } else {
75 adios (NULL, "%s is invalid argument", dp);
76 }
77 }
78
79 /*
80 * Find user's home directory. Try the HOME environment variable first,
81 * the home directory field in the password file if that's not found.
82 */
83
84 if ((mypath = getenv("HOME")) == NULL) {
85 if ((pw = getpwuid(getuid())) == NULL || *pw->pw_dir == '\0')
86 adios(NULL, "cannot determine your home directory");
87 else
88 mypath = pw->pw_dir;
89 }
90
91 /*
92 * Find the user's profile. Check for the existence of an MH environment
93 * variable first with non-empty contents. Convert any relative path name
94 * found there to an absolute one. Look for the profile in the user's home
95 * directory if the MH environment variable isn't set.
96 */
97
98 if ((cp = getenv("MH")) && *cp != '\0')
99 defpath = path(cp, TFILE);
100 else
101 defpath = concat(mypath, "/", mh_profile, NULL);
102
103 /*
104 * Check for the existence of the profile file. It's an error if it exists and
105 * this isn't an installation check. An installation check fails if it does not
106 * exist, succeeds if it does.
107 */
108
109 if (stat (defpath, &st) != NOTOK) {
110 if (check)
111 done(0);
112
113 else if (autof)
114 adios (NULL, "invocation error");
115 else
116 adios (NULL, "You already have an nmh profile, use an editor to modify it");
117 }
118 else if (check) {
119 done(1);
120 }
121
122 if (!autof && read_switch ("Do you want help? ", anoyes)) {
123 (void)printf(
124 "\n"
125 "Prior to using nmh, it is necessary to have a file in your login\n"
126 "directory (%s) named %s which contains information\n"
127 "to direct certain nmh operations. The only item which is required\n"
128 "is the path to use for all nmh folder operations. The suggested nmh\n"
129 "path for you is %s/Mail...\n"
130 "\n", mypath, mh_profile, mypath);
131 }
132
133 cp = concat (mypath, "/", "Mail", NULL);
134 if (stat (cp, &st) != NOTOK) {
135 if (S_ISDIR(st.st_mode)) {
136 cp = concat ("You already have the standard nmh directory \"",
137 cp, "\".\nDo you want to use it for nmh? ", NULL);
138 if (read_switch (cp, anoyes))
139 pathname = "Mail";
140 else
141 goto query;
142 } else {
143 goto query;
144 }
145 } else {
146 if (autof)
147 puts("I'm going to create the standard nmh path for you.");
148 else
149 cp = concat ("Do you want the standard nmh path \"",
150 mypath, "/", "Mail\"? ", NULL);
151 if (autof || read_switch (cp, anoyes))
152 pathname = "Mail";
153 else {
154 query:
155 if (read_switch ("Do you want a path below your login directory? ",
156 anoyes)) {
157 printf ("What is the path? %s/", mypath);
158 pathname = read_line ();
159 if (pathname == NULL) done (1);
160 } else {
161 printf ("What is the whole path? /");
162 pathname = read_line ();
163 if (pathname == NULL) done (1);
164 pathname = concat ("/", pathname, NULL);
165 }
166 }
167 }
168
169 if (chdir (mypath) < 0) {
170 advise (mypath, "chdir");
171 }
172 if (chdir (pathname) == NOTOK) {
173 cp = concat ("\"", pathname, "\" doesn't exist; Create it? ", NULL);
174 if (autof || read_switch (cp, anoyes))
175 if (makedir (pathname) == 0)
176 adios (NULL, "unable to create %s", pathname);
177 } else {
178 puts("[Using existing directory]");
179 }
180
181 /*
182 * Add some initial elements to the profile/context list
183 */
184 NEW(np);
185 m_defs = np;
186 np->n_name = mh_xstrdup("Path");
187 np->n_field = mh_xstrdup(pathname);
188 np->n_context = 0;
189 np->n_next = NULL;
190
191 /*
192 * If there is a default profile file in the
193 * nmh `etc' directory, then read it also.
194 */
195 if ((in = fopen (mh_defaults, "r"))) {
196 readconfig (&np->n_next, in, mh_defaults, 0);
197 fclose (in);
198 }
199
200 ctxpath = getcpy (m_maildir (context = "context"));
201
202 /* Initialize current folder to default */
203 context_replace (pfolder, defaultfolder);
204 context_save ();
205
206 /*
207 * Now write out the initial .mh_profile
208 */
209 if ((out = fopen (defpath, "w")) == NULL)
210 adios (defpath, "unable to write");
211 /*
212 * The main purpose of this first line is to fool file(1).
213 * Without it, if the first line of the profile is Path:,
214 * file 5.19 reports its type as message/news. With it,
215 * it reports the type as text/plain.
216 */
217 fprintf (out, "MH-Profile-Version: 1.0\n");
218 for (np = m_defs; np; np = np->n_next) {
219 if (!np->n_context)
220 fprintf (out, "%s: %s\n", np->n_name, np->n_field);
221 }
222 fclose (out);
223
224 puts ("\nPlease see the nmh(7) man page for an introduction to nmh.\n");
225 print_intro (stdout, FALSE);
226
227 /* Initialize the saved nmh version. The Path profile entry was added
228 above, that's all this needs. */
229 (void) nmh_version_changed (0);
230
231 done (0);
232 return 1;
233 }