/* see misc/fviews.* */ #include #include #include #include "amandaconf.h" #include "amandaconf.m" #include #include #include "fviews.h" #include "lame_parser.h" #define AMANDA_CONFIG_DIRECTORY "/etc/amanda" #define DEFAULT_DISKLIST_FILENAME "disklist" #define TYPICAL_STRING_SIZE 100 #define HUGE_STRING_SIZE 500 #define complexfloat SSTRING #define complexbool SSTRING #define complexint SSTRING #define complexintquoted SSTRING /* varname, "varname in file" */ #define bload_str(a,b) load_vardata_into(parser_control, groupname, b, my_intvars.a) #define bload_cint(a,b) load_vardata_into(parser_control, groupname, b, my_intvars.a, ' ', '\0') #define bload_cintq(a,b) load_vardata_into(parser_control, groupname, b, my_intvars.a) #define bload_bool(a,b) load_vardata_into(parser_control, groupname, b, my_intvars.a) #define bload_float(a,b) load_vardata_into(parser_control, groupname, b, my_intvars.a) // (disklist-specific) varname, which word #define bload_dsklst(a,b) return_which_word(current_dsklst_line, b, my_intvars.a) /* varname, description */ #define bgui_str(a,b) my_dialog.newf_str(b, my_intvars.a) #define bgui_cint(a,b) my_dialog.newf_str(b, my_intvars.a) #define bgui_cintq(a,b) my_dialog.newf_str(b, my_intvars.a) #define bgui_bool(a,b) FIELD_LIST *a;\ load_boolean_sstring(my_intvars.a.get(), my_intvars.a);\ create_triple_boolean_gadget(my_dialog, &a, b, my_intvars.a) #define bgui_float(a,b) my_dialog.newf_str(b, my_intvars.a) #define bgui_strcombo(a,b) FIELD_COMBO *a;\ a=my_dialog.newf_combo(b, my_intvars.a) #define bgui_comboitem(a,b) a->addopt(b) // popdown menu with all items of a specified group -- varname, group_prefix, description, sstrings_varname #define bgui_fl_groupitems(a,b,c,d) FIELD_LIST *a;\ SSTRINGS d;\ a=my_dialog.newf_list(c, my_intvars.a);\ fills_sstrings_with_selected_groups(parser_control, d, b);\ dump_sstrings_to_fieldlist(my_dialog, d, a) /* varname, "varname in file" */ #define bsave_str(a,b) write_var_data(parser_control, groupname, b, my_intvars.a.get()) #define bsave_cint(a,b) write_var_data(parser_control, groupname, b, my_intvars.a.get(), ' ', '\0') #define bsave_cintq(a,b) write_var_data(parser_control, groupname, b, my_intvars.a.get()) #define bsave_bool(a,b) write_var_data(parser_control, groupname, b, my_intvars.a.get()) #define bsave_float(a,b) write_var_data(parser_control, groupname, b, my_intvars.a.get()) // (disklist-specific) varname #define bsave_dsklst(a) temp_buff.append(my_intvars.a.get());\ temp_buff.append(" ");\ if(invalid_chars_present(my_intvars.a.get()))\ enter_the_loop=1\ /* misc aliases */ // am_dumptypes.cc #define addthis(a) extra_possible_heritages.add(new SSTRING(a)) /* help files */ HELP_FILE general_helpfile("amandaconf", "general"); HELP_FILE disklist_helpfile("amandaconf", "disklist"); HELP_FILE holdingdisks_helpfile("amandaconf", "holdingdisks"); HELP_FILE dumptypes_helpfile("amandaconf", "dumptypes"); HELP_FILE tapetypes_helpfile("amandaconf", "tapetypes"); HELP_FILE interfaces_helpfile("amandaconf", "interfaces"); HELP_FILE disklist_prop_helpfile("amandaconf", "disklist_prop"); HELP_FILE holdingdisks_prop_helpfile("amandaconf", "holdingdisks_prop"); HELP_FILE dumptypes_prop_helpfile("amandaconf", "dumptypes_prop"); HELP_FILE tapetypes_prop_helpfile("amandaconf", "tapetypes_prop"); HELP_FILE interfaces_prop_helpfile("amandaconf", "interfaces_prop"); HELP_FILE config_menu_helpfile("amandaconf", "config_menu"); /* protos */ int return_which_word(const char *given_string, int which_word, SSTRING &where_to_dump); int fills_sstrings_with_selected_groups(t_parser_control *parser_control, SSTRINGS &sstrings_to_fill, const char *match_this_string); int are_there_heritages(t_parser_control *parser_control, const char *given_group_opener, const char *whole_groupname, SSTRINGS *where_to_dump_heritages, SSTRINGS *extra_heritages); int confirm_yesno_window(const char *my_title, const char *my_text); int group_heritages_are_a_problem(t_parser_control *parser_control, const char *given_group_opener, const char *whole_groupname); int group_heritages_are_a_problem(t_parser_control *parser_control, const char *given_group_opener, const char *whole_groupname, SSTRINGS *extra_heritages); void dump_sstrings_to_list(DIALOG_RECORDS &my_dialog, SSTRINGS &given_sstrings); void dump_sstrings_to_list(DIALOG_RECORDS &my_dialog, SSTRINGS &given_sstrings, int ¤t_line); /* alias for group_heritages_are_a_problem(...) */ int group_heritages_are_a_problem(t_parser_control *parser_control, const char *given_group_opener, const char *whole_groupname) { return(group_heritages_are_a_problem(parser_control, given_group_opener, whole_groupname, NULL)); } /* checks if specified group has no heritages; if it does, ask user if he want to edit that group anyway !=0 heritages are a problem indeed, do NOT edit that ==0 ok, go on. even if there are heritages used said it's not a problem */ int group_heritages_are_a_problem(t_parser_control *parser_control, const char *given_group_opener, const char *whole_groupname, SSTRINGS *extra_heritages) { SSTRINGS where_to_dump_heritages; if(!are_there_heritages(parser_control, given_group_opener, whole_groupname, &where_to_dump_heritages, extra_heritages)) return(0); { SSTRING heritages_explanation; int my_loop; heritages_explanation.setfrom(MSG_U(I_THISGRPHASTHESEHERITAGES,"This group you selected has\nthe following heritages declared:\n\n")); my_loop=where_to_dump_heritages.getnb(); while(my_loop--){ heritages_explanation.append(where_to_dump_heritages.getitem(my_loop)->get()); heritages_explanation.append("\n"); } heritages_explanation.append(MSG_U(I_EDITINGMAYBEBADHERITAGES,"\nEditing this group may change\nthe positions of heritages' declarations.\n\nDo you still want to edit this group?\n\n")); if(confirm_yesno_window(MSG_U(T_HERITAGESFOUND,"Heritages found"), heritages_explanation.get())) return(0); } return(1); } /* !=0 if there are heritages present in this group */ int are_there_heritages(t_parser_control *parser_control, const char *given_group_opener, const char *whole_groupname, SSTRINGS *where_to_dump_heritages, SSTRINGS *extra_heritages) { int my_line=0; int total_items; // this one is used twice, for different purposes const char *current_group=NULL; /* NULL=none or name_of_the_group */ VIEWITEMS *work_vitems; const char *current_string; int case_sensitive; SSTRINGS sections_list; // all sections of this grouptype int heritages_present=0; case_sensitive=parser_control->case_sensitive_names; work_vitems=parser_control->given_viewitems; fills_sstrings_with_selected_groups(parser_control, sections_list, given_group_opener); if(extra_heritages){ total_items=extra_heritages->getnb(); while(total_items--) sections_list.add(extra_heritages->getitem(total_items)); } total_items=work_vitems->getnb(); while(total_items--){ current_string=work_vitems->getitem(my_line)->line.get(); switch(what_is_that_string(parser_control, current_string, current_group)){ case GROUP_OPENER: current_group=current_string; break; case GROUP_CLOSER: current_group=NULL; break; default: if(!smart_string_compare(current_group, whole_groupname, case_sensitive)){ { int my_loop=sections_list.getnb(); while(my_loop--){ if(!smart_string_compare(current_string, sections_list.getitem(my_loop)->get(), case_sensitive)){ where_to_dump_heritages->add(new SSTRING(sections_list.getitem(my_loop)->get())); heritages_present=1; } } } } } my_line++; } return(heritages_present); } /* replace space separators with \t (for list header) */ void columnize_words_string(const char *given_string, SSTRING &where_to_dump) { int my_counter=0; SSTRING temporary_storage; where_to_dump.setfrom(""); while(return_which_word(given_string, my_counter++, temporary_storage)){ where_to_dump.append(temporary_storage.get()); where_to_dump.append("\t"); } } /* fills where_to_dump with the word number 'which_word' (0=first one) from given_string */ /* used for parsing disklist file */ /* returns length of word (0=not found) */ int return_which_word(const char *given_string, int which_word, SSTRING &where_to_dump) { const char *copy_from; int my_length; int which_one; const char *last_beginning=NULL; int last_length=0; which_one=which_word; which_one++; copy_from=given_string; /* finds start position and length */ while(which_one--){ /* find beginning */ while(*copy_from==' ') copy_from++; last_beginning=copy_from; /* find ending */ my_length=0; while((*copy_from)&&(*copy_from!=' ')){ my_length++; copy_from++; } last_length=my_length; } where_to_dump.setfrom(last_beginning, last_length); return(last_length); } /* creates a 'boolean' gadget for Y, N or \0 */ void create_triple_boolean_gadget(DIALOG &given_dialog, FIELD_LIST **given_field_list, const char *given_fieldname, SSTRING &given_sstring) { *given_field_list=given_dialog.newf_list(given_fieldname, given_sstring); (*given_field_list)->addopt("", MSG_U(X_USEDEFAULT,"(use default)"), ""); (*given_field_list)->addopt("y", MSG_U(X_YES,"Yes"), ""); (*given_field_list)->addopt("n", MSG_U(X_NO,"No"), ""); } /* processed the given data returning Y, N or '\0' */ void load_boolean_sstring(const char *where_to_read_from, SSTRING &where_to_write) { char tempbuf[2]; char given_char; tempbuf[1]=0; if(where_to_read_from){ given_char=*where_to_read_from; switch(given_char){ case 'y': case 't': tempbuf[0]='y'; break; case 'n': case 'f': tempbuf[0]='n'; break; default: tempbuf[0]=0; } if(!tempbuf[0]){ if(!(strcmp(where_to_read_from, "off"))) tempbuf[0]='n'; if(!(strcmp(where_to_read_from, "on"))) tempbuf[0]='y'; } } else { tempbuf[0]=0; } where_to_write.setfrom(tempbuf); } void dump_sstrings_to_fieldlist(DIALOG &my_dialog, SSTRINGS &given_sstrings, FIELD_LIST *given_field_list) { int total_groups; int my_counter=0; given_field_list->addopt("", MSG_U(X_UNDEFINED,"(undefined)"), ""); total_groups=given_sstrings.getnb(); while(total_groups--){ given_field_list->addopt(given_sstrings.getitem(my_counter++)->get()); } } void dump_sstrings_to_list(DIALOG_RECORDS &my_dialog, SSTRINGS &given_sstrings) { int my_counter=0; dump_sstrings_to_list(my_dialog, given_sstrings, my_counter); } /* (my_counter is the first line in list where the provided list should be written to) */ /* my_counter data is modified after calling this */ void dump_sstrings_to_list(DIALOG_RECORDS &my_dialog, SSTRINGS &given_sstrings, int ¤t_line) { int total_groups; int my_counter=0; total_groups=given_sstrings.getnb(); while(total_groups--) my_dialog.set_menuitem(current_line++, given_sstrings.getitem(my_counter++)->get(), ""); // my_dialog.new_menuitem(given_sstrings.getitem(my_counter++)->get(), ""); } /* return true if yes, false if no */ int confirm_yesno_window(const char *my_title, const char *my_text) { if(dialog_yesno(my_title, my_text, help_nil)==MENU_YES){ return(1); } else { return(0); } } void informational_window(const char *my_title, const char *my_text) { int nothing=0; DIALOG uhoh_dialog; uhoh_dialog.edit(my_title, my_text, help_nil, nothing, MENUBUT_OK); } /* returns !=0 is string has chars <33 */ int invalid_chars_present(const char *given_string) { int my_loop; my_loop=strlen(given_string); while(my_loop--){ if(*(given_string+my_loop)<33) return(1); } return(0); } void adjust_str(SSTRING &given_string) { if(!(strcmp(given_string.get(), "czesc man"))) informational_window(" ", "Amandaconf - Linuxconf module\nby Daniel Mealha Cabrita (dancab@conectiva.com)\nv1.0 Sep 21st, 2000"); // i know, this is too lame } /* used to check if provided name for a group is valid: - is not empty - has no <33 ASCII characters - is not repeated/forbidden (checks 'forbidden list') */ /* ==0 if acceptable group name, ==1 empty name, ==2 has spaces, ==3 repeated or forbidden */ int acceptable_group_entry(const char *given_string, SSTRINGS &forbidden_names) { int repeated_forbidden=0; /* set if repeated/forbidden found */ int my_loop; /* is that empty..? */ if(!(*given_string)) return(1); /* checks if there are chars from 0 to 32 ASCII */ if(invalid_chars_present(given_string)) return(2); /* checks if the given name is not repeated or forbidden */ my_loop=forbidden_names.getnb(); while(my_loop--){ if(!(strcmp(given_string, forbidden_names.getitem(my_loop)->get()))) repeated_forbidden=1; } if(repeated_forbidden) return(3); return(0); } /* prompts user to specify a name for a new group, and creates it if the name is ok */ /* !=0 group successfully added */ int ask_name_add_group_entry(t_parser_control *parser_control, SSTRINGS &list_of_groups, const char *groupname_builder, const char *given_title, const char *given_extrainfo, const char *given_prompt) { DIALOG my_dialog; MENU_STATUS my_button=(MENU_STATUS)0; int my_selection=0; SSTRING name_for_new_group; SSTRING whole_groupname; int go_for_it=1; my_dialog.newf_str(given_prompt, name_for_new_group); while(go_for_it){ my_button=my_dialog.edit(given_title, given_extrainfo, help_nil, my_selection, MENUBUT_QUIT|MENUBUT_ACCEPT); if(my_button==MENU_ACCEPT){ switch(acceptable_group_entry(name_for_new_group.get(), list_of_groups)){ case 0: whole_groupname.setfromf(groupname_builder, name_for_new_group.get()); create_new_group(parser_control, whole_groupname.get()); update_file(parser_control); go_for_it=0; break; case 1: informational_window(MSG_R(T_BADNAMEPROVIDED), MSG_R(I_EMPTYNESSNOTALLOWED)); break; case 2: informational_window(MSG_R(T_BADNAMEPROVIDED), MSG_R(I_SPACESNOTALLOWED)); break; case 3: informational_window(MSG_R(T_BADNAMEPROVIDED), MSG_U(I_NAMEMUSTBEDIFFERENT,"The name must be different from the existing ones.")); break; default: break; } }else{ return(0); } } return(1); } /* fills sstrings with the names from the specified group */ /* returns total of items */ int fills_sstrings_with_selected_groups(t_parser_control *parser_control, SSTRINGS &sstrings_to_fill, const char *match_this_string) { int my_loop; const char *current_string; SSTRING temp_str; int case_sensitive; case_sensitive=parser_control->case_sensitive_names; my_loop=fills_sstrings_with_group_openers(parser_control, sstrings_to_fill); while(my_loop--){ current_string=sstrings_to_fill.getitem(my_loop)->get(); if(compare_the_header(match_this_string, current_string, case_sensitive)){ sstrings_to_fill.remove_del(my_loop); }else{ /* picks the name attributed to this group */ temp_str.setfrom((current_string+strlen(match_this_string))); { const char *temp_str_char; int where_theres_space=0; temp_str_char=temp_str.get(); while((*temp_str_char)&&(*temp_str_char!=' ')){ where_theres_space++; temp_str_char++; } temp_str.truncate(where_theres_space); /* ok, string now done, let's replace the old one.. */ sstrings_to_fill.getitem(my_loop)->setfrom(temp_str.get()); } } } return(sstrings_to_fill.getnb()); } /* erase all directory's files and, then, the directory itself */ /* (does not remove internal subdirectories) */ /* returns zero if ok, nonzero if unsuccessful */ int zaapboom_directory(const char *which_one) { DIR *my_dir; struct dirent *ent; char tempy[2048]; if((my_dir=opendir(which_one))){ while((ent=readdir(my_dir))){ if(strcmp(ent->d_name, ".")&&strcmp(ent->d_name, "..")){ sprintf(tempy, "%s/%s", which_one, ent->d_name); unlink(tempy); } } closedir(my_dir); } return(rmdir(which_one)); } /* goatsucker sucks.. */