]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - release/sysinstall/register.c
Some of my pending merge changes, Paul Traina's more flexible config
[FreeBSD/FreeBSD.git] / release / sysinstall / register.c
1 /*
2  * The new sysinstall program.
3  *
4  * This is probably the last program in the `sysinstall' line - the next
5  * generation being essentially a complete rewrite.
6  *
7  * $Id: register.c,v 1.4 1997/03/15 16:24:31 jkh Exp $
8  *
9  * Copyright (c) 1997
10  *      Jordan Hubbard.  All rights reserved.
11  *
12  * Redistribution and use in source and binary forms, with or without
13  * modification, are permitted provided that the following conditions
14  * are met:
15  * 1. Redistributions of source code must retain the above copyright
16  *    notice, this list of conditions and the following disclaimer,
17  *    verbatim and that no modifications are made prior to this
18  *    point in the file.
19  * 2. Redistributions in binary form must reproduce the above copyright
20  *    notice, this list of conditions and the following disclaimer in the
21  *    documentation and/or other materials provided with the distribution.
22  *
23  * THIS SOFTWARE IS PROVIDED BY JORDAN HUBBARD ``AS IS'' AND
24  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
25  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
26  * ARE DISCLAIMED.  IN NO EVENT SHALL JORDAN HUBBARD OR HIS PETS BE LIABLE
27  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
28  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
29  * OR SERVICES; LOSS OF USE, DATA, LIFE OR PROFITS; OR BUSINESS INTERRUPTION)
30  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
31  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
32  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
33  * SUCH DAMAGE.
34  *
35  */
36
37 #include "sysinstall.h"
38 #include <ctype.h>
39
40 #define REGISTER_HELPFILE       "register"
41 #define REGISTRATION_FNAME      "/new-registration"
42 #define REGISTRATION_ADDRESS    "register@freebsd.org"
43 #define MAJORDOMO_ADDRESS       "majordomo@freebsd.org"
44
45 #define FIRSTNAME_FIELD_LEN     25
46 #define LASTNAME_FIELD_LEN      30
47 #define EMAIL_FIELD_LEN         61
48 #define ADDRESS_FIELD_LEN       160
49 #define CITY_FIELD_LEN          20
50 #define STATE_FIELD_LEN         15
51 #define ZIP_FIELD_LEN           15
52
53 static char firstname[FIRSTNAME_FIELD_LEN], lastname[LASTNAME_FIELD_LEN],
54     email[EMAIL_FIELD_LEN], address[ADDRESS_FIELD_LEN],
55     city[CITY_FIELD_LEN], state[STATE_FIELD_LEN], zip[ZIP_FIELD_LEN];
56
57 static int      okbutton, cancelbutton;
58
59 /* What the screen size is meant to be */
60 #define REGISTER_DIALOG_Y               0
61 #define REGISTER_DIALOG_X               2
62 #define REGISTER_DIALOG_WIDTH           COLS - 4
63 #define REGISTER_DIALOG_HEIGHT          LINES - 2
64
65 static Layout layout[] = {
66 #define LAYOUT_LASTNAME         0
67     { 1, 2, LASTNAME_FIELD_LEN - 1, LASTNAME_FIELD_LEN - 1,
68       "Last Name:", "Your surname (family name) or company name should go here.",
69       lastname, STRINGOBJ, NULL },
70 #define LAYOUT_FIRSTNAME        1
71     { 1, 36, FIRSTNAME_FIELD_LEN - 1, FIRSTNAME_FIELD_LEN - 1,
72       "First Name:", "Your given name or a contact name if registering for a company.",
73       firstname, STRINGOBJ, NULL },
74 #define LAYOUT_EMAIL            2
75     { 6, 2, EMAIL_FIELD_LEN - 1, EMAIL_FIELD_LEN - 1,
76       "EMail Address:",
77       "Where you'd like any announcement email sent, e.g. bsdmail@someplace.com",
78       email, STRINGOBJ, NULL },
79 #define LAYOUT_ADDRESS          3
80     { 10, 2, 60, ADDRESS_FIELD_LEN - 1,
81       "Street address:", "Your street address, all in one line (optional).",
82       address, STRINGOBJ, NULL },
83 #define LAYOUT_CITY             4
84     { 14, 2, CITY_FIELD_LEN - 1, CITY_FIELD_LEN - 1,
85       "City:", "Your city name (optional)",
86       city, STRINGOBJ, NULL },
87 #define LAYOUT_STATE            5
88     { 14, 26, STATE_FIELD_LEN - 1, STATE_FIELD_LEN - 1,
89       "State / Province:",
90       "Your local state or province.",
91       state, STRINGOBJ, NULL },
92 #define LAYOUT_ZIP              5
93     { 14, 50, ZIP_FIELD_LEN - 1, ZIP_FIELD_LEN - 1,
94       "Zip / Country Code:",
95       "Your U.S. Zip code or International country code (optional).",
96       zip, STRINGOBJ, NULL },
97 #define LAYOUT_OKBUTTON         7
98     { 18, 20, 0, 0,
99       "OK", "Select this if you are happy with these settings",
100       &okbutton, BUTTONOBJ, NULL },
101 #define LAYOUT_CANCELBUTTON     8
102     { 18, 40, 0, 0,
103       "CANCEL", "Select this if you wish to cancel this registration",
104       &cancelbutton, BUTTONOBJ, NULL },
105     { NULL },
106 };
107
108 /* Submenu selections */
109 #define COMMERCE_MAIL   0
110 #define COMMERCE_EMAIL  1
111 #define ANNOUNCE_LIST   2
112 #define NEWSLETTER      3
113
114 static struct { int y, x, sel; char *desc, *allowed; } hotspots[] = {
115     { 5, 35, 0, "Do you wish to receive FreeBSD [ONLY!] related commercial mail?",         "Y" },
116     { 5, 57, 0, "Do you wish to receive FreeBSD [ONLY!] related commercial email?",        "Y" },
117     { 6, 35, 0, "Sign up (with majordomo@FreeBSD.org) for important announcements?",       "Y" },
118     { 10, 35, 0, "Sign up for the FreeBSD Newsletter?  P = Postal (paper) copy, E = Email", "PE" },
119 };
120
121 /* Check the accuracy of user's choices before letting them move on */
122 static int
123 verifySettings(void)
124 {
125     if (!lastname[0]) {
126         msgConfirm("Missing last name / company name field.");
127         return 0;
128     }
129     else if (email[0] && !index(email, '@'))
130         return !msgYesNo("Hmmmm, this email address has no `@' in it.  Are you\n"
131                          "sure that %s is a valid address?");
132     else if (address[0] && !city[0]) {
133         msgConfirm("Missing City name.");
134         return 0;
135     }
136     else if (!email[0] && (hotspots[COMMERCE_EMAIL].sel || hotspots[NEWSLETTER].sel == 2)) {
137         msgConfirm("You've signed up to receive commercial email or the newsletter by\n"
138                    "email but have no email address specified!");
139         return 0;
140     }
141     else if (!address[0] && (hotspots[COMMERCE_MAIL].sel || hotspots[NEWSLETTER].sel == 1)) {
142         msgConfirm("You've signed up to receive commercial mail or the newsletter by\n"
143                    "post but have no postal address specified!");
144         return 0;
145     }
146     return 1;
147 }
148
149 /* Do the actual work of mailing out the registration once all is filled in */
150 static void
151 handle_registration(void)
152 {
153     FILE *fp;
154     WINDOW *save = savescr();
155
156     dialog_clear_norefresh();
157     (void)unlink(REGISTRATION_FNAME);
158     fp = fopen(REGISTRATION_FNAME, "w");
159     if (!fp) {
160         msgConfirm("Unable to open %s for the new registration.\n"
161                    "That's pretty bad!  Please fix whatever's wrong\n"
162                    "and try this registration again.");
163         restorescr(save);
164         return;
165     }
166     fprintf(fp, "<entry>\n");
167     fprintf(fp, "<first>%s</first>\n", firstname);
168     fprintf(fp, "<last>%s</last>\n", lastname);
169     fprintf(fp, "<email>%s</email>\n", email);
170     fprintf(fp, "<address>%s</address>\n", address);
171     fprintf(fp, "<city>%s</city>\n", city);
172     fprintf(fp, "<state>%s</state>\n", state);
173     fprintf(fp, "<zip>%s</zip>\n", zip);
174     fprintf(fp, "<options commerce_email=\"%s\" commerce_mail=\"%s\" announce=\"%s\" newsletter=\"%s\"></options>\n",
175             hotspots[COMMERCE_EMAIL].sel ? "yes" : "no", hotspots[COMMERCE_MAIL].sel ? "yes" : "no",
176             hotspots[ANNOUNCE_LIST].sel ? "yes" : "no",
177             hotspots[NEWSLETTER].sel == 0 ? "no" : hotspots[NEWSLETTER].sel == 1 ? "postal" : "email"); 
178     fprintf(fp, "<version>%s</version>\n", RELEASE_NAME);
179     fprintf(fp, "</entry>\n");
180     fclose(fp);
181     if (!msgYesNo("Do you have a working network connection and outgoing email\n"
182                   "enabled at this time?  I need to be able to reach freebsd.org\n"
183                   "in order to submit your registration.")) {
184         if (!vsystem("mail %s < %s", REGISTRATION_ADDRESS, REGISTRATION_FNAME)) {
185             msgConfirm("Thank you!  Your registration has been sent in successfully.\n");
186             (void)unlink(REGISTRATION_FNAME);
187         }
188         else {
189             msgConfirm("Argh!  The mail program returned a bad status - there\n"
190                        "must be something still not quite configured correctly.\n"
191                        "leaving the registration in: %s\n"
192                        "When you're connected to the net and ready to send it,\n"
193                        "simply type:  mail %s < %s\n", REGISTRATION_ADDRESS, REGISTRATION_FNAME,
194                        REGISTRATION_FNAME);
195         }
196         if (hotspots[ANNOUNCE_LIST].sel) {
197             char *cp;
198             
199             cp = msgGetInput(email, "What email address would you like to subscribe under?\n"
200                              "This is a fairly low-traffic mailing list and only generates\n"
201                              "around 5 messages a month, so it's also safe to receive at your\n"
202                              "standard email address.");
203             if (!cp)
204                 msgConfirm("OK, I won't subscribe to announce at this time.  To do it manually\n"
205                            "yourself, simply send mail to %s.", MAJORDOMO_ADDRESS);
206             else {
207                 if (!vsystem("echo subscribe freebsd-announce %s | mail %s", email, MAJORDOMO_ADDRESS))
208                     msgConfirm("Your request to join the announce mailing list has been sent.\n"
209                               "you should receive notification back in 24 hours or less, otherwise\n"
210                               "something has gone wrong and you should try this again by sending\n"
211                               "a message to %s which contains the line:\n\n"
212                               "subscribe freebsd-announce %s\n", MAJORDOMO_ADDRESS, email);
213                 else
214                     msgConfirm("Argh!  The mail program returned a bad status - there\n"
215                                "must be something still not quite configured correctly.\n"
216                                "Please fix this then try again by sending a message to\n"
217                                "to %s which contains the line:\n\n"
218                                "subscribe freebsd-announce %s\n", MAJORDOMO_ADDRESS, email);
219             }
220         }
221     }
222     else {
223         msgConfirm("OK, your registration has been left in the file %s\n"
224                    "When you're connected to the net and ready to send it,\n"
225                    "simply type:  mail %s < %s\n", REGISTRATION_FNAME,
226                    REGISTRATION_ADDRESS, REGISTRATION_FNAME);
227     }
228     restorescr(save);
229 }
230
231 /* Put up a subdialog for the registration options */
232 static void
233 subdialog(WINDOW *win)
234 {
235     int i, j, attrs;
236     char help_line[80];
237
238     attrs = getattrs(win);
239     mvwaddstr(win, hotspots[COMMERCE_MAIL].y, hotspots[COMMERCE_MAIL].x - 1, "[ ] Postal Adverts");
240     mvwaddstr(win, hotspots[COMMERCE_EMAIL].y, hotspots[COMMERCE_EMAIL].x - 1, "[ ] Email Adverts");
241     mvwaddstr(win, hotspots[ANNOUNCE_LIST].y, hotspots[ANNOUNCE_LIST].x - 1,
242               "[ ] The announce@FreeBSD.ORG mailing list.");
243     mvwaddstr(win, hotspots[NEWSLETTER].y, hotspots[NEWSLETTER].x - 1, "[ ] The FreeBSD Newsletter.");
244     /* Tack up the initial values */
245     for (i = 0; i < sizeof(hotspots) / sizeof(hotspots[0]); i++) {
246         wattrset(win, attrs | A_BOLD);
247         mvwaddch(win, hotspots[i].y, hotspots[i].x, hotspots[i].sel ? hotspots[i].allowed[hotspots[i].sel - 1] : 'N');
248     }
249     wattrset(win, attrs);
250     wrefresh(win);
251
252     for (i = 0; i < sizeof(hotspots) / sizeof(hotspots[0]);) {
253         int ch, len = strlen(hotspots[i].desc);
254         char *cp;
255
256         /* Display the help line at the bottom of the screen */
257         for (j = 0; j < 79; j++)
258             help_line[j] = (j < len) ? hotspots[i].desc[j] : ' ';
259         help_line[j] = '\0';
260         use_helpline(help_line);
261         display_helpline(win, LINES - 1, COLS - 1);
262         wmove(win, hotspots[i].y, hotspots[i].x);
263         wrefresh(win);
264         switch(ch = toupper(getch())) {
265         case KEY_UP:
266                 if (i)
267                     i--;
268                 continue;
269
270         case KEY_DOWN:
271         case '\011':    /* TAB */
272         case '\012':    /* ^J */
273         case '\014':    /* ^M */
274             /* Treat as a no-change op */
275             ++i;
276             break;
277
278         case 'N':       /* No is generic to all */
279             hotspots[i].sel = 0;
280             wattrset(win, attrs | A_BOLD);
281             mvwaddch(win, hotspots[i].y, hotspots[i].x, 'N');
282             wattrset(win, attrs);
283             wrefresh(win);
284             ++i;
285             break;
286
287         default:
288             cp = index(hotspots[i].allowed, ch);
289             if (cp) {
290                 hotspots[i].sel = (cp - hotspots[i].allowed) + 1;
291                 wattrset(win, attrs | A_BOLD);
292                 mvwaddch(win, hotspots[i].y, hotspots[i].x, *cp);
293                 wattrset(win, attrs);
294                 wrefresh(win);
295                 ++i;
296             }
297             else
298                 beep();
299             break;
300         }
301     }
302 }
303
304 /* Register a user */
305 int
306 registerOpenDialog(void)
307 {
308     WINDOW              *ds_win, *save = savescr();
309     ComposeObj          *obj = NULL;
310     int                 n = 0, cancel = FALSE;
311     int                 max, ret = DITEM_SUCCESS;
312
313     dialog_clear_norefresh();
314     /* We need a curses window */
315     if (!(ds_win = openLayoutDialog(REGISTER_HELPFILE, " FreeBSD Registration Form:  Press F1 for Help / General Info ",
316                                     REGISTER_DIALOG_X, REGISTER_DIALOG_Y,
317                                     REGISTER_DIALOG_WIDTH, REGISTER_DIALOG_HEIGHT))) {
318         beep();
319         msgConfirm("Cannot open registration dialog window!!");
320         restorescr(save);
321         return DITEM_FAILURE;
322     }
323
324     /* Some more initialisation before we go into the main input loop */
325     obj = initLayoutDialog(ds_win, layout, REGISTER_DIALOG_X, REGISTER_DIALOG_Y, &max);
326
327 reenter:
328     cancelbutton = okbutton = 0;
329     while (layoutDialogLoop(ds_win, layout, &obj, &n, max, &cancelbutton, &cancel)) {
330         if (n == LAYOUT_ADDRESS)
331             subdialog(ds_win);
332     }
333     
334     if (!cancel && !verifySettings())
335         goto reenter;
336
337     /* OK, we've got a valid registration, now push it out */
338     handle_registration();
339
340     /* Clear this crap off the screen */
341     delwin(ds_win);
342     dialog_clear_norefresh();
343     use_helpfile(NULL);
344
345     restorescr(save);
346     return ret;
347 }