ff50d359df21e334de9d89374b2d6bbc7c79ffb9
[mmh] / uip / install-mh.c
1
2 /*
3  * install-mh.c -- initialize the nmh environment of a new user
4  *
5  * $Id$
6  *
7  * This code is Copyright (c) 2002, by the authors of nmh.  See the
8  * COPYRIGHT file in the root directory of the nmh distribution for
9  * complete copyright information.
10  */
11
12 #include <h/mh.h>
13 #include <pwd.h>
14
15 static struct swit switches[] = {
16 #define AUTOSW     0
17     { "auto", 0 },
18 #define VERSIONSW  1
19     { "version", 0 },
20 #define HELPSW     2
21     { "help", 0 },
22     { NULL, 0 }
23 };
24
25 static char *message[] = {
26     "Prior to using nmh, it is necessary to have a file in your login",
27     "directory (%s) named %s which contains information",
28     "to direct certain nmh operations.  The only item which is required",
29     "is the path to use for all nmh folder operations.  The suggested nmh",
30     "path for you is %s/Mail...",
31     NULL
32 };
33
34 /*
35  * static prototypes
36  */
37 static char *geta(void);
38
39
40 int
41 main (int argc, char **argv)
42 {
43     int i, autof = 0;
44     char *cp, *path, buf[BUFSIZ];
45     char *dp, **arguments, **argp;
46     struct node *np;
47     struct passwd *pw;
48     struct stat st;
49     FILE *in, *out;
50
51 #ifdef LOCALE
52     setlocale(LC_ALL, "");
53 #endif
54     invo_name = r1bindex (argv[0], '/');
55     arguments = getarguments (invo_name, argc, argv, 0);
56     argp = arguments;
57
58     while ((dp = *argp++)) {
59         if (*dp == '-') {
60             switch (smatch (++dp, switches)) {
61                 case AMBIGSW:
62                     ambigsw (dp, switches);
63                     done (1);
64                 case UNKWNSW:
65                     adios (NULL, "-%s unknown\n", dp);
66
67                 case HELPSW:
68                     snprintf (buf, sizeof(buf), "%s [switches]", invo_name);
69                     print_help (buf, switches, 0);
70                     done (1);
71                 case VERSIONSW:
72                     print_version(invo_name);
73                     done (1);
74
75                 case AUTOSW:
76                     autof++;
77                     continue;
78             }
79         } else {
80             adios (NULL, "%s is invalid argument", dp);
81         }
82     }
83
84     /* straight from context_read ... */
85     if (mypath == NULL) {
86         if ((mypath = getenv ("HOME"))) {
87             mypath = getcpy (mypath);
88         } else {
89             if ((pw = getpwuid (getuid ())) == NULL
90                     || pw->pw_dir == NULL
91                     || *pw->pw_dir == 0)
92                 adios (NULL, "no HOME envariable");
93             else
94                 mypath = getcpy (pw->pw_dir);
95         }
96         if ((cp = mypath + strlen (mypath) - 1) > mypath && *cp == '/')
97             *cp = 0;
98     }
99     defpath = concat (mypath, "/", mh_profile, NULL);
100
101     if (stat (defpath, &st) != NOTOK) {
102         if (autof)
103             adios (NULL, "invocation error");
104         else
105             adios (NULL,
106                     "You already have an nmh profile, use an editor to modify it");
107     }
108
109     if (!autof && gans ("Do you want help? ", anoyes)) {
110         putchar ('\n');
111         for (i = 0; message[i]; i++) {
112             printf (message[i], mypath, mh_profile);
113             putchar ('\n');
114         }
115         putchar ('\n');
116     }
117
118     cp = concat (mypath, "/", "Mail", NULL);
119     if (stat (cp, &st) != NOTOK) {
120         if (S_ISDIR(st.st_mode)) {
121             cp = concat ("You already have the standard nmh directory \"",
122                     cp, "\".\nDo you want to use it for nmh? ", NULL);
123             if (gans (cp, anoyes))
124                 path = "Mail";
125             else
126                 goto query;
127         } else {
128             goto query;
129         }
130     } else {
131         if (autof)
132             printf ("I'm going to create the standard nmh path for you.\n");
133         else
134             cp = concat ("Do you want the standard nmh path \"",
135                     mypath, "/", "Mail\"? ", NULL);
136         if (autof || gans (cp, anoyes))
137             path = "Mail";
138         else {
139 query:
140             if (gans ("Do you want a path below your login directory? ",
141                         anoyes)) {
142                 printf ("What is the path?  %s/", mypath);
143                 path = geta ();
144             } else {
145                 printf ("What is the whole path?  /");
146                 path = concat ("/", geta (), NULL);
147             }
148         }
149     }
150
151     chdir (mypath);
152     if (chdir (path) == NOTOK) {
153         cp = concat ("\"", path, "\" doesn't exist; Create it? ", NULL);
154         if (autof || gans (cp, anoyes))
155             if (makedir (path) == 0)
156                 adios (NULL, "unable to create %s", path);
157     } else {
158         printf ("[Using existing directory]\n");
159     }
160
161     /*
162      * Add some initial elements to the profile/context list
163      */
164     if (!(m_defs = (struct node *) malloc (sizeof *np)))
165         adios (NULL, "unable to allocate profile storage");
166     np = m_defs;
167     np->n_name = getcpy ("Path");
168     np->n_field = getcpy (path);
169     np->n_context = 0;
170     np->n_next = NULL;
171
172     /*
173      * If there is a default profile file in the
174      * nmh `etc' directory, then read it also.
175      */
176     if ((in = fopen (mh_defaults, "r"))) {
177         readconfig (&np->n_next, in, mh_defaults, 0);
178         fclose (in);
179     }
180
181     ctxpath = getcpy (m_maildir (context = "context"));
182
183     /* Initialize current folder to default */
184     context_replace (pfolder, defaultfolder);
185     context_save ();
186
187     /*
188      * Now write out the initial .mh_profile
189      */
190     if ((out = fopen (defpath, "w")) == NULL)
191         adios (defpath, "unable to write");
192     for (np = m_defs; np; np = np->n_next) {
193         if (!np->n_context)
194             fprintf (out, "%s: %s\n", np->n_name, np->n_field);
195     }
196     fclose (out);
197     return done (0);
198 }
199
200
201 static char *
202 geta (void)
203 {
204     char *cp;
205     static char line[BUFSIZ];
206
207     fflush(stdout);
208     if (fgets(line, sizeof(line), stdin) == NULL)
209         done (1);
210     if ((cp = strchr(line, '\n')))
211         *cp = 0;
212     return line;
213 }