/* * Guillaume Cottenceau (gc@mandrakesoft.com) * * Copyright 2000 MandrakeSoft * * This software may be freely redistributed under the terms of the GNU * public license. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * */ /* * Each different frontend must implement all functions defined in frontend.h */ #include #include #include #include #include #include #include #include #include "stage1.h" #include "log.h" #include "newt.h" #include "frontend.h" void init_frontend(void) { printf("Welcome to " DISTRIB_NAME " (" VERSION ") " __DATE__ " " __TIME__ "\n"); } void finish_frontend(void) { } static void get_any_response(void) { unsigned char t; printf("\n\t(press to proceed)"); fflush(stdout); read(0, &t, 1); fcntl(0, F_SETFL, O_NONBLOCK); while (read(0, &t, 1) > 0); fcntl(0, F_SETFL, 0); } static int get_int_response(void) { char s[50]; int j = 0, i = 0; /* (0) tied to Cancel */ fflush(stdout); read(0, &(s[i++]), 1); fcntl(0, F_SETFL, O_NONBLOCK); do { int v = s[i-1]; if (v >= '0' && v <= '9') j = j*10 + (v - '0'); } while (read(0, &(s[i++]), 1) > 0 && i < sizeof(s)); fcntl(0, F_SETFL, 0); return j; } static char * get_string_response(char * initial_string) { /* I won't use a scanf/%s since I also want the null string to be accepted -- also, I want the initial_string */ char s[500]; int i = 0; char buf[10]; int b_index = 0; char b; struct termios t; memset(s, '\0', sizeof(s)); if (initial_string) { printf(initial_string); strcpy(s, initial_string); i = strlen(s); } /* from ncurses/tinfo/lib_raw.c:(cbreak) */ tcgetattr(0, &t); t.c_lflag &= ~ICANON; t.c_lflag |= ISIG; t.c_lflag &= ~ECHO; t.c_iflag &= ~ICRNL; t.c_cc[VMIN] = 1; t.c_cc[VTIME] = 0; tcsetattr(0, TCSADRAIN, &t); fflush(stdout); fcntl(0, F_SETFL, O_NONBLOCK); while (1) { if (read(0, &b, 1) > 0) { if (b_index == 1) { if (b == 91) { buf[b_index] = b; b_index++; continue; } else b_index = 0; } if (b_index == 2) { if (b == 67) { if (s[i] != '\0') { printf("\033[C"); i++; } } if (b == 68) { if (i > 0) { printf("\033[D"); i--; } } b_index = 0; continue; } if (b == 13) break; if (b == 127) { if (i > 0) { printf("\033[D"); printf(" "); printf("\033[D"); if (s[i] == '\0') s[i-1] = '\0'; else s[i-1] = ' '; i--; } } else if (b == 27) { buf[b_index] = b; b_index++; } else { printf("%c", b); s[i] = b; i++; } } } t.c_lflag |= ICANON; t.c_lflag |= ECHO; t.c_iflag |= ICRNL; tcsetattr(0, TCSADRAIN, &t); fcntl(0, F_SETFL, 0); printf("\n"); return strdup(s); } static void blocking_msg(char *type, char *fmt, va_list args) { printf(type); vprintf(fmt, args); get_any_response(); } void error_message(char *msg, ...) { va_list args; va_start(args, msg); va_end(args); blocking_msg("> Error! ", msg, args); unset_param(MODE_AUTOMATIC); } void info_message(char *msg, ...) { va_list args; va_start(args, msg); va_end(args); if (!IS_AUTOMATIC) blocking_msg("> Notice: ", msg, args); else vlog_message(msg, args); } void wait_message(char *msg, ...) { va_list args; printf("Please wait: "); va_start(args, msg); vprintf(msg, args); va_end(args); fflush(stdout); } void remove_wait_message(void) { printf("\n"); } static int size_progress; static int actually_drawn; #define PROGRESS_SIZE 60 void init_progression(char *msg, int size) { int i; size_progress = size; printf("%s\n", msg); if (size) { printf("["); actually_drawn = 0; for (i=0; i actually_drawn) { printf("*"); actually_drawn++; } } else printf("\033[G%d bytes read", current_size); fflush(stdout); } void end_progression(void) { if (size_progress) { update_progression(size_progress); printf("]\n"); } else printf(" done.\n"); } enum return_type ask_from_list_comments(char *msg, char ** elems, char ** elems_comments, char ** choice) { char ** sav_elems = elems; int i, j; printf("> %s\n(0) Cancel\n", msg); i = 1; while (elems && *elems) { printf("(%d) %s (%s)\n", i, *elems, *elems_comments); i++; elems++; elems_comments++; } printf("? "); j = get_int_response(); if (j == 0) return RETURN_BACK; if (j >= 1 && j < i) { *choice = strdup(sav_elems[j-1]); return RETURN_OK; } return RETURN_ERROR; } enum return_type ask_from_list(char *msg, char ** elems, char ** choice) { char ** sav_elems = elems; int i, j; i = 0; while (elems && *elems) { i++; elems++; } if (i < 10) { printf("> %s\n(0) Cancel\n", msg); for (j=0; j %s\n( 0) Cancel\n", msg); if (i < 20) for (j=0; j= 1 && j <= i) { *choice = strdup(sav_elems[j-1]); return RETURN_OK; } return RETURN_ERROR; } enum return_type ask_yes_no(char *msg) { int j; printf("> %s\n(0) Yes\n(1) No\n(2) Back\n? ", msg); j = get_int_response(); if (j == 0) return RETURN_OK; else if (j == 2) return RETURN_BACK; else return RETURN_ERROR; } enum return_type ask_from_entries(char *msg, char ** questions, char *** answers, int entry_size, void (*callback_func)(char ** strings)) { int j, i = 0; char ** already_answers = NULL; printf("> %s\n", msg); while (questions && *questions) { printf("(%c) %s\n", i + 'a', *questions); i++; questions++; } if (*answers == NULL) *answers = (char **) malloc(sizeof(char *) * i); else already_answers = *answers; while (1) { int r; for (j = 0 ; j < i ; j++) { printf("(%c) ? ", j + 'a'); if (already_answers && *already_answers) { (*answers)[j] = get_string_response(*already_answers); already_answers++; } else (*answers)[j] = get_string_response(NULL); } printf("(0) Cancel (1) Accept (2) Re-enter answers\n? "); r = get_int_response(); if (r == 0) return RETURN_BACK; if (r == 1) return RETURN_OK; } }