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