soiffer's latest round of changes
authorKirk McKusick <mckusick@ucbvax.Berkeley.EDU>
Thu, 19 May 1983 09:35:17 +0000 (01:35 -0800)
committerKirk McKusick <mckusick@ucbvax.Berkeley.EDU>
Thu, 19 May 1983 09:35:17 +0000 (01:35 -0800)
SCCS-vsn: usr.bin/passwd/chfn.sh 4.3

usr/src/usr.bin/passwd/chfn.sh

index 8b3963d..0b17dd4 100644 (file)
@@ -1,5 +1,5 @@
 #ifndef lint
 #ifndef lint
-static char *sccsid = "@(#)chfn.sh     4.2 (Berkeley) %G%";
+static char *sccsid = "@(#)chfn.sh     4.3 (Berkeley) %G%";
 #endif lint
 
 /*
 #endif lint
 
 /*
@@ -8,6 +8,14 @@ static char *sccsid = "@(#)chfn.sh     4.2 (Berkeley) %G%";
 #include <stdio.h>
 #include <signal.h>
 #include <pwd.h>
 #include <stdio.h>
 #include <signal.h>
 #include <pwd.h>
+#include <ctype.h>
+
+struct default_values {
+       char *name;
+       char *office_num;
+       char *office_phone;
+       char *home_phone;
+};
 
 char   passwd[] = "/etc/passwd";
 char   temp[]   = "/etc/ptmp";
 
 char   passwd[] = "/etc/passwd";
 char   temp[]   = "/etc/ptmp";
@@ -18,14 +26,13 @@ char        *crypt();
 char   *getpass();
 char   buf[BUFSIZ];
 
 char   *getpass();
 char   buf[BUFSIZ];
 
-#define MAX_STR 52
 main(argc, argv)
        int argc;
        char *argv[];
 {
        int user_uid;
        int num_bytes, fi, fo;
 main(argc, argv)
        int argc;
        char *argv[];
 {
        int user_uid;
        int num_bytes, fi, fo;
-       char replacement[4*MAX_STR];
+       char replacement[4*BUFSIZ];
        FILE *tf;
 
        if (argc > 2) {
        FILE *tf;
 
        if (argc > 2) {
@@ -52,7 +59,7 @@ main(argc, argv)
                if (pwd->pw_uid != user_uid) {
                        printf("%s%s",
                                "You are not allowed to change another",
                if (pwd->pw_uid != user_uid) {
                        printf("%s%s",
                                "You are not allowed to change another",
-                               " person's password entry.\n");
+                               " person's finger entry.\n");
                        exit(1);
                }
        }
                        exit(1);
                }
        }
@@ -69,10 +76,18 @@ main(argc, argv)
                }
                user_uid = pwd->pw_uid;
        }
                }
                user_uid = pwd->pw_uid;
        }
+       if (argc == 1) {
+               pwd = getpwuid(user_uid);
+               if (pwd == NULL) {
+                       fprintf(stderr, "No passwd file entry!?\n");
+                       exit(1);
+               }
+       }
        /*
         * Collect name, room number, school phone, and home phone.
         */
        /*
         * Collect name, room number, school phone, and home phone.
         */
-       get_info(replacement);
+       get_info(pwd->pw_gecos, replacement);
+
        /*
         * Update the entry in the password file.
         */
        /*
         * Update the entry in the password file.
         */
@@ -87,12 +102,12 @@ main(argc, argv)
        /*
         * Race condition -- the locking mechinism is not my idea (ns)
         */
        /*
         * Race condition -- the locking mechinism is not my idea (ns)
         */
-       if(access(temp, 0) >= 0) {
+       if (access(temp, 0) >= 0) {
                printf("It's not your day!  Password file is busy again.\n");
                printf("Try again later.\n");
                exit(1);
        }
                printf("It's not your day!  Password file is busy again.\n");
                printf("Try again later.\n");
                exit(1);
        }
-       if((tf=fopen(temp,"w")) == NULL) {
+       if ((tf=fopen(temp,"w")) == NULL) {
                printf("Cannot create temporary file\n");
                exit(1);
        }
                printf("Cannot create temporary file\n");
                exit(1);
        }
@@ -111,8 +126,8 @@ main(argc, argv)
         * copy passwd to temp, replacing matching line
         * with new finger entry (gecos field).
         */
         * copy passwd to temp, replacing matching line
         * with new finger entry (gecos field).
         */
