Removed the space between function names and the opening parenthesis.
[mmh] / 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(1);
65                                 case VERSIONSW:
66                                         print_version(invo_name);
67                                         done(1);
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
84         ** variable first, the home directory field in the password file
85         ** if that's not found.
86         */
87
88         if ((mypath = getenv("HOME")) == (char *)0) {
89                 if ((pw = getpwuid(getuid())) == (struct passwd *)0 ||
90                                 *pw->pw_dir == '\0')
91                         adios(NULL, "cannot determine your home directory");
92                 else
93                         mypath = pw->pw_dir;
94         }
95
96         /*
97         ** Find the user's profile.  Check for the existence of an
98         ** MH environment variable first with non-empty contents.
99         ** Convert any relative path name found there to an absolute one.
100         ** Look for the profile in the user's home directory if the MH
101         ** environment variable isn't set.
102         */
103
104         if ((cp = getenv("MH")) && *cp != '\0')
105                 defpath = path(cp, TFILE);
106         else
107                 defpath = concat(mypath, "/", mh_profile, NULL);
108
109         /*
110         ** Check for the existence of the profile file.  It's an
111         ** error if it exists and this isn't an installation check.
112         ** An installation check fails if it does not exist, succeeds
113         ** if it does.
114         */
115
116         if (stat(defpath, &st) != NOTOK) {
117                 if (check)
118                         done(0);
119
120                 else if (autof)
121                         adios(NULL, "invocation error");
122                 else
123                         adios(NULL, "You already have an nmh profile, use an editor to modify it");
124         } else if (check) {
125                 done(1);
126         }
127
128         if (!autof && gans("Do you want help? ", anoyes)) {
129                 (void)printf(
130                  "\n"
131                  "Prior to using nmh, it is necessary to have a file in your login\n"
132                  "directory (%s) named %s which contains information\n"
133                  "to direct certain nmh operations.  The only item which is required\n"
134                  "is the path to use for all nmh folder operations.  The suggested nmh\n"
135                  "path for you is %s/Mail...\n"
136                  "\n", mypath, mh_profile, mypath);
137         }
138
139         cp = concat(mypath, "/", "Mail", NULL);
140         if (stat(cp, &st) != NOTOK) {
141                 if (S_ISDIR(st.st_mode)) {
142                         cp = concat("You already have the standard nmh directory \"",
143                                 cp, "\".\nDo you want to use it for nmh? ", NULL);
144                         if (gans(cp, anoyes))
145                                 pathname = "Mail";
146                         else
147                                 goto query;
148                 } else {
149                         goto query;
150                 }
151         } else {
152                 if (autof)
153                         printf("I'm going to create the standard nmh path for you.\n");
154                 else
155                         cp = concat("Do you want the standard nmh path \"",
156                                         mypath, "/", "Mail\"? ", NULL);
157                 if (autof || gans(cp, anoyes))
158                         pathname = "Mail";
159                 else {
160 query:
161                         if (gans("Do you want a path below your login directory? ", anoyes)) {
162                                 printf("What is the path?  %s/", mypath);
163                                 pathname = geta();
164                         } else {
165                                 printf("What is the whole path?  /");
166                                 pathname = concat("/", geta(), NULL);
167                         }
168                 }
169         }
170
171         chdir(mypath);
172         if (chdir(pathname) == NOTOK) {
173                 cp = concat("\"", pathname, "\" doesn't exist; Create it? ",
174                                 NULL);
175                 if (autof || gans(cp, anoyes))
176                         if (makedir(pathname) == 0)
177                                 adios(NULL, "unable to create %s", pathname);
178         } else {
179                 printf("[Using existing directory]\n");
180         }
181
182         /*
183         ** Add some initial elements to the profile/context list
184         */
185         m_defs = (struct node *) mh_xmalloc(sizeof *np);
186         np = m_defs;
187         np->n_name = getcpy("Path");
188         np->n_field = getcpy(pathname);
189         np->n_context = 0;
190         np->n_next = NULL;
191
192         /*
193         ** If there is a default profile file in the
194         ** nmh `etc' directory, then read it also.
195         */
196         if ((in = fopen(mh_defaults, "r"))) {
197                 readconfig(&np->n_next, in, mh_defaults, 0);
198                 fclose(in);
199         }
200
201         ctxpath = getcpy(m_maildir(context = "context"));
202
203         /* Initialize current folder to default */
204         context_replace(pfolder, defaultfolder);
205         context_save();
206
207         /*
208         ** Now write out the initial .mh_profile
209         */
210         if ((out = fopen(defpath, "w")) == NULL)
211                 adios(defpath, "unable to write");
212         for (np = m_defs; np; np = np->n_next) {
213                 if (!np->n_context)
214                         fprintf(out, "%s: %s\n", np->n_name, np->n_field);
215         }
216         fclose(out);
217         done(0);
218         return 1;
219 }
220
221
222 static char *
223 geta(void)
224 {
225         char *cp;
226         static char line[BUFSIZ];
227
228         fflush(stdout);
229         if (fgets(line, sizeof(line), stdin) == NULL)
230                 done(1);
231         if ((cp = strchr(line, '\n')))
232                 *cp = 0;
233         return line;
234 }