]> diplodocus.org Git - nmh/blob - uip/install-mh.c
Fix stupid accidental dependence on a bash quirk in previous
[nmh] / uip / install-mh.c
1 /*
2 * install-mh.c -- initialize the nmh environment of a new user
3 *
4 * $Id$
5 *
6 * This code is Copyright (c) 2002, by the authors of nmh. See the
7 * COPYRIGHT file in the root directory of the nmh distribution for
8 * complete copyright information.
9 */
10
11 #include <h/mh.h> /* mh internals */
12 #include <pwd.h> /* structure for getpwuid() results */
13
14 static struct swit switches[] = {
15 #define AUTOSW 0
16 { "auto", 0 },
17 #define VERSIONSW 1
18 { "version", 0 },
19 #define HELPSW 2
20 { "help", 0 },
21 #define CHECKSW 3
22 { "check", 1 },
23 { NULL, 0 }
24 };
25
26 /*
27 * static prototypes
28 */
29 static char *geta(void);
30
31
32 int
33 main (int argc, char **argv)
34 {
35 int autof = 0;
36 char *cp, *pathname, buf[BUFSIZ];
37 char *dp, **arguments, **argp;
38 struct node *np;
39 struct passwd *pw;
40 struct stat st;
41 FILE *in, *out;
42 int check;
43
44 #ifdef LOCALE
45 setlocale(LC_ALL, "");
46 #endif
47 invo_name = r1bindex (argv[0], '/');
48 arguments = getarguments (invo_name, argc, argv, 0);
49 argp = arguments;
50
51 check = 0;
52
53 while ((dp = *argp++)) {
54 if (*dp == '-') {
55 switch (smatch (++dp, switches)) {
56 case AMBIGSW:
57 ambigsw (dp, switches);
58 done (1);
59 case UNKWNSW:
60 adios (NULL, "-%s unknown\n", dp);
61
62 case HELPSW:
63 snprintf (buf, sizeof(buf), "%s [switches]", invo_name);
64 print_help (buf, switches, 0);
65 done (1);
66 case VERSIONSW:
67 print_version(invo_name);
68 done (1);
69
70 case AUTOSW:
71 autof++;
72 continue;
73
74 case CHECKSW:
75 check = 1;
76 continue;
77 }
78 } else {
79 adios (NULL, "%s is invalid argument", dp);
80 }
81 }
82
83 /*
84 * Find user's home directory. Try the HOME environment variable first,
85 * the home directory field in the password file if that's not found.
86 */
87
88 if ((mypath = getenv("HOME")) == (char *)0) {
89 if ((pw = getpwuid(getuid())) == (struct passwd *)0 || *pw->pw_dir == '\0')
90 adios(NULL, "cannot determine your home directory");
91 else
92 mypath = pw->pw_dir;
93 }
94
95 /*
96 * Find the user's profile. Check for the existence of an MH environment
97 * variable first with non-empty contents. Convert any relative path name
98 * found there to an absolute one. Look for the profile in the user's home
99 * directory if the MH environment variable isn't set.
100 */
101
102 if ((cp = getenv("MH")) && *cp != '\0')
103 defpath = path(cp, TFILE);
104 else
105 defpath = concat(mypath, "/", mh_profile, NULL);
106
107 /*
108 * Check for the existence of the profile file. It's an error if it exists and
109 * this isn't an installation check. An installation check fails if it does not
110 * exist, succeeds if it does.
111 */
112
113 if (stat (defpath, &st) != NOTOK) {
114 if (check)
115 done(0);
116
117 else if (autof)
118 adios (NULL, "invocation error");
119 else
120 adios (NULL, "You already have an nmh profile, use an editor to modify it");
121 }
122 else if (check) {
123 done(1);
124 }
125
126 if (!autof && gans ("Do you want help? ", anoyes)) {
127 (void)printf(
128 "\n"
129 "Prior to using nmh, it is necessary to have a file in your login\n"
130 "directory (%s) named %s which contains information\n"
131 "to direct certain nmh operations. The only item which is required\n"
132 "is the path to use for all nmh folder operations. The suggested nmh\n"
133 "path for you is %s/Mail...\n"
134 "\n", mypath, mh_profile, mypath);
135 }
136
137 cp = concat (mypath, "/", "Mail", NULL);
138 if (stat (cp, &st) != NOTOK) {
139 if (S_ISDIR(st.st_mode)) {
140 cp = concat ("You already have the standard nmh directory \"",
141 cp, "\".\nDo you want to use it for nmh? ", NULL);
142 if (gans (cp, anoyes))
143 pathname = "Mail";
144 else
145 goto query;
146 } else {
147 goto query;
148 }
149 } else {
150 if (autof)
151 printf ("I'm going to create the standard nmh path for you.\n");
152 else
153 cp = concat ("Do you want the standard nmh path \"",
154 mypath, "/", "Mail\"? ", NULL);
155 if (autof || gans (cp, anoyes))
156 pathname = "Mail";
157 else {
158 query:
159 if (gans ("Do you want a path below your login directory? ",
160 anoyes)) {
161 printf ("What is the path? %s/", mypath);
162 pathname = geta ();
163 } else {
164 printf ("What is the whole path? /");
165 pathname = concat ("/", geta (), NULL);
166 }
167 }
168 }
169
170 chdir (mypath);
171 if (chdir (pathname) == NOTOK) {
172 cp = concat ("\"", pathname, "\" doesn't exist; Create it? ", NULL);
173 if (autof || gans (cp, anoyes))
174 if (makedir (pathname) == 0)
175 adios (NULL, "unable to create %s", pathname);
176 } else {
177 printf ("[Using existing directory]\n");
178 }
179
180 /*
181 * Add some initial elements to the profile/context list
182 */
183 if (!(m_defs = (struct node *) malloc (sizeof *np)))
184 adios (NULL, "unable to allocate profile storage");
185 np = m_defs;
186 np->n_name = getcpy ("Path");
187 np->n_field = getcpy (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 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 return done (0);
217 }
218
219
220 static char *
221 geta (void)
222 {
223 char *cp;
224 static char line[BUFSIZ];
225
226 fflush(stdout);
227 if (fgets(line, sizeof(line), stdin) == NULL)
228 done (1);
229 if ((cp = strchr(line, '\n')))
230 *cp = 0;
231 return line;
232 }