-       while((pwd=getpwent()) != NULL) {
-               if(pwd->pw_uid == user_uid) {
+       while ((pwd=getpwent()) != NULL) {
+               if (pwd->pw_uid == user_uid) {
                        pwd->pw_gecos = replacement;
                }
                fprintf(tf,"%s:%s:%d:%d:%s:%s:%s\n",
                        pwd->pw_gecos = replacement;
                }
                fprintf(tf,"%s:%s:%d:%d:%s:%s:%s\n",
@@ -142,64 +157,83 @@ main(argc, argv)
 out:
        (void) unlink(temp);
 }
 out:
        (void) unlink(temp);
 }
-\f
+
 /*
  * Get name, room number, school phone, and home phone.
  */
 /*
  * Get name, room number, school phone, and home phone.
  */
-get_info(answer)
+get_info(gecos_field, answer)
+       char *gecos_field;
        char *answer;
 {
        char *strcpy(), *strcat();
        char *answer;
 {
        char *strcpy(), *strcat();
-       char in_str[MAX_STR];
-       answer[0] = '\0';
+       char in_str[BUFSIZ];
+       struct default_values *defaults, *get_defaults();
 
 
+       answer[0] = '\0';
+       defaults = get_defaults(gecos_field);
+       printf("Default values are printed inside of of '[]'.\n");
+       printf("To accept the default, type <return>.\n");
+       printf("To have a blank entry, type the word 'none'.\n");
        /*
         * Get name.
         */
        do {
        /*
         * Get name.
         */
        do {
-               printf("\nName: ");
-               (void) fgets(in_str, MAX_STR, stdin);
+               printf("\nName [%s]: ", defaults->name);
+               (void) fgets(in_str, BUFSIZ, stdin);
+               if (special_case(in_str, defaults->name)) 
+                       break;
        } while (illegal_input(in_str));
        (void) strcpy(answer, in_str);
        /*
         * Get room number.
         */
        do {
        } while (illegal_input(in_str));
        (void) strcpy(answer, in_str);
        /*
         * Get room number.
         */
        do {
-               printf("Room number (Exs: 597E or 197C): ");
-               (void) fgets(in_str, MAX_STR, stdin);
+               printf("Room number (Exs: 597E or 197C) [%s]: ",
+                       defaults->office_num);
+               (void) fgets(in_str, BUFSIZ, stdin);
+               if (special_case(in_str, defaults->office_num))
+                       break;
        } while (illegal_input(in_str) || illegal_building(in_str));
        (void) strcat(strcat(answer, ","), in_str);
        /*
         * Get office phone number.
        } while (illegal_input(in_str) || illegal_building(in_str));
        (void) strcat(strcat(answer, ","), in_str);
        /*
         * Get office phone number.
-        * Remove hyphens and 642 or x2 prefixes if present.
+        * Remove hyphens and 642, x2, or 2 prefixes if present.
         */
        do {
         */
        do {
-               printf("Office Phone (Ex: 1632): ");
-               (void) fgets(in_str, MAX_STR, stdin);
+               printf("Office Phone (Ex: 1632) [%s]: ",
+                       defaults->office_phone);
+               (void) fgets(in_str, BUFSIZ, stdin);
+               if (special_case(in_str, defaults->office_phone))
+                       break;
                remove_hyphens(in_str);
                if ((strlen(in_str) == 8) && (strcmpn(in_str, "642", 3) == 0))
                        (void) strcpy(in_str, in_str+3);
                if ((strlen(in_str) == 7) && (strcmpn(in_str, "x2", 2) == 0))
                        (void) strcpy(in_str, in_str+2);
                remove_hyphens(in_str);
                if ((strlen(in_str) == 8) && (strcmpn(in_str, "642", 3) == 0))
                        (void) strcpy(in_str, in_str+3);
                if ((strlen(in_str) == 7) && (strcmpn(in_str, "x2", 2) == 0))
                        (void) strcpy(in_str, in_str+2);
-       } while ((illegal_input(in_str)) || wrong_length(in_str, 4));
+               if ((strlen(in_str) == 6) && (in_str[0] == '2'))
+                       (void) strcpy(in_str, in_str+1);
+       } while (illegal_input(in_str) || not_all_digits(in_str)
+                || wrong_length(in_str, 4));
        (void) strcat(strcat(answer, ","), in_str);
        /*
         * Get home phone number.
         * Remove hyphens if present.
         */
        do {
        (void) strcat(strcat(answer, ","), in_str);
        /*
         * Get home phone number.
         * Remove hyphens if present.
         */
        do {
-               printf("Home Phone (Ex: 9875432): ");
-               (void) fgets(in_str, MAX_STR, stdin);
+               printf("Home Phone (Ex: 9875432) [%s]: ", defaults->home_phone);
+               (void) fgets(in_str, BUFSIZ, stdin);
+               if (special_case(in_str, defaults->home_phone))
+                       break;
                remove_hyphens(in_str);
                remove_hyphens(in_str);
-       } while (illegal_input(in_str));
+       } while (illegal_input(in_str) || not_all_digits(in_str));
        (void) strcat(strcat(answer, ","), in_str);
 }
        (void) strcat(strcat(answer, ","), in_str);
 }
-\f
+
 /*
  * Prints an error message if a ':' or a newline is found in the string.
  * A message is also printed if the input string is too long.
  * The password file uses :'s as seperators, and are not allowed in the "gcos"
 /*
  * Prints an error message if a ':' or a newline is found in the string.
  * A message is also printed if the input string is too long.
  * The password file uses :'s as seperators, and are not allowed in the "gcos"
- * field.  Newlines serve a delimiters between users in the password file,
+ * field.  Newlines serve as delimiters between users in the password file,
  * and so, those too, are checked for.  (I don't think that it is possible to
  * type them in, but better safe than sorry)
  *
  * and so, those too, are checked for.  (I don't think that it is possible to
  * type them in, but better safe than sorry)
  *
@@ -220,7 +254,7 @@ illegal_input(input_str)
        if (input_str[length-1] != '\n') {
                /* the newline and the '\0' eat up two characters */
                printf("Maximum number of characters allowed is %d\n",
        if (input_str[length-1] != '\n') {
                /* the newline and the '\0' eat up two characters */
                printf("Maximum number of characters allowed is %d\n",
-                       MAX_STR-2);
+                       BUFSIZ-2);
                /* flush the rest of the input line */
                while (getchar() != '\n')
                        /* void */;
                /* flush the rest of the input line */
                while (getchar() != '\n')
                        /* void */;
@@ -256,6 +290,24 @@ remove_hyphens(str)
        }
 }
 
        }
 }
 
