]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - release/sysinstall/register.c
This commit was generated by cvs2svn to compensate for changes in r27859,
[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.6 1997/03/25 03:07:46 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         dialog_clear_norefresh();
185         if (!vsystem("mail %s < %s", REGISTRATION_ADDRESS, REGISTRATION_FNAME)) {
186             msgConfirm("Thank you!  Your registration has been sent in successfully.\n");
187             (void)unlink(REGISTRATION_FNAME);
188         }
189         else {
190             msgConfirm("Argh!  The mail program returned a bad status - there\n"
191                        "must be something still not quite configured correctly.\n"
192                        "leaving the registration in: %s\n"
193                        "When you're connected to the net and ready to send it,\n"
194                        "simply type:  mail %s < %s\n", REGISTRATION_ADDRESS, REGISTRATION_FNAME,
195                        REGISTRATION_FNAME);
196         }
197         if (hotspots[ANNOUNCE_LIST].sel) {
198             char *cp;
199             
200             dialog_clear_norefresh();
201             cp = msgGetInput(email, "What email address would you like to subscribe under?\n"
202                              "This is a fairly low-traffic mailing list and only generates\n"
203                              "around 5 messages a month, so it's also safe to receive at your\n"
204                              "standard email address.");
205             if (!cp)
206                 msgConfirm("OK, I won't subscribe to announce at this time.  To do it manually\n"
207                            "yourself, simply send mail to %s.", MAJORDOMO_ADDRESS);
208             else {
209                 dialog_clear_norefresh();
210                 if (!vsystem("echo subscribe freebsd-announce %s | mail %s", email, MAJORDOMO_ADDRESS))
211                     msgConfirm("Your request to join the announce mailing list has been sent.\n"
212                               "you should receive notification back in 24 hours or less, otherwise\n"
213                               "something has gone wrong and you should try this again by sending\n"
214                               "a message to %s which contains the line:\n\n"
215                               "subscribe freebsd-announce %s\n", MAJORDOMO_ADDRESS, email);
216                 else
217                     msgConfirm("Argh!  The mail program returned a bad status - there\n"
218                                "must be something still not quite configured correctly.\n"
219                                "Please fix this then try again by sending a message to\n"
220                                "to %s which contains the line:\n\n"
221                                "subscribe freebsd-announce %s\n", MAJORDOMO_ADDRESS, email);
222             }
223         }
224     }
225     else {
226         dialog_clear_norefresh();
227         msgConfirm("OK, your registration has been left in the file %s\n"
228                    "When you're connected to the net and ready to send it,\n"
229                    "simply type:  mail %s < %s\n", REGISTRATION_FNAME,
230                    REGISTRATION_ADDRESS, REGISTRATION_FNAME);
231     }
232     restorescr(save);
233 }
234
235 /* Put up a subdialog for the registration options */
236 static void
237 subdialog(WINDOW *win)
238 {
239     int i, j, attrs;
240     char help_line[80];
241
242     attrs = getattrs(win);
243     mvwaddstr(win, hotspots[COMMERCE_MAIL].y, hotspots[COMMERCE_MAIL].x - 1, "[ ] Postal Adverts");
244     mvwaddstr(win, hotspots[COMMERCE_EMAIL].y, hotspots[COMMERCE_EMAIL].x - 1, "[ ] Email Adverts");
245     mvwaddstr(win, hotspots[ANNOUNCE_LIST].y, hotspots[ANNOUNCE_LIST].x - 1,
246               "[ ] The announce@FreeBSD.ORG mailing list.");
247     mvwaddstr(win, hotspots[NEWSLETTER].y, hotspots[NEWSLETTER].x - 1, "[ ] The FreeBSD Newsletter.");
248     /* Tack up the initial values */
249     for (i = 0; i < sizeof(hotspots) / sizeof(hotspots[0]); i++) {
250         wattrset(win, attrs | A_BOLD);
251         mvwaddch(win, hotspots[i].y, hotspots[i].x, hotspots[i].sel ? hotspots[i].allowed[hotspots[i].sel - 1] : 'N');
252     }
253     wattrset(win, attrs);
254     wrefresh(win);
255
256     for (i = 0; i < sizeof(hotspots) / sizeof(hotspots[0]);) {
257         int ch, len = strlen(hotspots[i].desc);
258         char *cp;
259
260         /* Display the help line at the bottom of the screen */
261         for (j = 0; j < 79; j++)
262             help_line[j] = (j < len) ? hotspots[i].desc[j] : ' ';
263         help_line[j] = '\0';
264         use_helpline(help_line);
265         display_helpline(win, LINES - 1, COLS - 1);
266         wmove(win, hotspots[i].y, hotspots[i].x);
267         wrefresh(win);
268         switch(ch = toupper(getch())) {
269         case KEY_UP:
270                 if (i)
271                     i--;
272                 continue;
273
274         case KEY_DOWN:
275         case '\011':    /* TAB */
276         case '\012':    /* ^J */
277         case '\014':    /* ^M */
278             /* Treat as a no-change op */
279             ++i;
280             break;
281
282         case 'N':       /* No is generic to all */
283             hotspots[i].sel = 0;
284             wattrset(win, attrs | A_BOLD);
285             mvwaddch(win, hotspots[i].y, hotspots[i].x, 'N');
286             wattrset(win, attrs);
287             wrefresh(win);
288             ++i;
289             break;
290
291         default:
292             cp = index(hotspots[i].allowed, ch);
293             if (cp) {
294                 hotspots[i].sel = (cp - hotspots[i].allowed) + 1;
295                 wattrset(win, attrs | A_BOLD);
296                 mvwaddch(win, hotspots[i].y, hotspots[i].x, *cp);
297                 wattrset(win, attrs);
298                 wrefresh(win);
299                 ++i;
300             }
301             else
302                 beep();
303             break;
304         }
305     }
306 }
307
308 /* Register a user */
309 int
310 registerOpenDialog(void)
311 {
312     WINDOW              *ds_win, *save = savescr();
313     ComposeObj          *obj = NULL;
314     int                 n = 0, cancel = FALSE;
315     int                 max, ret = DITEM_SUCCESS;
316
317     dialog_clear_norefresh();
318     /* We need a curses window */
319     if (!(ds_win = openLayoutDialog(REGISTER_HELPFILE, " FreeBSD Registration Form:  Press F1 for Help / General Info ",
320                                     REGISTER_DIALOG_X, REGISTER_DIALOG_Y,
321                                     REGISTER_DIALOG_WIDTH, REGISTER_DIALOG_HEIGHT))) {
322         beep();
323         msgConfirm("Cannot open registration dialog window!!");
324         restorescr(save);
325         return DITEM_FAILURE;
326     }
327
328     /* Some more initialisation before we go into the main input loop */
329     obj = initLayoutDialog(ds_win, layout, REGISTER_DIALOG_X, REGISTER_DIALOG_Y, &max);
330
331 reenter:
332     cancelbutton = okbutton = 0;
333     while (layoutDialogLoop(ds_win, layout, &obj, &n, max, &cancelbutton, &cancel)) {
334         if (n == LAYOUT_ADDRESS)
335             subdialog(ds_win);
336     }
337     
338     if (!cancel && !verifySettings())
339         goto reenter;
340
341     /* OK, we've got a valid registration, now push it out */
342     handle_registration();
343
344     /* Clear this crap off the screen */
345     delwin(ds_win);
346     dialog_clear_norefresh();
347     use_helpfile(NULL);
348
349     restorescr(save);
350     return ret;
351 }