/* here are the routines which deal with the printers' config files, the variables which deal with the /var/spool/lpd/my_printer/ files are here (the printcap-related ones are in printer_common_data.h) */ #include #include #include #include #include "deez_parser.h" #include "printer_printcap.h" #include "printer_common_data.h" #include "printer_cfile.h" #include "printer_fi.h" #include "printer.m" #include "printer_smbncp-specific.h" /* these are my_parms, first entry is the filename */ char ps_cfg_tag[]="postscript.cfg\0GSDEVICE=\0RESOLUTION=\0COLOR=\0PAPERSIZE=\0EXTRA_GS_OPTIONS=\0REVERSE_ORDER=\0PS_SEND_EOF=\0NUP=\0RTLFTMAR=\0TOPBOTMAR=\0\0"; char to_cfg_tag[]="textonly.cfg\0TEXTONLYOPTIONS=\0CRLFTRANS=\0TEXT_SEND_EOF=\0\0"; char ge_cfg_tag[]="general.cfg\0DESIRED_TO=\0PAPERSIZE=\0PRINTER_TYPE=\0ASCII_TO_PS=\0\0"; /* these properties don't store all printers simultaneously (unlike printcap ones), they only store for the currently-edited printer */ struct t_rh_array ps_cfg[10]; struct t_rh_array to_cfg[3]; struct t_rh_array ge_cfg[4]; /* variables for editfilter field of editprinter window */ /* they're meant to be accessed only by editfilter_window(int which_printer, DIALOG &filterwindow) editprinter_window(int which_printer) (which are one window now) */ char f_printername[TYPICAL_STRING_SIZE]; /* GUI variables */ char f_filterdescription[BIG_STRING_SIZE]; SSTRING f_resolution; SSTRING f_papersize; SSTRING f_colordepth; char f_sendeof; char f_correctcrlf; char f_fastascii; SSTRING f_printedpages; int f_horizmargins; int f_vertmargins; char f_extragsopt[TYPICAL_STRING_SIZE]; /* writes 'printer.lp_something This is my filter description' to global linuxconf settings file */ /* this is necessary to know which printer was selected by user since now there are new entries in printerdb file which points to the same drivername, because this sometimes the wrong printer is showed after selection just because it uses the same GS driver */ void write_filter_description(int which_printer, const char *given_desc) { char mtemp[TYPICAL_STRING_SIZE]; char *zerothis; strcpy(mtemp, my_printcap[which_printer].printer_name); if((zerothis=strchr(mtemp, '|'))) *zerothis=0; strcat(mtemp, "_filterdesc"); linuxconf_replace ("printer", mtemp, given_desc); linuxconf_save(); } /* reads filter description from global linuxconf settings file */ const char *read_filter_description(int which_printer) { char mtemp[TYPICAL_STRING_SIZE]; char *zerothis; strcpy(mtemp, my_printcap[which_printer].printer_name); if((zerothis=strchr(mtemp, '|'))) *zerothis=0; strcat(mtemp, "_filterdesc"); return(linuxconf_getval("printer", mtemp)); } void remove_filter_description(int which_printer) { char mtemp[TYPICAL_STRING_SIZE]; char *zerothis; strcpy(mtemp, my_printcap[which_printer].printer_name); if((zerothis=strchr(mtemp, '|'))) *zerothis=0; strcat(mtemp, "_filterdesc"); linuxconf_removeall ("printer", mtemp); linuxconf_save(); } /* creates a thing like: ##PRINTTOOL3## LOCAL uniprint NAxNA legal {} U_EpsonStylusColor stc_h {} from the currently selected printer (loaded to variables) */ void create_commented_printcap_config(char *output_string) { char *my_startentry; char my_color[TYPICAL_STRING_SIZE]; char my_crlftrans[TYPICAL_STRING_SIZE]; *output_string=0; if(*ps_color) { strcpy(my_color, ps_color); } else { strcpy(my_color, "Default"); } if(*to_crlftrans){ strcpy(my_crlftrans, to_crlftrans); } else { strcpy(my_crlftrans, "{}"); } my_startentry=return_filter_propertylist(f_printername, "StartEntry: "); /* stair-stepping */ sprintf(output_string, "##PRINTTOOL3## %s %s %s %s {} %s %s %s", ge_printer_type, ps_gsdevice, ps_resolution, ps_papersize, my_startentry, my_color, my_crlftrans); free(my_startentry); } /* sorts the given string list */ void sort_string_list(char *given_string_list) { int my_size; char *read_point; char *my_buff; char my_last_string[TYPICAL_STRING_SIZE]; char my_current_selection[TYPICAL_STRING_SIZE]; char *write_point; *my_last_string=0; *my_current_selection=0; my_size=0; read_point=given_string_list; while(*read_point){ while(*read_point++){ my_size++; } my_size++; } my_size++; if((my_buff=(char *)malloc(my_size))){ write_point=my_buff; while(*my_current_selection!='é'){ strcpy(my_current_selection, "é"); /* certainly the last one */ read_point=given_string_list; while(*read_point){ if(strcmp(read_point, my_current_selection)<0){ if(strcmp(read_point, my_last_string)>0){ strcpy(my_current_selection, read_point); } } read_point+=strlen(read_point)+1; } if(*my_current_selection!='é'){ strcpy(write_point, my_current_selection); write_point+=strlen(write_point)+1; strcpy(my_last_string, my_current_selection); } } *write_point=0; } memcpy(given_string_list, my_buff, my_size); free(my_buff); } /* given a string pointer, seeks for 0 and, then, returns the 0's address+1 (beginning of next string) */ /* returns NULL if that address also contains zero (end of string series) */ char *gimme_next_string(const char *from_this_point) { const char *my_counter; my_counter=from_this_point; while(*(my_counter++)); if(!(*my_counter)) my_counter=NULL; return((char *)my_counter); } /* which_printer is the string just after 'Description: {' */ char *return_filter_propertylist(char *which_printer, char *which_property) { FILE_CFG *my_file; int myfilesize; char *my_buff; char *my_out_buff=NULL; char *my_secondary_buff; char *where_to_write; char the_printername[500]; char *read_from_here; // if((my_file=fopen(PRINTERDB_FILENAME, "r"))){ if((my_file=cf_printerdbfile.fopen("r"))){ fseek(my_file, 0, SEEK_END); myfilesize=ftell(my_file); fseek(my_file, 0, SEEK_SET); if((my_buff=(char *)malloc(myfilesize+1))){ *my_buff=0; *(my_buff+myfilesize)=0; fread(my_buff, myfilesize, 1, my_file); if((my_out_buff=(char *)malloc(myfilesize+1))){ where_to_write=my_out_buff; *where_to_write=0; if((my_secondary_buff=(char *)malloc(myfilesize+1))){ int i; i=0; while(copy_specific_block(my_buff, "StartEntry: ", i++, my_secondary_buff)){ parse_string_data(my_secondary_buff, "Description: {", "}", the_printername); if(!(strcmp(the_printername, which_printer))){ read_from_here=my_secondary_buff; while((read_from_here=parse_string_data(read_from_here, which_property, "\n", where_to_write))) { where_to_write+=strlen(where_to_write)+1; } *where_to_write=0; /* makes the 2nd zero, meaning the list finished */ } } } } free(my_buff); } // fclose(my_file); cf_printerdbfile.fclose(my_file); } return(my_out_buff); } /* allocate a string in memory and return its pointer containing all the printer filters' names. name1\0name2\0ame3\0.. ..\0last_name\0\0 */ /* it MUST be freed after then! free(blabla) */ char *return_filters_list(void) { FILE_CFG *my_file; int myfilesize; char *my_buff; char *my_out_buff=NULL; char *my_secondary_buff; char *where_to_write; // if((my_file=fopen(printerdb_filename, "r"))){ if((my_file=cf_printerdbfile.fopen("r"))){ fseek(my_file, 0, SEEK_END); myfilesize=ftell(my_file); fseek(my_file, 0, SEEK_SET); if((my_buff=(char *)malloc(myfilesize+1))){ *my_buff=0; *(my_buff+myfilesize)=0; fread(my_buff, myfilesize, 1, my_file); if((my_out_buff=(char *)malloc(myfilesize+1))){ where_to_write=my_out_buff; *where_to_write=0; if((my_secondary_buff=(char *)malloc(myfilesize+1))){ int i; i=0; while(copy_specific_block(my_buff, "StartEntry: ", i++, my_secondary_buff)){ parse_string_data(my_secondary_buff, "Description: {", "}", where_to_write); where_to_write+=strlen(where_to_write)+1; } *where_to_write=0; /* makes the 2nd zero, meaning the list finished */ } } free(my_buff); } // fclose(my_file); cf_printerdbfile.fclose(my_file); } /* sorts filterlist.. */ sort_string_list(my_out_buff); return(my_out_buff); } /* if add_export=true, append a 'export ' before each entry */ void save_rhprt_config(char *my_parms, struct t_rh_array *where_to_go, char *printer_spool_path, int add_export) { FILE_CFG *my_file; char whole_filename[500]; char *my_pointer; int my_counter; char data_to_file[500]; my_pointer=my_parms; my_counter=0; sprintf(whole_filename, "%s/%s", printer_spool_path, my_parms); const char *user = "root"; const char *group = "root"; if(kind_of_lpr_system_installed==LPRTYPE_LPRNG){ user = "$lprng_user"; group = "$lprng_group"; } CONFIG_FILE f_tmp (whole_filename,help_nil,CONFIGF_OPTIONAL ,user,group,"$lprng_perm","lpd"); if((my_file=f_tmp.fopen("w"))){ fputs("#\n# This file was generated by Linuxconf's Printer module\n# according fileformat from RH's printtool\n#\n# Comments and unsupported entries may be lost!\n#\n\n", my_file); while((my_pointer=gimme_next_string(my_pointer))){ if(add_export){ sprintf(data_to_file, "export %s%s\n", my_pointer, where_to_go[my_counter++].d); } else { sprintf(data_to_file, "%s%s\n", my_pointer, where_to_go[my_counter++].d); } fputs(data_to_file, my_file); } fclose(my_file); } } /* load RH's printer config file to previously-allocated memory */ /* returns 0 if ok */ int load_rhprt_config(char *my_parms, struct t_rh_array *where_to_go, char *printer_spool_path) { FILE *my_file; int myfilesize; char *my_buff; char *my_pointer; int my_counter; char whole_filename[500]; my_pointer=my_parms; my_counter=0; sprintf(whole_filename, "%s/%s", printer_spool_path, my_parms); if((my_file=fopen(whole_filename, "r"))){ fseek(my_file, 0, SEEK_END); myfilesize=ftell(my_file); fseek(my_file, 0, SEEK_SET); if((my_buff=(char *)malloc(myfilesize+1))){ *my_buff=0; *(my_buff+myfilesize)=0; fread(my_buff, myfilesize, 1, my_file); while((my_pointer=gimme_next_string(my_pointer))){ parse_string_data(my_buff, my_pointer, "\n", where_to_go[my_counter++].d); } free(my_buff); } fclose(my_file); return(0); } return(1); } /* load config files in printer spool directory to memory if they don't exist, create them with defaults */ void load_initialise_secondary_configfiles(int which_printer) { char tempy[PATH_MAX]; /* creates filterscript in spool directory, if absent */ sprintf(tempy, "%s/%s", my_printcap[which_printer].sd, FILTERSCRIPT_NAME); const char *user = "root"; const char *group = "root"; if(kind_of_lpr_system_installed==LPRTYPE_LPRNG){ user = "$lprng_user"; group = "$lprng_group"; } CONFIG_FILE f_tmp (tempy,help_nil,CONFIGF_OPTIONAL ,user,group,"$lprng_perm","lpd"); if(!f_tmp.exist()){ FILE_CFG *my_filter; FILE_CFG *my_master_filter; int myfilesize; char *my_buff; if((my_filter=f_tmp.fopen("w"))){ if((my_master_filter=cf_masterfilterfile.fopen("r"))){ // if((my_master_filter=fopen(MASTERFILTER_FULLPATH, "r"))){ /* read file to memory.. */ fseek(my_master_filter, 0, SEEK_END); myfilesize=ftell(my_master_filter); fseek(my_master_filter, 0, SEEK_SET); if((my_buff=(char *)malloc(myfilesize+1))){ if(fread(my_buff, myfilesize, 1, my_master_filter)){ *(my_buff+myfilesize)=0; /* write it.. */ fputs(my_buff, my_filter); } cf_masterfilterfile.fclose(my_master_filter); free(my_buff); }else{ cf_masterfilterfile.fclose(my_master_filter); } } else { /* this is unlikely to happen, but it will put my own filter instead if RH's one is not accessible */ fputs("#!/bin/bash\n\n# this filterscript was generated by Linuxconf's Printer module\n", my_filter); fputs("# currently it only uses the postscript.cfg file, but it may change in future\n\n", my_filter); fputs("export SPOOLDIR=$(pwd)\n\nsource ${SPOOLDIR}/postscript.cfg\n# source ${SPOOLDIR}/general.cfg\n# source ${SPOOLDIR}/textonly.cfg\n", my_filter); fputs("\n", my_filter); fputs("if [ \"$GSDEVICE\" != \"TEXT\" ]; then\n", my_filter); fputs(" if [ \"$RESOLUTION\" != \"NAxNA\" ]; then\n", my_filter); fputs(" nenscript -TA4 -ZB -p- |\n", my_filter); fputs(" gs -q -sDEVICE=$GSDEVICE \\\n", my_filter); fputs(" -r$RESOLUTION \\\n", my_filter); fputs(" -sPAPERSIZE=$PAPERSIZE \\\n", my_filter); fputs(" -dNOPAUSE \\\n -dSAFER \\\n", my_filter); fputs(" $COLOR \\\n", my_filter); fputs(" $EXTRA_GS_OPTIONS \\\n", my_filter); fputs(" -sOutputFile=- -\n", my_filter); fputs(" else\n", my_filter); fputs(" nenscript -TA4 -ZB -p- |\n", my_filter); fputs(" gs -q -sDEVICE=$GSDEVICE \\\n", my_filter); fputs(" -sPAPERSIZE=$PAPERSIZE \\\n", my_filter); fputs(" -dNOPAUSE \\\n -dSAFER \\\n", my_filter); fputs(" $COLOR \\\n", my_filter); fputs(" $EXTRA_GS_OPTIONS \\\n", my_filter); fputs(" -sOutputFile=- -\n", my_filter); fputs(" fi\n", my_filter); fputs("else\n cat -\nfi\n\n", my_filter); fputs("\nif [ \"$PS_SEND_EOF\" == \"\" ]; then\n", my_filter); fputs(" printf \"\\004\"\nfi\n", my_filter); } fclose(my_filter); } } /* postscript.cfg */ sprintf(tempy, "%s/%s", my_printcap[which_printer].sd, ps_cfg_tag); if(!this_file_exists(tempy)){ strcpy(ps_gsdevice, "TEXT"); strcpy(ps_resolution, "NAxNA"); *ps_color=0; strcpy(ps_papersize, "a4"); strcpy(ps_extra_gs_options, "\"\""); *ps_reverse_order=0; strcpy(ps_send_eof, "NO"); strcpy(ps_nup, "1"); strcpy(ps_rtlftmar, "18"); strcpy(ps_topbotmar, "18"); } else { load_rhprt_config(ps_cfg_tag, ps_cfg, my_printcap[which_printer].sd); /* adjust ps_color data */ { char *where_it_should_begin; char tempy2[TYPICAL_STRING_SIZE]; if(*ps_color){ if((where_it_should_begin=strchr(ps_color, '='))){ strcpy(tempy2, ++where_it_should_begin); strcpy(ps_color, tempy2); } } } } /* textonly.cfg */ sprintf(tempy, "%s/%s", my_printcap[which_printer].sd, to_cfg_tag); if(!this_file_exists(tempy)){ *to_textonlyoptions=0; *to_crlftrans=0; strcpy(to_text_send_eof, "NO"); } else { load_rhprt_config(to_cfg_tag, to_cfg, my_printcap[which_printer].sd); } /* general.cfg */ sprintf(tempy, "%s/%s", my_printcap[which_printer].sd, ge_cfg_tag); if(!this_file_exists(tempy)){ strcpy(ge_desired_to, "ps"); strcpy(ge_papersize, "a4"); // strcpy(ge_printer_type, "LOCAL"); /* not defined here */ strcpy(ge_ascii_to_ps, "NO"); } else { load_rhprt_config(ge_cfg_tag, ge_cfg, my_printcap[which_printer].sd); } /* define everything defined before (from printcap) */ strcpy(ge_printer_type, "LOCAL"); switch(return_printer_type(which_printer)){ case PRT_REMOTE: strcpy(ge_printer_type, "REMOTE"); break; case PRT_SMBWIN: strcpy(ge_printer_type, "SMB"); break; case PRT_NETWARE: strcpy(ge_printer_type, "NCP"); break; case PRT_DIRECT: strcpy(ge_printer_type, "DIRECT"); break; } /* patches the -dBitsPerPixel=NONONONO thing */ { char tempz[TYPICAL_STRING_SIZE]; char *where_copy_from; strcpy(tempz, ps_color); if(*ps_color){ if((where_copy_from=strchr(ps_color, '='))) strcpy(tempz, ++where_copy_from); } /* if the filter description is not found in internal linuxconf configfile.. try to guess based on the filtername */ { const char *readen_filterdesc; /* ok, now let's get the filter description from linuxconf global configfile _or_ guess it */ if((readen_filterdesc=read_filter_description(which_printer))){ strcpy(f_printername, readen_filterdesc); }else{ tellme_which_printer_it_is(ps_gsdevice, tempz, f_printername); } } } } /* dump all the current printer's filter data to right files.. */ /* this what is called when user clicked the button for saving preferences */ void save_all_the_filters_stuff(int which_printer) { save_from_gui_variables(); /* adjust ps_color data, attach '-dBitsPerPixel=%s' but NOT if postscript driver is 'uniprint' */ if((*ps_color)&&(strcmp(ps_gsdevice, "uniprint")&&(strcmp(ps_gsdevice, "ppa")))){ char tempy2[TYPICAL_STRING_SIZE]; sprintf(tempy2, "-dBitsPerPixel=%s", ps_color); strcpy(ps_color, tempy2); } /* postscript.cfg */ save_rhprt_config(ps_cfg_tag, ps_cfg, my_printcap[which_printer].sd, 0); /* textonly.cfg */ save_rhprt_config(to_cfg_tag, to_cfg, my_printcap[which_printer].sd, 0); /* general.cfg */ save_rhprt_config(ge_cfg_tag, ge_cfg, my_printcap[which_printer].sd, 1); /* remove the heading '-dBitsPerPixel=' from ps_color, if it was previously added */ if(*ps_color){ char tempz[TYPICAL_STRING_SIZE]; char *where_copy_from; strcpy(tempz, ps_color); if((where_copy_from=strchr(ps_color, '='))){ strcpy(tempz, ++where_copy_from); strcpy(ps_color, tempz); } } } /* fills with right printername (Description:) from given specs */ void tellme_which_printer_it_is(char *given_gsdriver, char *given_colordepth, char *output_string) { tellme_fully_which_printer_it_is(given_gsdriver, given_colordepth, output_string, NULL); } /* fills with right printername (Description:) from given specs */ /* if secondary output not null, it also returns the StartEntry: field */ void tellme_fully_which_printer_it_is(char *given_gsdriver, char *given_colordepth, char *output_string, char *secondary_output) { FILE_CFG *my_file; int myfilesize; char *my_buff; char *my_secondary_buff; char seek_for[TYPICAL_STRING_SIZE]; char string_ends_with[10]; char matchs_with[TYPICAL_STRING_SIZE]; char temp_output[500]; char *read_from_here; if(output_string) *output_string=0; if(secondary_output) *secondary_output=0; /* if not 'ppa' nor 'uniprint', normal filter */ if((strcmp(given_gsdriver, "uniprint"))&&(strcmp(given_gsdriver, "ppa"))){ strcpy(seek_for, "GSDriver: "); sprintf(string_ends_with, "\n"); strcpy(matchs_with, given_gsdriver); }else{ strcpy(seek_for, "BitsPerPixel: {"); strcpy(string_ends_with, "}"); strcpy(matchs_with, given_colordepth); } // if((my_file=fopen(printerdb_filename, "r"))){ if((my_file=cf_printerdbfile.fopen("r"))){ fseek(my_file, 0, SEEK_END); myfilesize=ftell(my_file); fseek(my_file, 0, SEEK_SET); if((my_buff=(char *)malloc(myfilesize+1))){ *my_buff=0; *(my_buff+myfilesize)=0; fread(my_buff, myfilesize, 1, my_file); if((my_secondary_buff=(char *)malloc(myfilesize+1))){ int i; i=0; while(copy_specific_block(my_buff, "StartEntry: ", i++, my_secondary_buff)){ read_from_here=my_secondary_buff; while((read_from_here=parse_string_data(read_from_here, seek_for, string_ends_with, temp_output))){ if(!strcmp(matchs_with, temp_output)){ if(output_string) parse_string_data(my_secondary_buff, "Description: {", "}", output_string); if(secondary_output) parse_string_data(my_secondary_buff, "StartEntry: ", "\n", secondary_output); } } } } free(my_buff); } // fclose(my_file); cf_printerdbfile.fclose(my_file); } } /* given a string {blablabla0} {blablabla1} {blablabla2} .. copies the specified element between the {} (element1 means 'blablabla1') */ void gimme_string_element(char *given_string, int which_element, char *output_string) { char *my_pointer; char *my_output_pointer; int my_counter; my_pointer=given_string-1; my_counter=which_element+1; my_output_pointer=output_string; while((my_counter--)&&my_pointer){ my_pointer=strchr(++my_pointer, '{'); } if((my_pointer)){ my_pointer++; while(my_pointer&&(*my_pointer)&&(*my_pointer!='}')){ *my_output_pointer++=*my_pointer++; } } *my_output_pointer=0; } /* save the printcap configuration */ void save_all_printers_data(void) { FILE_CFG *printcap_file; int i; // if((printcap_file=fopen(PRINTCAP_LOCATION, "w"))){ if((printcap_file=cf_printcapfile.fopen("w"))){ char tempy[300]; sprintf(tempy, "# %s\n#\n# This file was generated by Linuxconf's Printer module\n", PRINTCAP_LOCATION); fputs(tempy, printcap_file); sprintf(tempy, "# You may edit this file directly, but only standard printcap entries\n# will be preserved.\n"); fputs(tempy, printcap_file); i=0; // while (i&1", fried_chicken, 1023); if(strstr(fried_chicken, "LPRng")){ return(LPRTYPE_LPRNG); } return(LPRTYPE_OLD_LPR); } /* will reset resolution and colordepth for first permitted values (because new filter installed) */ /* given the selected filtername */ /* UNFINISHED */ void new_filter_so_reset_some_things(char *overrider_printer) { char *my_new_gs_driver; char *my_new_resolution; char *my_new_colordepth; char tempy[TYPICAL_STRING_SIZE]; char tempy2[TYPICAL_STRING_SIZE]; /* f_printername redefined.. */ strcpy(f_printername, overrider_printer); my_new_gs_driver=return_filter_propertylist(overrider_printer, "GSDriver: "); my_new_resolution=return_filter_propertylist(overrider_printer, "Resolution: "); my_new_colordepth=return_filter_propertylist(overrider_printer, "BitsPerPixel: "); if(!(strcmp(my_new_gs_driver, "ppa"))) /* ppa printers shall not have fast ascii enabled */ f_fastascii=0; /* ps_gsdevice redefined.. */ strcpy(ps_gsdevice, my_new_gs_driver); /* ps_resolution redefined.. */ gimme_string_element(my_new_resolution, 0, tempy); gimme_string_element(my_new_resolution, 1, tempy2); sprintf(ps_resolution, "%sx%s", tempy, tempy2); /* ps_color redefined.. */ gimme_string_element(my_new_colordepth, 0, ps_color); free(my_new_colordepth); free(my_new_resolution); free(my_new_gs_driver); } /* filed popup menus with printerdb data, according the printer selected */ /* processing: 0-none 1-{300} {300} {} to 300x300 2-{blabla0} {blablabla..} to blabla0, blablabla.. */ /* returns how many items were added */ int populate_sstrings(char *filter_id, char *field_identificator, int processing, SSTRINGS &descriptions, SSTRINGS &values) { char *generated_list; char *readpoint; char my_desc[500]; char my_retcod[500]; int how_many_added=0; generated_list=return_filter_propertylist(filter_id, field_identificator); readpoint=generated_list; while(*readpoint){ switch(processing){ case 0: strcpy(my_desc, readpoint); strcpy(my_retcod, readpoint); break; case 1: { char xres[20], yres[20], commentres[100]; gimme_string_element(readpoint, 0, xres); gimme_string_element(readpoint, 1, yres); gimme_string_element(readpoint, 2, commentres); sprintf(my_retcod, "%sx%s", xres, yres); if(*commentres){ sprintf(my_desc, "%s (%s)", my_retcod, commentres); } else { sprintf(my_desc, "%s", my_retcod); } } break; case 2: { gimme_string_element(readpoint, 0, my_retcod); gimme_string_element(readpoint, 1, my_desc); } break; } if(strcmp("NAxNA", my_desc)){ // if != "NAxNA" descriptions.add(new SSTRING(my_desc)); values.add(new SSTRING(my_retcod)); how_many_added++; } readpoint+=strlen(readpoint)+1; } free(generated_list); return(how_many_added); } /* given_number = printer number from 0 to N-1 (N = total of printers) returns the _real_ location (which may be the same number, or not if there's some empty printcap 'slot' in the middle of the list */ /* returns -1 is printer does not exist */ int translate_printer_number(int given_number) { int my_counter=0; int i=0; while(i