+/*
+ *  Checks to see if 'str' contains only digits (0-9).  If not, then
+ *  an error message is printed and '1' is returned.
+ */
+not_all_digits(str)
+       char *str;
+{
+       char *ptr;
+
+       for (ptr=str; *ptr != '\0'; ++ptr) {
+               if (!isdigit(*ptr)) {
+                       printf("Phone numbers can only contain digits.\n");
+                       return(1);
+               }
+       }
+       return(0);
+}
+
 /*
  * Returns 1 when the length of the input string is not zero or equal to n.
  * Prints an error message in this case.
 /*
  * Returns 1 when the length of the input string is not zero or equal to n.
  * Prints an error message in this case.
@@ -264,6 +316,7 @@ wrong_length(str, n)
        char *str;
        int n;
 {
        char *str;
        int n;
 {
+
        if ((strlen(str) != 0) && (strlen(str) != n)) {
                printf("The phone number should be %d digits long.\n", n);
                return(1);
        if ((strlen(str) != 0) && (strlen(str) != n)) {
                printf("The phone number should be %d digits long.\n", n);
                return(1);
@@ -332,3 +385,97 @@ illegal_building(str)
        }
        return(0);
 }
        }
        return(0);
 }
+
+/* get_defaults picks apart "str" and returns a structure points.
+ * "str" contains up to 4 fields separated by commas.
+ * Any field that is missing is set to blank.
+ */
+struct default_values 
+*get_defaults(str)
+       char *str;
+{
+       struct default_values *answer;
+       char *malloc(), *index();
+
+       answer = (struct default_values *)
+               malloc((unsigned)sizeof(struct default_values));
+       if (answer == (struct default_values *) NULL) {
+               fprintf(stderr,
+                       "\nUnable to allocate storage in get_defaults!\n");
+               exit(1);
+       }
+       /*
+        * Values if no corresponding string in "str".
+        */
+       answer->name = str;
+       answer->office_num = "";
+       answer->office_phone = "";
+       answer->home_phone = "";
+       str = index(answer->name, ',');
+       if (str == 0) 
+               return(answer);
+       *str = '\0';
+       answer->office_num = str + 1;
+       str = index(answer->office_num, ',');
+       if (str == 0) 
+               return(answer);
+       *str = '\0';
+       answer->office_phone = str + 1;
+       str = index(answer->office_phone, ',');
+       if (str == 0) 
+               return(answer);
+       *str = '\0';
+       answer->home_phone = str + 1;
+       return(answer);
+}
+
+/*
+ *  special_case returns true when either the default is accepted
+ *  (str = '\n'), or when 'none' is typed.  'none' is accepted in
+ *  either upper or lower case (or any combination).  'str' is modified
+ *  in these two cases.
+ */
+int special_case(str,default_str)
+       char *str;
+       char *default_str;
+{
+       static char word[] = "none\n";
+       char *ptr, *wordptr;
+
+       /*
+        *  If the default is accepted, then change the old string do the 
+        *  default string.
+        */
+       if (*str == '\n') {
+               (void) strcpy(str, default_str);
+               return(1);
+       }
+       /*
+        *  Check to see if str is 'none'.  (It is questionable if case
+        *  insensitivity is worth the hair).
+        */
+       wordptr = word-1;
+       for (ptr=str; *ptr != '\0'; ++ptr) {
+               ++wordptr;
+               if (*wordptr == '\0')   /* then words are different sizes */
+                       return(0);
+               if (*ptr == *wordptr)
+                       continue;
+               if (isupper(*ptr) && (tolower(*ptr) == *wordptr))
+                       continue;
+               /*
+                * At this point we have a mismatch, so we return
+                */
+               return(0);
+       }
+       /*
+        * Make sure that words are the same length.
+        */
+       if (*(wordptr+1) != '\0')
+               return(0);
+       /*
+        * Change 'str' to be the null string
+        */
+       *str = '\0';
+       return(1);
+}