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