#ifndef lint #ifdef SunB1 static char sccsid[] = "@(#)main.c 1.1 94/10/31 SMI; SunOS MLS"; #else static char sccsid[] = "@(#)main.c 1.1 94/10/31 SMI"; #endif /* SunB1 */ #endif lint /* * Copyright (c) 1989 Sun Microsystems, Inc. */ /* * Name: main.c * * Description: This is the main driver for the system installation * tool. This program uses a menu based interface for getting * information from the user about the system's configuration. * * Overview : * * main driver * | * get_host_info * | * get_disk_info * | * get_software_info * | * get_client_info * | * get_sec_info * | * installation */ #include #include #include #include #include #include #include #include #include "install.h" #include "main_impl.h" /* * External functions: */ extern time_t getdate(); extern char * sprintf(); /* * Local functions: */ static void ask_for_time(); static void get_timezone(); static int is_northam(); static void print_ddmmyy(); static void print_mmddyy(); /* * Global variables: */ #ifdef SunB1 int old_mac_state; /* old mac-exempt state */ #endif /* SunB1 */ char * progname; main(argc, argv) int argc; char ** argv; { menu * menu_p; /* pointer to MAIN menu */ sys_info sys; /* system information */ char *new_argv[3]; #ifdef lint argc = argc; #endif (void) umask(UMASK); /* set file creation mask */ progname = basename(argv[0]); /* get name for error mesgs */ /* * Only superuser can do damage with this command */ if (suser() != 1) { (void) fprintf(stderr, "%s: must be superuser\n", progname); exit(EX_NOPERM); } /* * Ignore the 4.0 "repaint" */ (void) signal(SIGQUIT, SIG_IGN); /* ** get installation method */ switch(get_install_method()) { #ifdef REPREINSTALLED case RE_PREINSTALLED : *new_argv=*argv; *(new_argv+1)="-r"; *(new_argv+2)=(char *) 0; if (execv (EASYINSTALL, new_argv) != 1) { (void) menu_log("%s:\tUnable to execute %s\n", progname, "easyinstall"); exit(1); } #endif REPREINSTALLED case EASY_INSTALL : argv[0] = EASYINSTALL; *(argv+1)=(char *) NULL; if (execv (EASYINSTALL, argv) != 1) { (void) menu_log("%s:\tUnable to execute %s\n", progname, "easyinstall"); exit(1); } break; case EXIT_INSTALL : exit(0); } set_menu_log(LOGFILE); /* * Read sys_info from user defined info or default file */ if (read_sys_info(SYS_INFO, &sys) != 1 && read_sys_info(DEFAULT_SYS_INFO, &sys) != 1) { menu_log("%s: Error in %s.", progname, DEFAULT_SYS_INFO); menu_abort(1); } get_terminal(sys.termtype); /* get terminal type */ if (is_miniroot()) { get_timezone(&sys); /* get timezone */ ask_for_time(sys.timezone); /* ask for the time */ if (save_sys_info(SYS_INFO, &sys) != 1) menu_abort(1); } menu_p = create_main_menu(&sys); /* create MAIN menu */ set_items(menu_p, &sys); /* set up menu items */ /* * Ignore the 4.0 "repaint" */ (void) signal(SIGQUIT, SIG_IGN); if (use_menu(menu_p) != 1) /* use MAIN menu */ menu_abort(1); (void) signal(SIGQUIT, SIG_DFL); end_menu(); /* done with menu system */ exit(0); /*NOTREACHED*/ } /* end main() */ /* * Name: ask_for_time() * * Description: Ask the user what time it is and set the time if * the user changes it. */ static void ask_for_time(timezone) char * timezone; { char * ascii_p; /* ptr to time in ASCII */ char buf[BUFSIZ]; /* input buffer */ int done; /* done with input? */ int need_set = 0; /* need to set the time? */ struct timeval now; /* buffer for the time */ struct tm * local_p; /* pointer to local time */ (void) gettimeofday(&now, (struct timezone *) NULL); while (1) { local_p = localtime(&now.tv_sec); ascii_p = asctime(local_p); (void) printf( "\n\nIs this the correct date/time: %.20s%s%s\n[y/n] >> ", ascii_p, local_p->tm_zone ? local_p->tm_zone : "", ascii_p + 19); (void) fflush(stdout); get_stdin(buf); switch (buf[0]) { case 'N': case 'n': need_set = 1; break; case 'Y': case 'y': if (need_set && settimeofday(&now, (struct timezone *) NULL) < 0) { #ifndef TEST_JIG menu_log("%s: cannot set date and time.", progname); menu_abort(1); #endif TEST_JIG } return; } done = 0; while (!done) { if (is_northam(timezone)) print_mmddyy(); else print_ddmmyy(); get_stdin(buf); now.tv_sec = getdate(buf, is_northam(timezone)); if (now.tv_sec >= 0) done = 1; else { (void) printf( "That date and time is not valid.\n"); (void) fflush(stdout); continue; } } } /* end while(1) */ } /* end ask_for_time() */ /* * Name: get_timezone() * * Description: Ask the user if the timezone is valid or ask the * user for a timezone. If the user enters a '?', then the * timezone menu is invoked. Setup the localtime link once * the timezone has been established. */ static void get_timezone(sys_p) sys_info * sys_p; { char buf[BUFSIZ]; /* input buffer */ int done; /* done with input? */ char pathname[MAXPATHLEN]; /* path to timezone file */ menu * tz_p = NULL; /* pointer to timezone menu */ struct stat stat_buf; /* stat buffer for dir test */ if (strlen(sys_p->timezone)) { /* * Confirm the timezone with the user. */ done = 0; while (!done) { (void) printf( "\nIs this the correct time zone: %s\n\n[y/n] >> ", sys_p->timezone); (void) fflush(stdout); get_stdin(buf); switch (buf[0]) { case 'N': case 'n': bzero(sys_p->timezone, sizeof(sys_p->timezone)); /* * Fall through here */ case 'Y': case 'y': done = 1; break; } } } while (!strlen(sys_p->timezone)) { bzero(buf, sizeof(buf)); (void) printf( "\nEnter the local time zone name (enter ? for help):\n\n>> "); (void) fflush(stdout); get_stdin(buf); if (buf[0] == '?') { if (tz_p == NULL) tz_p = create_tz_menu(buf); else init_menu(); /* * Ignore the 4.0 "repaint" */ (void) signal(SIGQUIT, SIG_IGN); (void) use_menu(tz_p); end_menu(); } (void) sprintf(pathname, "%s/%s", ZONEINFO, buf); if ((stat(pathname, &stat_buf) == -1) || (S_ISDIR(stat_buf.st_mode))) { (void) printf("'%s': is not a valid time zone.\n", buf); (void) fflush(stdout); continue; } (void) strcpy(sys_p->timezone, buf); } mk_localtime(sys_p, CP_NULL, CP_NULL); tzsetwall(); } /* end get_timezone() */ /* * Name: is_client_ok() * * Description: Is the information about a client ok? */ int is_client_ok(sys_p) sys_info * sys_p; { arch_info *arch_list, *ap; /* architecture info */ char buf[BUFSIZ]; /* input buffer */ clnt_info clnt; /* client info buffer */ FILE * fp; /* ptr to client_list. */ char pathname[MAXPATHLEN]; /* general pathname buffer */ int ret_code; /* return code */ /* * System is not a server so the client stuff cannot be okay. */ if (sys_p->sys_type != SYS_SERVER) { return(0); } /* * If there are no architectures, then client stuff is not ok. */ ret_code = read_arch_info(ARCH_INFO, &arch_list); if (ret_code != 1) { return(0); } for (ap = arch_list; ap ; ap = ap->next) { (void) sprintf(pathname, "%s.%s", CLIENT_LIST, ap->arch_str); fp = fopen(pathname, "r"); /* * It is okay if there are no clients for this * architecture. */ if (fp == NULL) continue; /* read each client name */ while (fgets(buf, sizeof(buf), fp)) { delete_blanks(buf); (void) sprintf(pathname, "%s.%s", CLIENT_STR, buf); /* * Make sure we can read the client info. Treat * fatal and non-fatal errors the same. */ if (read_clnt_info(pathname, &clnt) != 1) { (void) fclose(fp); free_arch_info(arch_list); return(0); } } (void) fclose(fp); } free_arch_info(arch_list); /* * It is okay if there are no clients at all. */ return(1); } /* end is_client_ok() */ /* * Name: is_disk_ok() * * Description: Is the information about a disk ok? */ int is_disk_ok() { char buf[BUFSIZ]; /* input buffer */ disk_info disk; /* disk info buffer */ int disk_count = 0; /* number of valid disks */ FILE * fp; /* pointer to disk_list */ char pathname[MAXPATHLEN]; /* general pathname buffer */ fp = fopen(DISK_LIST, "r"); if (fp == NULL) return(0); while (fgets(buf, sizeof(buf), fp)) { /* read each disk name */ delete_blanks(buf); (void) sprintf(pathname, "%s.%s", DISK_INFO, buf); if (read_disk_info(pathname, &disk) == 1) disk_count++; else { (void) fclose(fp); return(0); } } (void) fclose(fp); /* * If there are no disks, then the disk stuff is not ok. */ if (disk_count == 0) return(0); return(1); } /* end is_disk_ok() */ /* * Name: is_northam() * * Description: Determine if the timezone is in North America. */ static char * northam_prefixes[] = { "US/", "Canada/", "EST", "CST", "MST", "PST", CP_NULL }; static int is_northam(timezone) char * timezone; { char ** cpp; /* ptr to prefix pointer */ for (cpp = northam_prefixes; *cpp; cpp++) if (strncmp(timezone, *cpp, strlen(*cpp)) == 0) return(1); return(0); } /* end is_northam() */ /* * Name: is_sec_ok() * * Description: Is the information about security ok? */ int is_sec_ok(sys_p) sys_info * sys_p; { arch_info *arch_list, *ap; /* architecture info */ char buf[BUFSIZ]; /* input buffer */ FILE * fp; /* ptr to client_list. */ char pathname[MAXPATHLEN]; /* general pathname buffer */ int ret_code; /* return code */ sec_info sec; /* security info buffer */ (void) sprintf(pathname, "%s.%s", SEC_INFO, sys_p->hostname0); if (read_sec_info(pathname, &sec) != 1) return(0); /* * System is not a server no need to check client security. */ if (sys_p->sys_type != SYS_SERVER) { return(1); } /* * If there are no architectures, then client security * stuff is not ok. */ ret_code = read_arch_info(ARCH_INFO, &arch_list); if (ret_code != 1) { return(0); } for (ap = arch_list; ap ; ap = ap->next) { (void) sprintf(pathname, "%s.%s", CLIENT_LIST, ap->arch_str); fp = fopen(pathname, "r"); /* * It is okay if there are no clients for this * architecture. */ if (fp == NULL) continue; /* read each client name */ while (fgets(buf, sizeof(buf), fp)) { delete_blanks(buf); (void) sprintf(pathname, "%s.%s", SEC_INFO, buf); /* * Make sure we can read the client's security * info. Treat fatal and non-fatal errors the * same. */ if (read_sec_info(pathname, &sec) != 1) { (void) fclose(fp); free_arch_info(arch_list); return(0); } } (void) fclose(fp); } free_arch_info(arch_list); return(1); } /* end is_sec_ok() */ /* * Name: is_soft_ok() * * Description: Is the information about the software ok? */ int is_soft_ok() { arch_info *arch_list, *ap; /* architecture info */ char pathname[MAXPATHLEN]; /* general pathname buffer */ int soft_count = 0; /* # of valid software */ /* * Software info structure must be declared static since * read_soft_info() allocates and frees its own run-time memory. */ static soft_info soft; /* * If there are no architectures, then software stuff is not ok. */ if (read_arch_info(ARCH_INFO, &arch_list) != 1) return(0); for (ap = arch_list; ap ; ap = ap->next) { /* * The software for this architecture is not valid unless * both soft_info and media_file can be read. */ (void) sprintf(pathname, "%s.%s", SOFT_INFO, ap->arch_str); if (read_soft_info(pathname, &soft) != 1) { free_arch_info(arch_list); return(0); } (void) sprintf(pathname, "%s.%s", MEDIA_FILE, ap->arch_str); if (read_media_file(pathname, &soft) == 1) soft_count++; else { free_arch_info(arch_list); return(0); } } /* * If there is no software, then the software stuff is not ok. */ free_arch_info(arch_list); if (soft_count == 0) return(0); return(1); } /* end is_soft_ok() */ /* * Name: is_sys_ok() * * Description: Is the information about the system ok? */ int is_sys_ok(sys_p) sys_info * sys_p; { if (read_sys_info(SYS_INFO, sys_p) != 1) return(0); if (strlen(sys_p->hostname0) == 0) return(0); if (strcmp(sys_p->hostname0, "noname") == 0) return(0); if (sys_p->yp_type != YP_NONE && strcmp(sys_p->domainname, "noname") == 0) return(0); return(1); } /* end is_sys_ok() */ static char * ddmmyy_lines[] = { "", "Enter the current date and local time (e.g. 09/03/88 12:20:30); the date", "may be in one of the following formats:", "", " dd/mm/yy", " dd/mm/yyyy", " dd.mm.yyyy", " dd-mm-yyyy", " dd-mm-yy", " month dd, yyyy", " dd month yyyy", "", "and the time may be in one of the following formats:", "", " hh am/pm", " hh:mm am/pm", " hh.mm", " hh:mm am/pm", " hh.mm", " hh:mm:ss am/pm", " hh:mm:ss", " hh.mm.ss am/pm", " hh.mm.ss", "", CP_NULL }; /* * Name: print_ddmmyy() * * Description: Print a date and time prompt in non-North * American style. */ static void print_ddmmyy() { char ** cpp; /* ptr to string to print */ for (cpp = ddmmyy_lines; *cpp; cpp++) (void) printf("%s\n", *cpp); (void) printf(">> "); (void) fflush(stdout); } /* end print_ddmmyy() */ static char * mmddyy_lines[] = { "", "Enter the current date and local time (e.g. 03/09/88 12:20:30); the date", "may be in one of the following formats:", "", " mm/dd/yy", " mm/dd/yyyy", " dd.mm.yyyy", " dd-mm-yyyy", " dd-mm-yy", " month dd, yyyy", " dd month yyyy", "", "and the time may be in one of the following formats:", "", " hh am/pm", " hh:mm am/pm", " hh.mm", " hh:mm am/pm", " hh.mm", " hh:mm:ss am/pm", " hh:mm:ss", " hh.mm.ss am/pm", " hh.mm.ss", "", CP_NULL }; /* * Name: print_mmddyy() * * Description: Print a date and time prompt in North American style. */ static void print_mmddyy() { char ** cpp; /* ptr to string to print */ for (cpp = mmddyy_lines; *cpp; cpp++) (void) printf("%s\n", *cpp); (void) printf(">> "); (void) fflush(stdout); } /* end print_mmddyy() */