]> diplodocus.org Git - nmh/blob - uip/install-mh.c
picksbr.c: Specify parameters of nexus's n_action function pointer.
[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 mypath = pw->pw_dir;
88 }
89
90 /*
91 * Find the user's profile. Check for the existence of an MH environment
92 * variable first with non-empty contents. Convert any relative path name
93 * found there to an absolute one. Look for the profile in the user's home
94 * directory if the MH environment variable isn't set.
95 */
96
97 if ((cp = getenv("MH")) && *cp != '\0')
98 defpath = path(cp, TFILE);
99 else
100 defpath = concat(mypath, "/", mh_profile, NULL);
101
102 /*
103 * Check for the existence of the profile file. It's an error if it exists and
104 * this isn't an installation check. An installation check fails if it does not
105 * exist, succeeds if it does.
106 */
107
108 if (stat (defpath, &st) != NOTOK) {
109 if (check)
110 done(0);
111 if (autof)
112 adios (NULL, "invocation error");
113 adios (NULL, "You already have an nmh profile, use an editor to modify it");
114 }
115 if (check)
116 done(1);
117
118 if (!autof && read_switch ("Do you want help? ", anoyes)) {
119 (void)printf(
120 "\n"
121 "Prior to using nmh, it is necessary to have a file in your login\n"
122 "directory (%s) named %s which contains information\n"
123 "to direct certain nmh operations. The only item which is required\n"
124 "is the path to use for all nmh folder operations. The suggested nmh\n"
125 "path for you is %s/Mail...\n"
126 "\n", mypath, mh_profile, mypath);
127 }
128
129 cp = concat (mypath, "/", "Mail", NULL);
130 if (stat (cp, &st) != NOTOK) {
131 if (!S_ISDIR(st.st_mode))
132 goto query;
133 cp = concat ("You already have the standard nmh directory \"",
134 cp, "\".\nDo you want to use it for nmh? ", NULL);
135 if (!read_switch (cp, anoyes))
136 goto query;
137 pathname = "Mail";
138 } else {
139 if (autof)
140 puts("I'm going to create the standard nmh path for you.");
141 else
142 cp = concat ("Do you want the standard nmh path \"",
143 mypath, "/", "Mail\"? ", NULL);
144 if (autof || read_switch (cp, anoyes))
145 pathname = "Mail";
146 else {
147 query:
148 if (read_switch ("Do you want a path below your login directory? ",
149 anoyes)) {
150 printf ("What is the path? %s/", mypath);
151 pathname = read_line ();
152 if (pathname == NULL) done (1);
153 } else {
154 printf ("What is the whole path? /");
155 pathname = read_line ();
156 if (pathname == NULL) done (1);
157 pathname = concat ("/", pathname, NULL);
158 }
159 }
160 }
161
162 if (chdir (mypath) < 0) {
163 advise (mypath, "chdir");
164 }
165 if (chdir (pathname) == NOTOK) {
166 cp = concat ("\"", pathname, "\" doesn't exist; Create it? ", NULL);
167 if (autof || read_switch (cp, anoyes))
168 if (makedir (pathname) == 0)
169 adios (NULL, "unable to create %s", pathname);
170 } else {
171 puts("[Using existing directory]");
172 }
173
174 /*
175 * Add some initial elements to the profile/context list
176 */
177 NEW(np);
178 m_defs = np;
179 np->n_name = mh_xstrdup("Path");
180 np->n_field = mh_xstrdup(pathname);
181 np->n_context = 0;
182 np->n_next = NULL;
183
184 /*
185 * If there is a default profile file in the
186 * nmh `etc' directory, then read it also.
187 */
188 if ((in = fopen (mh_defaults, "r"))) {
189 readconfig (&np->n_next, in, mh_defaults, 0);
190 fclose (in);
191 }
192
193 ctxpath = getcpy (m_maildir (context = "context"));
194
195 /* Initialize current folder to default */
196 context_replace (pfolder, defaultfolder);
197 context_save ();
198
199 /*
200 * Now write out the initial .mh_profile
201 */
202 if ((out = fopen (defpath, "w")) == NULL)
203 adios (defpath, "unable to write");
204 /*
205 * The main purpose of this first line is to fool file(1).
206 * Without it, if the first line of the profile is Path:,
207 * file 5.19 reports its type as message/news. With it,
208 * it reports the type as text/plain.
209 */
210 fprintf (out, "MH-Profile-Version: 1.0\n");
211 for (np = m_defs; np; np = np->n_next) {
212 if (!np->n_context)
213 fprintf (out, "%s: %s\n", np->n_name, np->n_field);
214 }
215 fclose (out);
216
217 puts ("\nPlease see the nmh(7) man page for an introduction to nmh.\n");
218 print_intro (stdout, FALSE);
219
220 /* Initialize the saved nmh version. The Path profile entry was added
221 above, that's all this needs. */
222 (void) nmh_version_changed (0);
223
224 done (0);
225 return 1;
226 }