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