/* this part manages: the main window (selects printer edit, allowed hosts and spool manager) (also manages printcap, but the heavy part of printcap managing is in another listing) the printerlist edit and printer add option it also have the routines for activating the lpd for startup for runlevels 2, 3, 4 and 5 if it isn't starting automatically and user confirms that it should be starting instead */ /* TO DO.. - better perm_access() support (permmiting non-root users to manage the queue) - sub systems definition (for rhs-printfilters) */ #include #include #include "printer.h" #include "printer.m" #include #include #include #include #include #include "deez_parser.h" #include "printer_printcap.h" #include "printer_props.cc" #include "printer_netwauth.cc" #include "printer_cfile.h" #include "printer_fi.h" #include "printer_gi.h" #include #include /* checks if lpd is starting automatically, if yes do nothing. if not, ask user if (s)he wants to change it and, if confirmed, - makes lpd starting automatically - starts lpd */ void check_lpd_status_and_ask_user(void) { char my_work_string[500]; char my_fullpath_string[500]; int current_runlevel=0; /* verifies if lpd is starting automatically for the current runlevel */ execute_proggy_and_get_stdout("runlevel", my_work_string, 500); if(parse_integer_data(my_work_string, "N ", ¤t_runlevel)){ if(!current_runlevel) current_runlevel=3; sprintf(my_fullpath_string, "/etc/rc.d/rc%d.d/S60lpd", current_runlevel); if(!this_file_exists(my_fullpath_string)){ sprintf(my_work_string, MSG_U(M_LPDNOTSTTX, "\"lpd\" is not being started automatically for the current runlevel (%d).\nIn order to be able to print you need it running.\n\nDo you want \"lpd\" always starting automatically (for runlevels 2, 3, 4 and 5)?\n(When Linuxconf asks if you want changes taking effect or not, reply positively)"), current_runlevel); if(confirm_yesno_window(MSG_U(M_LPDNOTSTTT, "warning about lpd startup"), my_work_string)){ /* set lpd starting for runlevels 2, 3, 4 and 5.. stopping at 6 */ unlink(KLINKLEV2_FULLPATH); unlink(KLINKLEV3_FULLPATH); unlink(KLINKLEV4_FULLPATH); unlink(KLINKLEV5_FULLPATH); unlink(SLINKLEV6_FULLPATH); symlink(LPDSCRIPT_TO_LINK, SLINKLEV2_FULLPATH); symlink(LPDSCRIPT_TO_LINK, SLINKLEV3_FULLPATH); symlink(LPDSCRIPT_TO_LINK, SLINKLEV4_FULLPATH); symlink(LPDSCRIPT_TO_LINK, SLINKLEV5_FULLPATH); symlink(LPDSCRIPT_TO_LINK, KLINKLEV6_FULLPATH); } } } } /* returns true if printer was successfully added */ int addprinter_window(char flag) { int i; int printername_already_taken; char printer_name[30]; char type_printr; int my_returncode; char my_pathspooldirectories[TYPICAL_STRING_SIZE]; char my_fullspoolpath[500]; strcpy(my_pathspooldirectories, DEFAULT_SPOOLDIRS_HOME); my_returncode=0; /* useless, present only for compiler warning supressing */ // this is junk, but we don't want the make msg to complain // informational_window(MSG_U(M_MAXPRINTERSREACHEDTT, "Maximum printers' limit reached"), MSG_U(M_MAXPRINTERSREACHEDTX, "Too many printers attached to this system.\nRemove some printer and try again.")); { DIALOG addprinter_dialog; *printer_name=0; type_printr=0; /* suggests an unique queuename */ { char proposal_of_printername[TYPICAL_STRING_SIZE]; int i=0; int proposal_number=1; strcpy(proposal_of_printername, "lp"); while(i1){ sprintf(proposal_of_printername, "%s%d", DEFAULT_PRINTERNAME, proposal_number); } else { strcpy(proposal_of_printername, DEFAULT_PRINTERNAME); } // if(!strcmp(my_printcap[i].printer_name, proposal_of_printername)){ if(is_this_printer_there(my_printcap[i].printer_name, proposal_of_printername)){ i=0; proposal_number++; } else { i++; } } strcpy(printer_name, proposal_of_printername); /* suggested printername given to the user */ if (flag) { /* flag = true for vregistry */ strcpy(printer_name, ""); /* for vregistry, have it empty */ } } sprintf(my_fullspoolpath, "%s/%s", my_pathspooldirectories, printer_name); addprinter_dialog.newf_str(MSG_U(M_NEWPRINTERNAME, "Printer name"), printer_name, 20); addprinter_dialog.newf_str(MSG_U(M_NEWSPOOLDIR, "Spool directory"), my_fullspoolpath, 499); /* uncomment this line if you want to provide an alternative path for spool directories (so the new spool will be created there) */ // addprinter_dialog.newf_str("Path for spool diretories:", my_pathspooldirectories, TYPICAL_STRING_SIZE-1); addprinter_dialog.newf_title("", MSG_U(M_NEWPRTATTACHEDAS, "Attached as")); addprinter_dialog.newf_radio("", type_printr, PRT_LOCAL, MSG_U(M_NEWPRTLOCAL, "Local Printer")); addprinter_dialog.newf_radio("", type_printr, PRT_REMOTE, MSG_U(M_NEWPRTREMOTE, "Remote Queue")); addprinter_dialog.newf_radio("", type_printr, PRT_SMBWIN, MSG_U(M_NEWPRTSMBWIN, "SMB/Windows Printer")); addprinter_dialog.newf_radio("", type_printr, PRT_NETWARE, MSG_U(M_NEWPRTNETW, "NetWare Printer (NCP)")); addprinter_dialog.newf_radio("", type_printr, PRT_DIRECT, MSG_U(M_NEWPRTDIRECT, "Direct (jetdirect, printserver, etc.)")); my_returncode=addprinter_dialog.edit(MSG_U(M_ADDINGPRINTERTT, "Adding a printer..."), MSG_U(M_ADDINGPRINTERTX, "Please specify a name and how the printer is connected.\n\"lp\" is the default system printer.\n"), help_nil); strgname(printer_name); //flag is true if going through the vregistry if (flag) { sprintf(my_fullspoolpath, "%s/%s", my_pathspooldirectories, printer_name); } } if((my_returncode==MENU_CANCEL)||(my_returncode==MENU_ESCAPE)) return(0); /* verifies if printer name and spool diretory are acceptable */ if(!printer_name[0]){ informational_window(MSG_U(M_PRTNAMEUNDEFINEDTT, "Printer name not defined"), MSG_U(M_PRTNAMEUNDEFINEDTX, "You must define a name for each added printer")); return(0); } if(!my_fullspoolpath[0]){ informational_window(MSG_U(M_SPOOLDIRUNDEFTT, "Spool directory not defined"), MSG_U(M_SPOOLDIRUNDEFTX, "You must define a name for a spool directory")); return(0); } if(invalid_string_provided(my_fullspoolpath, NULL, " !@#$%^&*()=+?|\\<>,[]{}~`'\0")){ informational_window(MSG_U(M_INVALIDCHSPOOLTT, "Invalid name for spool directory"), MSG_U(M_INVALIDCHSPOOLTX, "There are certain characters which can't be used while naming the directory.\n(space and control characters are not supported, try using Aa-Zz 0-9)")); return(0); } if(invalid_string_provided(printer_name, NULL, " !@#$%^&*()=+/?\\<>,[]{}~`'\0")){ informational_window(MSG_U(M_PRTNAMEINVALIDTT, "Invalid printer name provided"), MSG_U(M_PRTNAMEINVALIDTX, "There are certain characters which can't be used while naming the printer.\n(space and control characters are not supported, try using Aa-Zz 0-9)")); return(0); } /* verifies if the given name for new printer does not exist */ // i=MAX_PRINTERS; i=total_printer_entries; printername_already_taken=0; while(i--){ // if((general_printer_index[i].exists)&&(!strcmp(printer_name, general_printer_index[i].devname))) // printername_already_taken=1; if((general_printer_index[i].exists)&&(is_this_printer_there(printer_name, general_printer_index[i].devname))) printername_already_taken=1; } if(printername_already_taken){ informational_window(MSG_U(M_PRTNAMEREPEATEDTT, "Repeated printer name given"), MSG_U(M_PRTNAMEREPEATEDTX, "You must define an unique name for each printer")); return(0); } if(create_a_printer(type_printr, printer_name, my_fullspoolpath)) return(0); // error return(1); // ok } void manage_printerslistwindow(void) { DIALOG_LISTE main_dialog; int my_selection=0; main_dialog.newf_head("", MSG_U(M_PRTNAMEDESCTABLE, "printer name \tdescription")); while(1){ int total_items_added=0; /* this will need the free_buffers_of_mine() later */ load_printcap(); { int i=0; while(iget())) selected_printer=my_counter; my_counter++; } } /* creates the radio buttons' list */ { int my_counter=0; while(total_printers--){ my_dialog.newf_radio("", selected_printer, my_counter, printers_list.getitem(my_counter)->get()); my_counter++; } } my_button=my_dialog.edit(MSG_U(T_DEFAULTPRINTER, "Default printer"), "", help_nil); if(my_button==MENU_ACCEPT){ /* picks only one name (if printername is something like lp|blah|xyz) */ char adjusted_pn[1000]; char *found_pipe; strcpy(adjusted_pn, printers_list.getitem(selected_printer)->get()); if((found_pipe=strchr(adjusted_pn, '|'))) *found_pipe='\0'; my_vitems.update("default_printer", adjusted_pn); my_vitems.write(cf_lpdconf, NULL); } }else{ /* no printer installed */ informational_window(MSG_U(T_NOPRTINSTALLED, "No printer installed"), MSG_U(I_NOPRTINSTALLED, "At least two printers are needed\nin order to this configuration\nto be useful.")); } gi_close(); } /* shows and manage the main menu */ /* when it returns the module is supposed to quit */ void manage_mainmenu() { MENU_STATUS my_button; int my_selection; DIALOG_MENU dia_mymenu; my_selection=0; dia_mymenu.new_menuitem("", "", MSG_U(M_MAINADDEDPRINTERS, "Add/Edit printers")); if(kind_of_lpr_system_installed==LPRTYPE_OLD_LPR) dia_mymenu.new_menuitem("", "", MSG_U(M_MAINNETWKAUTH, "Network authorizations")); dia_mymenu.new_menuitem("", "", MSG_U(M_MAINQUEUEMGR, "Queue manager")); if(kind_of_lpr_system_installed==LPRTYPE_LPRNG) dia_mymenu.new_menuitem("", "", MSG_U(M_CHANGEDEFAULTPRINTER, "Change the default printer")); while(1){ my_button=dia_mymenu.editmenu(MSG_U(M_MAINDIALOGTT, "Printer services setup"), "", my_main_helpfile, my_selection, MENUBUT_QUIT); if((my_button==MENU_QUIT)||(my_button==MENU_ESCAPE)) return; /* if not old_lpr then the second option will not appear, affecting the resulting code.. this patches the returned value */ if((kind_of_lpr_system_installed!=LPRTYPE_OLD_LPR)&&(my_selection>0)) my_selection++; switch(my_selection){ case 0: if(perm_rootaccess("")) manage_printerslistwindow(); break; case 1: if(perm_rootaccess("")) edit_whocanuse_myprinters(); break; case 2: if (dialog_mode != DIALOG_TREE) queue_main_window(); // Manage the queue // and per queue privileges break; case 3: if(perm_rootaccess("")) // this option won't be available if LPRng not present change_default_printer(); break; } } } void printer_ed (void) { if(is_printcap_lprng_style()){ /* printcap IS LPRng styled, unsupported */ informational_window(MSG_U(M_LPRNGPRINTCAPTT, "LPRng-style printcap file found"), MSG_U(M_LPRNGPRINTCAPTX, "This module can't manage this printcap variant.\nYou may convert the file to the classic\nprintcap format or delete it and\nlet this module recreate a fresh-new\nprintcap file.\n")); } else { /* printcap is the classic lpr format, so it's ok */ /* defines that global variable with the type of lpr system installed on machine */ kind_of_lpr_system_installed=return_lpr_system_installed_in_this_system(); /* verify if lpd is being automatically initialised */ check_lpd_status_and_ask_user(); /* main menu */ manage_mainmenu(); /* at this point the module concluded operation... */ } }