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