]> andersk Git - moira.git/blob - clients/userreg/userreg.c
Code style cleanup. (No functional changes)
[moira.git] / clients / userreg / userreg.c
1 /*
2  * $Source$
3  * $Author$
4  * $Locker$
5  * $Header$ 
6  *
7  *  (c) Copyright 1988 by the Massachusetts Institute of Technology.
8  *  For copying and distribution information, please see the file
9  *  <mit-copyright.h>.
10  */
11
12 #ifndef lint
13 static char    *rcsid_userreg_c = "$Header$";
14 #endif
15
16 #include <mit-copyright.h>
17 #include <string.h>
18 #include <curses.h>
19 #include <signal.h>
20 #include <sys/time.h>
21 #include <setjmp.h>
22 #include <ctype.h>
23 #include <kadm.h>
24 #include <kadm_err.h>
25 #include <krb.h>
26 #include <des.h>
27 #include <errno.h>
28 #include "userreg.h"
29 #include "ureg_err.h"
30
31 /* 7.2 release compatibility */
32 #ifndef KADM_INSECURE_PW
33 #define KADM_INSECURE_PW        (-1783126240L)
34 #endif
35
36 #define EXIT -1
37
38
39 struct user     user, db_user;
40 struct alias    alias;
41 char            realm[REALM_SZ];
42 jmp_buf         redo;
43 int             restart();
44
45 extern int      errno;
46 int             user_is_valid = 0;
47 int             user_has_login = 0;
48 int             already_registered = 0;
49 int             enrollment = 0;
50 extern char *disabled();
51 char typed_mit_id[100];
52
53 fix_display(sig)
54 {
55   struct sigaction act;
56
57   sigemptyset(&act.sa_mask);
58   act.sa_flags = 0;
59   act.sa_handler = SIG_IGN;
60   sigaction(sig, &act, NULL);
61   noraw();
62   echo();
63   endwin();
64   exit(1);
65 }
66
67 int main(int argc, char **argv)
68 {
69   register int ntimes;
70   register int reencrypt;
71   char line[100], *when, *msg;
72   int status;
73   char tmpfirst[100], tmplast[100], tmpmid[100];
74   struct sigaction act;
75
76   status = ureg_init();
77   if (status)
78     {
79       com_err(argv[0], status, "while trying to initialize");
80       exit(1);
81     }
82
83   if (when = disabled(&msg))
84     {
85       printf("We're sorry, the registration service is unavailable right now\n");
86       if (msg)
87         printf("because %s\n", msg);
88       printf("You should be able to register after %s", when);
89       printf("\nPress ENTER or RETURN to continue ");
90       fflush(stdout);
91       getchar();
92       exit(0);
93     }
94
95   /* stash the realm for later use */
96   if ((status = krb_get_lrealm(realm, 1)) != KSUCCESS)
97     {
98       printf("System error; please try another workstation.");
99       exit(1);
100     }
101
102   setup_display();
103
104   sigemptyset(&act.sa_mask);
105   act.sa_flags = 0;
106   act.sa_handler = (void (*)()) fix_display;
107   sigaction(SIGINT, &act, NULL);
108   sigaction(SIGQUIT, &act, NULL);
109   sigaction(SIGHUP, &act, NULL);
110
111   while (1)
112     {
113       setjmp(redo);
114       reset();
115       ntimes = 0;
116
117       display_text(WELCOME, "");
118
119       gfirst();
120       gmi();
121       glast();
122       strcpy(tmpfirst, user.u_first);
123       strcpy(tmplast, user.u_last);
124       FixName(tmplast, tmpfirst, user.u_last, user.u_first, tmpmid);
125       redisp();
126
127       gmitid();
128
129       while (dolook())
130         {
131           ntimes++;
132           if (ntimes > 3)
133             {
134               display_text_line(0);
135               display_text_line("Sorry, you still cannot be found in the database.");
136               display_text_line(" ");
137               display_text_line("Please call an accounts consultant at x3-1325 for help.");
138               wait_for_user();
139               break;
140             }
141           display_text_line(0); /* clear the window */
142           display_text_line("You could not be found in the database.");
143           display_text_line("Do you want to change some input "
144                             "(for example, the spelling");
145           display_text_line("of part of your name) and try again?");
146           if (askyn("Do you want to try again ? ") == YES)
147             {
148               reencrypt = 0;
149               display_text_line(0);
150               sprintf(line, "You entered your first name as \"%s\"",
151                       user.u_first);
152               display_text_line(line);
153               if (askyn("Do you want to change it? ") == YES)
154                 {
155                   gfirst();
156                   strcpy(tmpfirst, user.u_first);
157                   strcpy(tmplast, user.u_last);
158                   FixName(tmplast, tmpfirst, user.u_last, user.u_first,
159                           tmpmid);
160                   redisp();
161                   reencrypt = 1;
162                 }
163               display_text_line(0);
164               sprintf(line, "You entered your middle initial as \"%s\"",
165                       user.u_mid_init);
166               display_text_line(line);
167               if (askyn("Do you want to change it? ") == YES)
168                 gmi();
169               display_text_line(0);
170               sprintf(line, "You entered your family name as \"%s\"",
171                       user.u_last);
172               display_text_line(line);
173               if (askyn("Do you want to change it? ") == YES)
174                 {
175                   glast();
176                   strcpy(tmpfirst, user.u_first);
177                   strcpy(tmplast, user.u_last);
178                   FixName(tmplast, tmpfirst, user.u_last, user.u_first,
179                           tmpmid);
180                   redisp();
181                   reencrypt = 1;
182                 }
183               display_text_line(0);
184               sprintf(line, "You entered your MIT id number as \"%s\"",
185                       typed_mit_id);
186               display_text_line(line);
187               if (askyn("Do you want to change it? ") == YES)
188                 {
189                   gmitid();
190                   reencrypt = 0;
191                 }
192               if (reencrypt)
193                 {
194                   EncryptID(user.u_mit_id, typed_mit_id,
195                             user.u_first, user.u_last);
196                 }
197             }
198           else
199             break;
200         }
201       if (!user_is_valid || already_registered)
202         {
203           qexit();
204           continue;
205         }
206       redisp();
207       if (!user_has_login)
208         {
209           if (negotiate_login() == -1)
210             {
211               qexit();
212               continue;
213             }
214         }
215       if (negotiate_passwd() == -1)
216         {
217           qexit();
218           continue;
219         }
220       sleep(1);
221       if (!enrollment)
222         display_text(FINISHED, user.u_login);
223       else
224         {
225           display_text(FINISHEDE, user.u_login);
226           if (askyn("Do you wish to set your mailbox now? (Yes or No) "))
227             {
228               clear();
229               refresh();
230               noraw();
231               echo();
232               kinit(user.u_login, user.u_password);
233               system(NAMESPACE_PROG);
234               dest_tkt();
235               qexit();
236               exit(0);
237             }
238         }
239       wait_for_user();
240       qexit();
241       break;
242     }
243   restore_display();
244   exit(0);
245 }
246
247 reset(void)
248 {
249   reset_display();
250   memset(&user, 0, sizeof(user));
251   user_is_valid = 0;
252   already_registered = 0;
253   enrollment = 0;
254   redisp();
255 }
256
257 int dolook(void)
258 {
259   /* do the database lookup */
260
261   char line[100];
262   register int result;
263
264   if (user_is_valid)
265     {
266       /* !! */
267       return 0;
268     }
269   display_text_line(0);
270   display_text_line("Looking you up in the database.... "
271                     "This may take from a few seconds to a few");
272   display_text_line("minutes, depending on how busy the system is "
273                     "at the moment.");
274
275   timer_off();
276   result = verify_user(user.u_first, user.u_last, typed_mit_id,
277                        user.u_mit_id, db_user.u_login);
278   wfeep();
279   display_text_line(0);
280   timer_on();
281   switch(result)
282     {
283     case 0:
284     case UREG_ENROLLED:
285       display_text_line("You have been located in the user registration database.");
286       user_is_valid = 1;
287       user_has_login = 0;
288       sleep(1);
289       return 0;
290     case UREG_HALF_ENROLLED:
291       enrollment = 1;
292       /* fall through to: */
293     case UREG_NO_PASSWD_YET:
294       user_is_valid = 1;
295       user_has_login = 1;
296       display_text_line ("You have chosen a login name, but you have not yet chosen a password.");
297       sprintf(line, "Remember: the username you chose was '%s'",
298               db_user.u_login);
299       strcpy(user.u_login, db_user.u_login);
300       display_text_line(line);
301       redisp();
302       sleep(5);
303       return 0;
304
305     case UREG_ALREADY_REGISTERED:
306       already_registered = 1;
307       /*
308        * we have to reset this so we dont ask for a
309        * new username
310        */
311       user_is_valid = 0;
312       display_text_line("You are already registered.  "
313                         "An account for you probably already exists");
314       display_text_line("(if not, it will appear within 24 hours).");
315       display_text_line("");
316       display_text_line("Refer to the document 'Working on Athena' "
317                         "for help logging in.");
318       strcpy(user.u_login, db_user.u_login);
319       sprintf(line, "Remember, the username you chose was '%s'",
320               db_user.u_login);
321       display_text_line(line);
322       redisp();
323       wait_for_user();
324       return 0;
325     case UREG_DELETED:
326       display_text(DELETED_ACCT, db_user.u_login);
327       wait_for_user();
328       restore_display();
329       exit(0);
330     case UREG_NOT_ALLOWED:
331       display_text(OFFER_ENROLL, db_user.u_login);
332       redisp();
333       if (!askyn("Continue choosing a name and password (Y/N)? "))
334         {
335           already_registered = 1;
336           return 0;
337         }
338       user_has_login = 0;
339       user_is_valid = 1;
340       enrollment = 1;
341       return 0;
342     case UREG_ENROLL_NOT_ALLOWED:
343       display_text(NOT_ALLOWED, db_user.u_login);
344       wait_for_user();
345       restore_display();
346       exit(0);
347     case UREG_KRB_TAKEN:
348       display_text(IMPROPER_LOGIN, db_user.u_login);
349       wait_for_user();
350       return 0;
351     case UREG_USER_NOT_FOUND:
352       return 1;
353
354     case ECONNREFUSED:
355     case ETIMEDOUT:
356     case UREG_MISC_ERROR:
357       display_text(NETWORK_DOWN, db_user.u_login);
358       display_text_line(" ");
359       sprintf(line, "The specific error was: %s", error_message(result));
360       display_text_line(line);
361       wait_for_user();
362       return 0;
363
364     default:
365       display_text_line("An unexpected error occurred while trying to "
366                         "access the database");
367       display_text_line(error_message(result));
368       redisp();
369       wait_for_user();
370       return 1;
371     }
372 }
373
374
375 /* Get a login name from the user and register it.  There are several steps
376  * to this: display help message, get name, check name, display confirmation
377  * message, get confirmation, register name.
378  */
379
380 int negotiate_login(void)
381 {
382   int result, i;
383   char line[100], old_login[LOGIN_SIZE + 2];
384   char *error, *cp;
385
386   /* build suggested username */
387   cp = user.u_login;
388   if (isalpha(user.u_first[0]))
389     *cp++ = user.u_first[0];
390   if (isalpha(user.u_mid_init[0]))
391     *cp++ = user.u_mid_init[0];
392   for (i = 0; user.u_last[i] && cp - user.u_login < 8; i++)
393     {
394       if (isalpha(user.u_last[i]))
395         *cp++ = user.u_last[i];
396     }
397   for (i = 0; user.u_login[i]; i++)
398     {
399       if (isupper(user.u_login[i]))
400         user.u_login[i] = tolower(user.u_login[i]);
401     }
402   strcpy(old_login, user.u_login);
403
404   /* print message */
405   display_text(USERNAME_BLURB, user.u_login);
406
407 again:
408   /* get name from user */
409   glogin();
410
411   display_text_line(0);
412   display_text_line("Testing that username...");
413   error = "";
414   if (strlen(user.u_login) < 3)
415     error = "Your username must be at least 3 characters long.";
416   else if (strlen(user.u_login) > 8)
417     error = "Your username cannot be longer than 8 characters.";
418   else if (!isalpha(user.u_login[0]) || !islower(user.u_login[0]))
419     error = "Your username must start with a lowercase letter.";
420   else
421     for (i = 1; i < strlen(user.u_login); i++)
422       {
423         if (!islower(user.u_login[i]) &&
424             !isdigit(user.u_login[i]) &&
425             user.u_login[i] != '_')
426           error = "Your username must contain only lower case letters, "
427             "numbers, and underscore";
428       }
429   timer_off();
430   result = krb_get_pw_in_tkt(user.u_login, "", realm, "krbtgt", realm, 1, "");
431   timer_on();
432   if (*error == 0 && result != KDC_PR_UNKNOWN)
433     error = "That username is already taken.";
434
435   /* if it's bad, get another name from user */
436   if (*error)
437     {
438       strcpy(user.u_login, old_login);
439       redisp();
440       display_text_line(error);
441       display_text_line("Please choose another username.");
442       goto again;
443     }
444
445   /* name is OK, make sure */
446   display_text(USERNAME_BLURB2, user.u_login);
447   if (!askyn("Do you want to register this username? (Yes or No) "))
448     goto again;
449
450   display_text_line(0);
451   display_text_line("Trying to assign that username...  "
452                     "This may take a few minutes.");
453
454   /* Do It! */
455   timer_off();
456   if (!enrollment)
457     {
458       result = grab_login(user.u_first, user.u_last, typed_mit_id,
459                           user.u_mit_id, user.u_login);
460     }
461   else
462     {
463       result = enroll_login(user.u_first, user.u_last, typed_mit_id,
464                             user.u_mit_id, user.u_login);
465     }
466   wfeep();
467   timer_on();
468   if (result != 0)
469     {
470       char buf[BUFSIZ];
471
472       if (result == UREG_LOGIN_USED)
473         {
474           /* name was in moira but not kerberos */
475           error = "Sorry, that username really was in use after all.";
476           strcpy(user.u_login, old_login);
477           redisp();
478           display_text_line(error);
479           display_text_line("Please choose another username.");
480           goto again;
481         }
482
483       display_text(NETWORK_DOWN, "");
484       display_text_line(" ");
485       sprintf(buf, "The specific error was: %s", error_message(result));
486       display_text_line(buf);
487       wait_for_user();
488       return qexit();
489     }
490
491   /* at this point we have successfully negotiated a username */
492   sprintf(line, "O.K. your username will be \"%s\".", user.u_login);
493   display_text_line(0);
494   display_text_line(line);
495   redisp();
496   sleep(3);
497   return 0;
498 }
499
500
501 int negotiate_passwd(void)
502 {
503   char *passwd, *error;
504   char old_passwd[256], fullname[256], tktstring[256], inst[INST_SZ];
505   char login[ANAME_SZ], lpassword[PASSWORD_SIZE];
506   int result;
507   des_cblock key;
508   FILE *in;
509
510 again:
511   display_text(PASSWORD_BLURB, "");
512   gpass();
513
514   /* validate password */
515   error = NULL;
516   passwd = user.u_password;
517   sprintf(fullname, "%s%s", user.u_first, user.u_last);
518   if (strlen(passwd) < 6)
519     error = "Please choose a longer password.";
520   if (!strpasscmp(passwd, user.u_first) ||
521       !strpasscmp(passwd, user.u_last) ||
522       !strpasscmp(passwd, user.u_login) ||
523       !strpasscmp(passwd, fullname) ||
524       !strpasscmp(passwd, typed_mit_id))
525     error = "Please do not use your name or ID number for your password.";
526   if (!error)
527     {
528       in = fopen(LOGIN_INFO, "r");
529       if (in)
530         {
531           fgets(login, sizeof(login), in);
532           /* trim trailing newline */
533           if (strlen(login))
534             login[strlen(login) - 1] = '\0';
535           fgets(lpassword, sizeof(lpassword), in);
536           /* trim trailing newline */
537           if (strlen(lpassword))
538             lpassword[strlen(lpassword) - 1] = '\0';
539           fclose(in);
540         }
541       else
542         {
543           strcpy(login, "moira");
544           strcpy(lpassword, "moira");
545         }
546
547       sprintf(tktstring, "/tmp/tkt_cpw_%d", getpid());
548       krb_set_tkt_string(tktstring);
549       des_string_to_key(passwd, key);
550       inst[0] = 0;
551
552       result = krb_get_pw_in_tkt(login, inst, realm, PWSERV_NAME,
553                                  KADM_SINST, 1, lpassword);
554       if (result == KSUCCESS)
555         result = kadm_init_link(PWSERV_NAME, KRB_MASTER, realm);
556       if (result == KSUCCESS)
557         result = kadm_check_pw(key, passwd, &error);
558       dest_tkt();
559       if (result == KADM_INSECURE_PW)
560         {
561           error = "You have chosen a passsword that is in the dictionary "
562             "of commonly\nselected user passwords.  You will have to choose "
563             "a better password.";
564         }
565       else if (result != KSUCCESS)
566         {
567           display_text(NETWORK_DOWN);
568           display_text_line(" ");
569           sprintf(fullname, "%s while verifying password",
570                   error_message(result));
571           display_text_line(fullname);
572           wait_for_user();
573           return -1;
574         }
575     }
576
577   if (error)
578     {
579       display_text_line(0);
580       display_text_line(error);
581       wait_for_user();
582       goto again;
583     }
584
585   display_text(PASSWORD_BLURB2, "");
586   strcpy(old_passwd, user.u_password);
587   gpass();
588   if (strcmp(old_passwd, user.u_password))
589     {
590       display_text_line(0);
591       display_text_line("What you just typed did not match the password "
592                         "you gave the first time.");
593       sleep(8);
594       goto again;
595     }
596
597   display_text_line("Storing password in the database...  This may take "
598                     "a few minutes.");
599   if (do_replace())
600     return -1;
601   display_text_line("done.");
602   return 0;
603 }
604
605 gfirst(void)
606 {
607   /* input the first name */
608   char buf[FIRST_NAME_SIZE + 2];
609   struct sigaction act;
610
611   sigemptyset(&act.sa_mask);
612   act.sa_flags = 0;
613   act.sa_handler = (void (*)()) fix_display;
614   sigaction(SIGALRM, &act, NULL);
615   input("Enter first Name:", buf, FIRST_NAME_SIZE + 1,
616         FIRSTNAME_TIMEOUT, TRUE);
617   strncpy(user.u_first, buf, FIRST_NAME_SIZE);
618   user.u_first[FIRST_NAME_SIZE - 1] = '\0';
619   canon_name(user.u_first);
620   redisp();
621 }
622
623 glast(void)
624 {
625   /* input the last name */
626   char buf[LAST_NAME_SIZE + 2];
627   struct sigaction act;
628
629   sigemptyset(&act.sa_mask);
630   act.sa_flags = 0;
631   act.sa_handler = (void (*)()) fix_display;
632   sigaction(SIGALRM, &act, NULL);
633   input("Enter family Name:", buf, LAST_NAME_SIZE + 1,
634         LASTNAME_TIMEOUT, FALSE);
635   strncpy(user.u_last, buf, LAST_NAME_SIZE);
636   user.u_last[LAST_NAME_SIZE - 1] = '\0';
637   canon_name(user.u_last);
638   redisp();
639 }
640
641 gpass(void)
642 {
643   /* input password */
644   char new_password[PASSWORD_SIZE + 1];
645   struct sigaction act;
646
647   sigemptyset(&act.sa_mask);
648   act.sa_flags = 0;
649   act.sa_handler = (void (*)()) fix_display;
650   sigaction(SIGALRM, &act, NULL);
651   input_no_echo("Enter password:", new_password,
652                 PASSWORD_SIZE, NEW_PASSWORD_TIMEOUT);
653   strcpy(user.u_password, new_password);
654   redisp();
655 }
656
657
658 /* get login name */
659
660 glogin(void)
661 {
662   char buf[LOGIN_SIZE + 2];
663   struct sigaction act;
664
665   sigemptyset(&act.sa_mask);
666   act.sa_flags = 0;
667   act.sa_handler = (void (*)()) fix_display;
668   sigaction(SIGALRM, &act, NULL);
669   user.u_login[0] = '\0';
670   input("Enter username:", buf, LOGIN_SIZE, USERNAME_TIMEOUT, FALSE);
671   strcpy(user.u_login, buf);
672   redisp();
673 }
674
675 gmitid(void)
676 {
677   /* get mid id */
678   register int i;
679   char buf[15];
680   register char *nbuf = buf;
681   struct sigaction act;
682
683 input_mit_id:
684   sigemptyset(&act.sa_mask);
685   act.sa_flags = 0;
686   act.sa_handler = (void (*)()) fix_display;
687   sigaction(SIGALRM, &act, NULL);
688   input("Enter MIT Id:", buf, 14, MITID_TIMEOUT, FALSE);
689   i = 0;
690   nbuf = &buf[0];
691   while (*nbuf)
692     {
693       if (*nbuf == ' ' || *nbuf == '-')
694         {
695           nbuf++;
696           continue;
697         }
698       if (!isdigit(*nbuf))
699         {
700           i = 0;
701           break;
702         }
703       typed_mit_id[i] = *nbuf;
704       nbuf++;
705       i++;
706     }
707   if (i != 9)
708     {
709       display_text_line("Your MIT id must be a nine-digit number.  "
710                         "Please try again.");
711       goto input_mit_id;
712     }
713   typed_mit_id[9] = '\0';
714   redisp();
715   EncryptID(user.u_mit_id, typed_mit_id, user.u_first, user.u_last);
716 }
717
718 gmi(void)
719 {
720   /* get middle initial */
721   char buf[MID_INIT_SIZE + 2];
722   struct sigaction act;
723
724   sigemptyset(&act.sa_mask);
725   act.sa_flags = 0;
726   act.sa_handler = (void (*)()) fix_display;
727   sigaction(SIGALRM, &act, NULL);
728   input("Enter Middle Initial:", buf, MID_INIT_SIZE + 1, MI_TIMEOUT, TRUE);
729   strncpy(user.u_mid_init, buf, MID_INIT_SIZE);
730   user.u_mid_init[MID_INIT_SIZE - 1] = '\0';
731   canon_name(user.u_mid_init);
732   redisp();
733 }
734
735 int qexit(void)
736 {
737   /* exit quickly, not saving anything in the database */
738   memset(&user, 0, sizeof(user));
739   typed_mit_id[0] = '\0';
740   user_is_valid = 0;
741   already_registered = 0;
742   enrollment = 0;
743   sleep(2);             /* give the user a chance to see the screen */
744   display_text_line(0);
745   return EXIT;
746 }
747
748
749 int do_replace(void)
750 {
751   int status;
752   char buf[100];
753
754   /*
755    * replaces a user in the database. If there is an error, it informs
756    * the user and calls qexit(); It returns only if is is successful
757    */
758   timer_off();
759   if (!enrollment)
760     {
761       status = set_password(user.u_first, user.u_last, typed_mit_id,
762                             user.u_mit_id, user.u_password);
763     }
764   else
765     {
766       status = get_krb(user.u_first, user.u_last, typed_mit_id,
767                        user.u_mit_id, user.u_password);
768     }
769   wfeep();
770   timer_on();
771   if (status)
772     {
773       display_text(NETWORK_DOWN);
774       display_text_line(" ");
775       sprintf(buf, "The specific error was: %s", error_message(status));
776       display_text_line(buf);
777       wait_for_user();
778       return -1;
779     }
780   else
781     return 0;
782 }
783
784
785 int kinit(char *user, char *passwd)
786 {
787   int status;
788   char inst[INST_SZ];
789
790   inst[0] = '\0';
791   status = krb_get_pw_in_tkt(user, inst, realm, "krbtgt",
792                              realm, DEFAULT_TKT_LIFE, 0);
793   return status;
794 }
795
796
797 #ifndef _toupper
798 #define _toupper(c) ((c) & ~0x20)
799 #endif
800
801 int lenient_strcmp(register char *string1, register char *string2)
802 {
803   /*
804    * a primitive case insensitive string comparison. It returns only 0
805    * if the strings are equal (ignoring case) and 1 if they are
806    * different. Also ignores spaces.
807    */
808
809   while (1)
810     {
811       if (*string1 == '\0' && *string2 == '\0')
812         return 0;
813       if (*string1 == ' ' || *string1 == '.' || *string1 == '-' ||
814           *string1 == '\'' || *string1 == '_')
815         {
816           string1++;
817           continue;
818         }
819       if (*string2 == ' ' || *string2 == '.' || *string2 == '-' ||
820           *string2 == '\'' || *string2 == '_')
821         {
822           string2++;
823           continue;
824         }
825       if (_toupper(*string1) != _toupper(*string2))
826         return 1;
827       string1++;
828       string2++;
829     }
830 }
831
832
833 /* See if the strings match in forward & reverse direction, ignoring
834  * case and spaces/punctuation.
835  */
836
837 int strpasscmp(char *s1, char *s2)
838 {
839   char buf[256], *from, *to;
840
841   if (!lenient_strcmp(s1, s2))
842     return 0;
843   /* if s2 is empty, say OK */
844   if (!*s2)
845     return 1;
846
847   from = &s2[strlen(s2)];
848   from--;
849   for (to = &buf[0]; from >= s2; from--)
850     *to++ = *from;
851
852   return lenient_strcmp(s1, buf);
853 }
854
855
856 /*
857  * Input timeout handler.  Loop back to asking for the first name.
858  */
859
860 /* Go to asking for first name. */
861 restart(void)
862 {
863   qexit();
864   longjmp(redo, 1);
865 }
866
867 canon_name(register char *cp)
868 {
869   register char *p2 = cp;
870
871   /* Trim whitespace off both ends. */
872   for (; *p2 && isspace(*p2); p2++)
873     ;
874   if (*p2)
875     {
876       strcpy(cp, p2);
877       p2 = cp + strlen(cp);
878       --p2;
879       while (p2 >= cp && isspace(*p2))
880         *(--p2) = '\0';
881     }
882   /* Make it capitalized */
883   FixCase(cp);
884 }
This page took 0.221749 seconds and 5 git commands to generate.