/* Copyright (c) 2001-2010, Dirk Krause All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above opyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of the Dirk Krause nor the names of contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /** @file yalc.c The yalc module used by klpr and others. */ /* #define DEBUG 1 */ #include #include #include #include #include #include #include #include #include #include #include #include /** 0 as long long unsigned. */ #if DK_HAVE_LONG_LONG_INT #define ULLZERO 0ULL #else #define ULLZERO 0UL #endif #if DK_HAVE_STDLIB_H #include #endif #if DK_HAVE_UNISTD_H #include #endif #if DK_HAVE_SIGNAL_H #include #endif #if DK_HAVE_STRING_H #include #endif #if DK_HAVE_CTYPE_H #include #endif #if DK_HAVE_CONIO_H #include #endif #if DK_HAVE_NETINET_IN_H #include #endif #if DK_HAVE_SYS_TYPES_H #include #endif /** Inside the yalc module. */ #define DK_YALC_C 1 #include "yalc.h" #include "dktools-version.h" #line 102 "yalc.ctr" /** Avoid double-free. */ #define DO_NOT_FREE_REQUEST_PDU 1 /** Dot. */ static char str_dot[] = { "." }; /** Equal sign. */ static char str_equal[] = { " = " }; /** Default application name. */ static char default_appname[] = { "yanolc" }; /** File name separator. */ static char fnsep[] = { #if DK_HAVE_FEATURE_BACKSLASH "\\" #else "/" #endif }; #if DK_HAVE_LONG_LONG_INT /** Convert long long int to text. @param s Result buffer. @param ul Value to convert. */ static void ull_to_string DK_P2(char *,s, unsigned long long,ul) { #if _MSC_VER >= 1100 sprintf(s, "%I64u", ul); #else sprintf(s, "%llu", ul); #endif } #endif #if DK_HAVE_LIBNETSNMP || DK_HAVE_LIBUCDSNMP #if DK_HAVE_LIBNETSNMP #include #include #include #ifdef __cplusplus extern "C" { #endif #if DK_HAVE_NETSNMP_ENABLE_FILELOG void netsnmp_enable_filelog DK_PR((netsnmp_log_handler *, int)); #endif #ifdef __cplusplus }; #endif #else #define UCD_COMPATIBLE 1 #include #include #include #include #endif /** Printer state: Ready. */ #define PRINTER_STATE_NORMAL 0 /** Printer state: Printing. */ #define PRINTER_STATE_BUSY 1 /** Printer state: Warning. */ #define PRINTER_STATE_WARNING 2 /** Printer state: Going offline. */ #define PRINTER_STATE_GO_OFFLINE 3 /** Printer state: Offline. */ #define PRINTER_STATE_OFFLINE 4 /** Printer state: Warmup. */ #define PRINTER_STATE_WARMUP 5 /** Printer state: Standby. */ #define PRINTER_STATE_STANDBY 6 /** Printer state: unknown. */ #define PRINTER_STATE_UNKNOWN 7 /** Printer state: Self-test. */ #define PRINTER_STATE_TESTING 8 /** Texts for printer states. */ static char *printer_state_msg[] = { "READY", "PRINTING", "READY/WARNING", "SHUTDOWN", "OFFLINE", "WARMUP", "STANDBY", "UNKNOWN-STATE", "TESTING" }; /** Check 2 OIDs for equality. @param o1 Left OID. @param l1 Number of elements in o1. @param o2 Right OID. @param l2 Number of elements in o2. @return 1 if both OIDs are equal, 0 otherwise. */ static int oids_equal DK_P4(oid *,o1,size_t,l1,oid *,o2,size_t,l2) { int back = 0; size_t i; if(l1 == l2) { back = 1; for(i = 0; i < l1; i++) { if(o1[i] != o2[i]) { back = 0; } } } return back; } /** SNMP variable to inspect. */ typedef struct { /* Low number indicates high priority */ unsigned long lineno; /**< Line number in snmpyalc cfg file. */ char *oid_text; /**< Text representation of OID. */ oid oid[MAX_OID_LEN]; /**< OID buffer. */ size_t oid_len; /**< Number of elements used in oid. */ int t; /**< Variable type: 0=unknown, 1=boolean, 2=text. */ int found; /**< Flag: Value found for this variable. */ long long_value; /**< Long integer found. */ char *string_value; /**< String value found. */ } Yalc_Snmp_Variable; /** Create variable. @param lineno Line number in snmpyalc cfg file. @param oidtext Text representation of OID to inspect. @return Pointer to new variable on success, NULL on error. */ static Yalc_Snmp_Variable * new_ysv DK_P2(unsigned long, lineno, char *, oidtext) { Yalc_Snmp_Variable *back = NULL; back = dk_new(Yalc_Snmp_Variable,1); if(back) { back->oid_text = dkstr_dup(oidtext); if(!(back->oid_text)) { dk_delete(back); back = NULL; } } if(back) { back->lineno = lineno; back->t = 0; back->found = 0; back->long_value = 0L; back->string_value = NULL; } return back; } /** Destroy variable. @param ptr Variable to destroy. */ static void delete_ysv DK_P1(Yalc_Snmp_Variable *,ptr) { char *p; if(ptr) { p = ptr->oid_text; if(p) { dk_delete(p); ptr->oid_text = NULL; } p = ptr->string_value; if(p) { dk_delete(p); ptr->string_value = NULL; } ptr->lineno = 0UL; ptr->t = 0; ptr->found = 0; ptr->long_value = 0L; dk_delete(ptr); } } /** Compare two variables to inspect by line number. @param p1 Left variable. @param p2 Right variable. @param how Comparison criteria (ignored). @return Comparison result. */ int compare_ysv DK_P3(void *,p1,void *,p2,int,how) { int back = 0; Yalc_Snmp_Variable *ptr1, *ptr2; if(p1 && p2) { ptr1 = (Yalc_Snmp_Variable *)p1; ptr2 = (Yalc_Snmp_Variable *)p2; if(ptr1->lineno > ptr2->lineno) { back = 1; } else { if(ptr1->lineno < ptr2->lineno) { back = -1; } } } return back; } /** Configuration keywords. */ static char *snmp_config_keywords[] = { "te$xt", "ty$pe", NULL }; /** Variable types. */ static char *snmp_type_keywords[] = { "b$oolean", /* boolean */ /* 0 */ "ib$oolean", /* inverted boolean */ /* 1 */ "d$isplay", /* display string */ /* 2 */ NULL }; /** Add OIDs to inspect for snmpyalc request to container. @param a Application. @param st Container with OIDs to inspect. @param typename SNMP type name. @return 1 on success, 0 on error. */ static int fill_snmp_storage_from_stream DK_P4(dk_app_t *,app,dk_storage_t *,st,dk_stream_t *,cfgstream,char *,typename) { int err, found, cc, is_this_for_me, keyno, typeno; unsigned long lineno; char il[256], *ptrstart, *p1, *p2; Yalc_Snmp_Variable *ysv_cur; ymp_snmp_start_config_file(); found = err = is_this_for_me = 0; lineno = 0UL; cc = 1; ysv_cur = NULL; while(cc) { if(dkstream_gets(cfgstream,il,sizeof(il))) { lineno++; dkstr_delcomm(il, '#'); ptrstart = dkstr_start(il, NULL); if(ptrstart) { if(*ptrstart == '[') { ysv_cur = NULL; ptrstart++; dkstr_chomp(ptrstart, NULL); dkstr_delcomm(ptrstart, ']'); if(strcmp(typename,ptrstart) == 0) { is_this_for_me = found = 1; ymp_snmp_start_config_section(); } else { is_this_for_me = 0; ymp_snmp_end_config_section(); } } else { if(is_this_for_me) { if((il[0] == ' ') || (il[0] == '\t')) { if(ysv_cur) { dkstr_chomp(il, NULL); p1 = dkstr_chr(il, '='); if(p1) { *(p1++) = (char)0; p1 = dkstr_start(p1, NULL); if(p1) { p2 = dkstr_start(il, NULL); if(p2) { dkstr_chomp(p2, NULL); keyno = dkstr_array_abbr( snmp_config_keywords, p2, '$', 0 ); switch(keyno) { case 0: { char *pa, *pb; pb = dkstr_dup(p1); if(pb) { pa = ysv_cur->string_value; if(pa) { dk_delete(pa); ysv_cur->string_value = NULL; } ysv_cur->string_value = pb; } else { dkapp_err_memory(app,sizeof(char),(strlen(p1)+1)); cc = 0; err = 1; } } break; case 1: { typeno = dkstr_array_abbr( snmp_type_keywords, p1, '$', 0 ); if(typeno > -1) { ysv_cur->t = (typeno + 1); } else { yme_snmp_bad_type(p1,lineno); cc = 0; err = 1; } } break; default: { yme_snmp_bad_conf(p2, lineno); cc = 0; err = 1; } break; } } else { yme_snmp_missing_key(lineno); cc = 0; err = 1; } } else { yme_snmp_missing_val(lineno); cc = 0; err = 1; } } else { } } else { yme_snmp_no_var(lineno); cc = 0; err = 1; } } else { dkstr_chomp(ptrstart, NULL); ysv_cur = new_ysv(lineno,ptrstart); if(ysv_cur) { if(!dksto_add(st,(void *)ysv_cur)) { cc = 0; err = 1; dkapp_err_memory(app,sizeof(dk_storage_node_t),1); } } else { dkapp_err_memory(app,sizeof(Yalc_Snmp_Variable),1); cc = 0; err = 1; } } } } } } else { cc = 0; } } if(!found) { yme_snmp_type_not_found(typename); } if(err) { found = 0; } if(is_this_for_me) { ymp_snmp_end_config_section(); } ymp_snmp_end_config_file(); return found; } /** OID for device status. */ static char str_oid_hrDeviceStatus[] = { "1.3.6.1.2.1.25.3.2.1.5.1" }; /** OID for printer status. */ static char str_oid_hrPrinterStatus[] = { "1.3.6.1.2.1.25.3.5.1.1.1" }; /** Add OIDs to inspect for klpinfo request to container. @param a Application. @param st Container with OIDs to inspect. @param typename SNMP type name. @return 1 on success, 0 on error. */ static int fill_short_snmp_storage_from_stream DK_P3(dk_app_t *,app,dk_storage_t *,st,char *,typename) { int err, found, cc, is_this_for_me; /* int keyno, typeno; */ unsigned long lineno; /* char il[256], *ptrstart, *p1, *p2; */ Yalc_Snmp_Variable *ysv_cur; ymp_snmp_start_config_file(); found = err = is_this_for_me = 0; lineno = 0UL; cc = 1; ysv_cur = NULL; found = 1; ysv_cur = new_ysv(0, str_oid_hrDeviceStatus); if(ysv_cur) { if(dksto_add(st, (void *)ysv_cur)) { ysv_cur = new_ysv(0, str_oid_hrPrinterStatus); if(ysv_cur) { if(!dksto_add(st, (void *)ysv_cur)) { dkapp_err_memory(app,sizeof(dk_storage_node_t),1); cc = 0; err = 1; } else { } } else { dkapp_err_memory(app,sizeof(Yalc_Snmp_Variable),1); cc = 0; err = 1; } } else { dkapp_err_memory(app,sizeof(dk_storage_node_t),1); cc = 0; err = 1; } } else { dkapp_err_memory(app,sizeof(Yalc_Snmp_Variable),1); cc = 0; err = 1; } if(err) { found = 0; } if(is_this_for_me) { ymp_snmp_end_config_section(); } ymp_snmp_end_config_file(); return found; } /** SNMP versions. */ static char *snmp_versions[] = { "1", "2", "2c", "2p", "3", NULL }; /** Show a parsed OID. @param a Application. @param oidtext Text representation of OID. @param oidptr OID elements array. @param sz Number of elements used in \a oidptr. */ static void show_parsed_oid DK_P4(dk_app_t *,a,char *,oidtext,oid *,oidptr,size_t,sz) { size_t i; char outbuffer[13*MAX_OID_LEN]; char buffer[13]; char *msg[3]; if(sz <= MAX_OID_LEN) { for(i = 0; i < sz; i++) { sprintf(buffer, "%ld", (long)(oidptr[i])); if(i == 0) { strcpy(outbuffer, buffer); } else { strcat(outbuffer, str_dot); strcat(outbuffer, buffer); msg[0] = oidtext; msg[1] = str_equal; msg[2] = outbuffer; } } dkapp_log_msg(a, DK_LOG_LEVEL_DEBUG, msg, 3); } } /** Default SNMP log file. */ static char default_snmp_log_file_name[] = { "snmp.log" }; /** Preference key: SNMP log file name. */ static char pk_snmp_log_file_name[] = { "/log/snmp/file/name" }; /** Preference key: Keep SNMP log file when exiting. */ static char pk_snmp_log_file_keep[] = { "/log/snmp/file/keep" }; /** Find log file name for SNMP logging. @param rq YALC request. @param app Application. @param buffer Result buffer. @param sz Size of \a buffer. @return 1 on success, 0 on error. */ static int find_snmp_log_file_name DK_P4(yalc_rq_t *,rq, dk_app_t *, app, char *,buffer, size_t,sz) { int back = 0; char line[512], *p1; if(app && buffer && sz) { if(dkapp_get_pref(app, pk_snmp_log_file_keep, line, sizeof(line), 0)) { p1 = dkstr_start(line, NULL); if(p1) { dkstr_chomp(p1, NULL); if(dkstr_is_bool(p1)) { if(dkstr_is_on(p1)) { (rq->args).snmp.keep_logfile = 1; } } } } if(dkapp_get_pref(app, pk_snmp_log_file_name, line, sizeof(line), 0)) { if(dkapp_transform_string_ext1(app,buffer,sz,line,1)) { back = 1; } } else { if(dkapp_tmpnam(app, line, sizeof(line))) { if(dkapp_transform_string_ext1(app,buffer,sz,line,1)) { if((strlen(buffer)+strlen(default_snmp_log_file_name)+strlen(fnsep)) < sz) { strcat(buffer, fnsep); strcat(buffer, default_snmp_log_file_name); } } } } } if(back) { dksf_correct_fnsep(buffer); } return back; } /** Parse OID using either netsnmp or ucdsnmp functions. @param ysvptr YALC SNMP variable. @param oid_text Text representation of OID. @param oid_ptr OID buffer. @param oid_len Size of \a oid_ptr in elements. @return 1 on success, 0 on error. */ static int my_read_objid DK_P4(\ Yalc_Snmp_Variable *,ysv_ptr, char *,oid_text,\ oid *,oid_ptr, size_t *,oid_len\ ) { int back = 0; #if DK_HAVE_LIBNETSNMP if(snmp_parse_oid(oid_text, oid_ptr, oid_len)) { #line 721 "yalc.ctr" #line 723 "yalc.ctr" #line 724 "yalc.ctr" #line 725 "yalc.ctr" #line 726 "yalc.ctr" #line 727 "yalc.ctr" #line 728 "yalc.ctr" #line 729 "yalc.ctr" #line 730 "yalc.ctr" back = 1; } #else if(read_objid(oid_text, oid_ptr, oid_len)) { back = 1; } #endif return back; } /** Run snmpyalc request. @param rq YALC request. @param h SNMP host. @param c SNMP community. @param t ???. @param cfg Configuration data stream. @param snmpvers SNMP version. @return 1 on success, 0 on error. */ static int run_snmp_request DK_P6(yalc_rq_t *,rq,char *,h,char *,c,char *,t,dk_stream_t *,cfg,char *,snmpvers) { int back = 0; dk_storage_t *st; dk_storage_iterator_t *stit; Yalc_Snmp_Variable *ysv_ptr; #if DK_HAVE_LIBNETSNMP netsnmp_session session, *ss; netsnmp_pdu *request_pdu, *response_pdu; netsnmp_variable_list *vars; #else struct snmp_session session, *ss; struct snmp_pdu *request_pdu, *response_pdu; struct variable_list *vars; #endif #if DK_HAVE_NETSNMP_ENABLE_FILELOG char lfnbuffer[512], *lfnptr = NULL; #endif oid *oid_ptr; size_t oid_len; int must_continue, status, cc, sv; char *pa, *pb, *myprgname; st = dksto_open(0); if(st) { stit = dksto_it_open(st); if(stit) { #if DK_HAVE_NETSNMP_ENABLE_FILELOG netsnmp_log_handler *logh = NULL; #endif dksto_set_comp(st,compare_ysv,0); myprgname = dkapp_get_appname(rq->app); if(!myprgname) { myprgname = default_appname; } #if DK_HAVE_NETSNMP_ENABLE_FILELOG logh = netsnmp_register_loghandler( NETSNMP_LOGHANDLER_FILE, 5 ); if(logh) { lfnptr = default_snmp_log_file_name; if(rq->app) { if(find_snmp_log_file_name(rq, rq->app, lfnbuffer, sizeof(lfnbuffer))) { lfnptr = lfnbuffer; } } logh->pri_max = 5; logh->token = strdup(lfnptr); if(logh->token) { netsnmp_enable_filelog(logh, 0); } } #endif init_snmp(myprgname); if(fill_snmp_storage_from_stream(rq->app,st,cfg,t)) { response_pdu = NULL; snmp_sess_init(&session); session.peername = h; session.version = SNMP_VERSION_1; sv = -1; if(snmpvers) { sv = dkstr_array_index(snmp_versions, snmpvers, 0); } switch(sv) { case 0: { session.version = SNMP_VERSION_1; } break; case 1: { session.version = SNMP_VERSION_2c; } break; case 2: { session.version = SNMP_VERSION_2c; } break; case 3: { session.version = SNMP_VERSION_2p; } break; case 4: { session.version = SNMP_VERSION_3; } break; default: { session.version = SNMP_VERSION_1; } break; } session.community = (unsigned char *)c; session.community_len = strlen(c); ss = snmp_open(&session); if(ss) { must_continue = 1; dksto_it_reset(stit); while(must_continue) { must_continue = 0; response_pdu = NULL; ysv_ptr = (Yalc_Snmp_Variable *)dksto_it_next(stit); if(ysv_ptr) { request_pdu = snmp_pdu_create(SNMP_MSG_GET); if(request_pdu) { oid_ptr = &(ysv_ptr->oid[0]); oid_len = MAX_OID_LEN; ysv_ptr->oid_len = 0; if(my_read_objid(ysv_ptr, ysv_ptr->oid_text, oid_ptr, &oid_len)) { if(rq->app) { if(dkapp_get_min_loglevel(rq->app) >= DK_LOG_LEVEL_DEBUG) { show_parsed_oid( rq->app, ysv_ptr->oid_text, oid_ptr, oid_len ); } } ysv_ptr->oid_len = oid_len; if(snmp_add_null_var(request_pdu, oid_ptr, oid_len)) { ymp_snmp_start_request(); status = snmp_synch_response(ss,request_pdu,&response_pdu); ymp_snmp_end_request(); if(status == STAT_SUCCESS) { if(response_pdu->errstat == SNMP_ERR_NOERROR) { for(vars=response_pdu->variables; vars; vars=vars->next_variable) { if(oids_equal(vars->name,vars->name_length,ysv_ptr->oid,ysv_ptr->oid_len)) { back = 1; switch((int)(vars->type)) { case ((int)(ASN_OCTET_STR)) : { switch(ysv_ptr->t) { case 1: case 2: { size_t lgt; pb = ysv_ptr->string_value; for(lgt = 0; lgt < vars->val_len; lgt++) { if(*pb != ' ') { if(*pb != '\t') { if(*pb != '\r') { if(*pb != '\n') { if(*pb) { ysv_ptr->long_value = 1L; ysv_ptr->found = 1; } } } } } pb++; } } break; case 3: { size_t lgt; lgt = vars->val_len + 1; pa = dk_new(char,lgt); if(pa) { pb = ysv_ptr->string_value; if(pb) { dk_delete(pb); } lgt--; strncpy(pa, (char *)((vars->val).string), lgt); pa[lgt] = (char)0; ysv_ptr->string_value = pa; ysv_ptr->found = 1; pb = pa; while(*pb) { if((*pb == '\r') || (*pb == '\n')) { *pb = ' '; } pb++; } } else { back = 0; dkapp_err_memory(rq->app,sizeof(char),lgt); } } break; } } break; case ((int)(ASN_INTEGER)): case ((int)(ASN_COUNTER)): case ((int)(ASN_GAUGE)): case ((int)(ASN_TIMETICKS)): { switch(ysv_ptr->t) { case 1: case 2: { ysv_ptr->long_value = *((vars->val).integer); ysv_ptr->found = 1; } break; case 3: { char buffer[16]; ysv_ptr->long_value = *((vars->val).integer); sprintf(buffer, "%ld", ysv_ptr->long_value); pa = dkstr_dup(buffer); if(pa) { pb = ysv_ptr->string_value; if(pb) { dk_delete(pb); } ysv_ptr->string_value = pa; ysv_ptr->found = 1; } else { back = 0; if(rq->app) { dkapp_err_memory(rq->app, sizeof(char), (1+strlen(buffer))); } } } break; } } break; } if(ysv_ptr->found) { switch(ysv_ptr->t) { case 1: { if(ysv_ptr->long_value) { if(ysv_ptr->string_value) { printf("%s\n", ysv_ptr->string_value); cc = 0; (rq->args).snmp.output_found = 1; } else { if(ysv_ptr->oid_text) { printf("%s\n", ysv_ptr->oid_text); cc = 0; (rq->args).snmp.output_found = 1; } } } } break; case 2: { if(!(ysv_ptr->long_value)) { if(ysv_ptr->string_value) { printf("%s\n", ysv_ptr->string_value); cc = 0; (rq->args).snmp.output_found = 1; } else { if(ysv_ptr->oid_text) { printf("%s\n", ysv_ptr->oid_text); cc = 0; (rq->args).snmp.output_found = 1; } } } } break; case 3: { if(ysv_ptr->string_value) { char c, *myptr; myptr = ysv_ptr->string_value; while(*myptr) { c = *myptr; if(isascii(c) && isprint(c)) { fputc(c, stdout); } else { printf("0x%02X", (((int)c) & 0xFF)); } myptr++; } fputc('\n', stdout); cc = 0; (rq->args).snmp.output_found = 1; } else { if(ysv_ptr->oid_text) { printf("%s\n", ysv_ptr->oid_text); cc = 0; (rq->args).snmp.output_found = 1; } } } break; } } else { must_continue = 1; } } } } else { must_continue = 1; /* attempt next oid */ } } else { yme_snmp_no_response(); printf("<<< UNREACHABLE >>>\n"); (rq->args).snmp.output_found = 1; } if(response_pdu) { snmp_free_pdu(response_pdu); response_pdu = NULL; } } else { back = 0; yme_snmp_request_pdu(); } } else { back = 0; yme_snmp_bad_oid_string(ysv_ptr->oid_text); } #ifndef DO_NOT_FREE_REQUEST_PDU snmp_free_pdu(request_pdu); #endif } else { /* Failed to create request PDU */ yme_err_snmp_request_pdu(); } } else { /* No more OIDs to check */ } } snmp_close(ss); } else { if((rq->args).snmp.force_output) { printf("<<< SNMP-ERROR: No session >>>\n"); (rq->args).snmp.output_found = 1; } yme_snmp_failed_to_open_session(); } } else { } /* cleanup */ dksto_it_reset(stit); while((ysv_ptr = (Yalc_Snmp_Variable *)dksto_it_next(stit)) != NULL) { #line 1064 "yalc.ctr" #line 1070 "yalc.ctr" #line 1072 "yalc.ctr" #line 1073 "yalc.ctr" delete_ysv(ysv_ptr); } #if DK_HAVE_NETSNMP_ENABLE_FILELOG if(logh) { snmp_disable_filelog(); if(logh->token) { free((void *)(logh->token)); logh->token = NULL; } netsnmp_remove_loghandler(logh); #if TAKE_RISK_OF_DOUBLE_FREE free(logh); #endif } #endif dksto_it_close(stit); stit = NULL; #if DK_HAVE_NETSNMP_ENABLE_FILELOG if(lfnptr) { if(!((rq->args).snmp.keep_logfile)) { dksf_remove_file(lfnptr); lfnptr = NULL; } } #endif } else { dkapp_err_memory(rq->app,sizeof(dk_storage_iterator_t),1); } dksto_close(st); st = NULL; } else { dkapp_err_memory(rq->app,sizeof(dk_storage_t),1); } return back; } /** Receive SNMP int response. @param rpdu Response PDU. @param str_oid OID to find. @param dv Default value. @return Value from response PDU or default value. */ #if DK_HAVE_LIB_NETSNMP int get_snmp_response_int_value DK_P3(netsnmp_pdu *,rpdu, char *,str_oid, int,dv) #else int get_snmp_response_int_value DK_P3(struct snmp_pdu *,rpdu, char *,str_oid, int,dv) #endif { int back; oid oid[MAX_OID_LEN], *oid_ptr; size_t oid_len; char buffer[256]; #if DK_HAVE_LIBNETSNMP netsnmp_variable_list *vars; #else struct variable_list *vars; #endif back = dv; oid_ptr = oid; oid_len = MAX_OID_LEN; #if DK_HAVE_LIBNETSNMP if(snmp_parse_oid(str_oid, oid_ptr, &oid_len)) { #else if(read_objid(str_oid, oid_ptr, &oid_len)) { #endif for(vars = rpdu->variables; vars; vars = vars->next_variable) { if(oids_equal(vars->name, vars->name_length, oid, oid_len)) { switch((int)(vars->type)) { case ((int)(ASN_OCTET_STR)): { if(vars->val_len < sizeof(buffer)) { int i; for(i=0; i < sizeof(buffer); i++) { buffer[i] = ' '; } i = vars->val_len; if(i > (sizeof(buffer)-1)) i = sizeof(buffer) - 1; strncpy(buffer, (char *)((vars->val).string), i); buffer[i] = '\0'; if(sscanf(buffer, "%d", &i) == 1) { back = i; } } } break; case ((int)(ASN_TIMETICKS)): case ((int)(ASN_GAUGE)): case ((int)(ASN_COUNTER)): case ((int)(ASN_INTEGER)): { back = *(vars->val).integer; } break; } } } } return back; } /** Device status texts. */ static char *device_status_msg[] = { "", "unknown", "running", "warning", "testing", "down" }; /** Printer status texts. */ static char *printer_status_msg[] = { "", "other", "unknown", "idle", "printing", "warmup" }; /** Run klpinfo request. @param rq YALC request. @param h SNMP host. @param c SNMP community. @param t ??? @param snmpvers SNMP version. @return 1 on success, 0 on error. */ static int run_snmp_short_request DK_P5(yalc_rq_t *,rq,char *,h,char *,c,char *,t,char *,snmpvers) { int back = 0; dk_storage_t *st; dk_storage_iterator_t *stit; Yalc_Snmp_Variable *ysv_ptr; #if DK_HAVE_LIBNETSNMP netsnmp_session session, *ss; netsnmp_pdu *request_pdu, *response_pdu; #else struct snmp_session session, *ss; struct snmp_pdu *request_pdu, *response_pdu; #endif #if DK_HAVE_NETSNMP_ENABLE_FILELOG char lfnbuffer[512], *lfnptr = NULL; #endif oid *oid_ptr; size_t oid_len; int status, is_first, sv; /* int cc ; */ char *myprgname; /* char *pa, *pb, *myprgname; */ int hrDeviceStatus, hrPrinterStatus, summaryStatus; hrDeviceStatus = 1; hrPrinterStatus = 2; summaryStatus = PRINTER_STATE_UNKNOWN; st = dksto_open(0); if(st) { stit = dksto_it_open(st); if(stit) { #if DK_HAVE_NETSNMP_ENABLE_FILELOG netsnmp_log_handler *logh = NULL; #endif dksto_set_comp(st,compare_ysv,0); myprgname = dkapp_get_appname(rq->app); if(!myprgname) { myprgname = default_appname; } #if DK_HAVE_NETSNMP_ENABLE_FILELOG logh = netsnmp_register_loghandler( NETSNMP_LOGHANDLER_FILE, 5 ); if(logh) { lfnptr = default_snmp_log_file_name; if(rq->app) { if(find_snmp_log_file_name(rq, rq->app, lfnbuffer, sizeof(lfnbuffer))) { lfnptr = lfnbuffer; } } logh->pri_max = 5; logh->token = strdup(lfnptr); if(logh->token) { netsnmp_enable_filelog(logh, 0); } } #endif init_snmp(myprgname); if(fill_short_snmp_storage_from_stream(rq->app,st,t)) { response_pdu = NULL; snmp_sess_init(&session); session.peername = h; session.version = SNMP_VERSION_1; sv = -1; if(snmpvers) { sv = dkstr_array_index(snmp_versions, snmpvers, 0); } switch(sv) { case 0: { session.version = SNMP_VERSION_1; } break; case 1: { session.version = SNMP_VERSION_2c; } break; case 2: { session.version = SNMP_VERSION_2c; } break; case 3: { session.version = SNMP_VERSION_2p; } break; case 4: { session.version = SNMP_VERSION_3; } break; default: { session.version = SNMP_VERSION_1; } break; } session.community = (unsigned char *)c; session.community_len = strlen(c); ss = snmp_open(&session); if(ss) { request_pdu = snmp_pdu_create(SNMP_MSG_GET); if(request_pdu) { is_first = 1; dksto_it_reset(stit); while((ysv_ptr = (Yalc_Snmp_Variable *)dksto_it_next(stit)) != NULL) { if(is_first) { back = 1; is_first = 0; } oid_ptr = &(ysv_ptr->oid[0]); oid_len = MAX_OID_LEN; ysv_ptr->oid_len = 0; #if DK_HAVE_LIBNETSNMP if(snmp_parse_oid(ysv_ptr->oid_text, oid_ptr, &oid_len)) { #line 1291 "yalc.ctr" #line 1293 "yalc.ctr" #line 1294 "yalc.ctr" #line 1295 "yalc.ctr" #line 1296 "yalc.ctr" #line 1297 "yalc.ctr" #line 1298 "yalc.ctr" #else if(read_objid(ysv_ptr->oid_text, oid_ptr, &oid_len)) { #endif if(rq->app) { if(dkapp_get_min_loglevel(rq->app) >= DK_LOG_LEVEL_DEBUG) { show_parsed_oid( rq->app, ysv_ptr->oid_text, oid_ptr, oid_len ); } } ysv_ptr->oid_len = oid_len; if(snmp_add_null_var(request_pdu, oid_ptr, oid_len)) { } else { back = 0; yme_snmp_request_pdu(); } } else { back = 0; yme_snmp_bad_oid_string(ysv_ptr->oid_text); } } if(back) { ymp_snmp_start_request(); status = snmp_synch_response(ss,request_pdu,&response_pdu); ymp_snmp_end_request(); if(status == STAT_SUCCESS) { if(response_pdu->errstat == SNMP_ERR_NOERROR) { hrPrinterStatus = get_snmp_response_int_value( response_pdu, str_oid_hrPrinterStatus, 2 ); hrDeviceStatus = get_snmp_response_int_value( response_pdu, str_oid_hrDeviceStatus, 1 ); if(hrPrinterStatus == 5) { summaryStatus = PRINTER_STATE_WARMUP; } else { if(hrDeviceStatus == 5) { summaryStatus = PRINTER_STATE_OFFLINE; } else { if((hrDeviceStatus == 2) || (hrDeviceStatus == 3)) { switch(hrPrinterStatus) { case 1: { summaryStatus = PRINTER_STATE_STANDBY; } break; case 3: { if(hrDeviceStatus == 2) { summaryStatus = PRINTER_STATE_NORMAL; } else { summaryStatus = PRINTER_STATE_WARNING; } } break; case 4: { summaryStatus = PRINTER_STATE_BUSY; } break; } } else { if(hrDeviceStatus == 4) { summaryStatus = PRINTER_STATE_TESTING; } } } } if(summaryStatus > PRINTER_STATE_TESTING) { summaryStatus = PRINTER_STATE_TESTING; } fputs(printer_state_msg[summaryStatus], stdout); if((rq->args).snmp.run_verbose) { fputs(" ", stdout); fprintf(stdout, "device status = %d (", hrDeviceStatus); if(hrDeviceStatus > 5) hrDeviceStatus = 1; if(hrDeviceStatus < 1) hrDeviceStatus = 1; fputs(device_status_msg[hrDeviceStatus], stdout); fprintf(stdout, ") printer status = %d (", hrPrinterStatus); if(hrPrinterStatus < 1) hrPrinterStatus = 1; if(hrPrinterStatus > 5) hrPrinterStatus = 2; fputs(printer_status_msg[hrPrinterStatus], stdout); fputs(")", stdout); } fputc('\n', stdout); } else { /* response_pdu->errstat == SNMP_ERR_NOERROR */ if((rq->args).snmp.force_output) { printf("<<< SNMP-ERROR: Bad response >>>\n"); (rq->args).snmp.output_found = 1; } yme_snmp_response_packet(); } /* response_pdu->errstat == SNMP_ERR_NOERROR */ } else { /* status == STAT_SUCCESS */ yme_snmp_no_response(); printf("<<< UNREACHABLE >>>\n"); (rq->args).snmp.output_found = 1; } /* status == STAT_SUCCESS */ if(response_pdu) { snmp_free_pdu(response_pdu); } } #ifndef DO_NOT_FREE_REQUEST_PDU snmp_free_pdu(request_pdu); #endif } snmp_close(ss); } else { if((rq->args).snmp.force_output) { printf("<<< SNMP-ERROR: No session >>>\n"); (rq->args).snmp.output_found = 1; } yme_snmp_failed_to_open_session(); } } /* cleanup */ dksto_it_reset(stit); while((ysv_ptr = (Yalc_Snmp_Variable *)dksto_it_next(stit)) != NULL) { #line 1422 "yalc.ctr" #line 1428 "yalc.ctr" #line 1430 "yalc.ctr" #line 1431 "yalc.ctr" delete_ysv(ysv_ptr); } #if DK_HAVE_NETSNMP_ENABLE_FILELOG if(logh) { snmp_disable_filelog(); if(logh->token) { free((void *)(logh->token)); logh->token = NULL; } netsnmp_remove_loghandler(logh); #if TAKE_RISK_OF_DOUBLE_FREE free(logh); #endif } #endif dksto_it_close(stit); stit = NULL; #if DK_HAVE_NETSNMP_ENABLE_FILELOG if(lfnptr) { if(!((rq->args).snmp.keep_logfile)) { dksf_remove_file(lfnptr); lfnptr = NULL; } } #endif } else { dkapp_err_memory(rq->app,sizeof(dk_storage_iterator_t),1); } dksto_close(st); st = NULL; } else { dkapp_err_memory(rq->app,sizeof(dk_storage_t),1); } return back; } #else /** Run snmpyalc request. @param rq YALC request. @param h SNMP host. @param c SNMP community. @param t ??? @param snmpvers SNMP version. @return 1 on success, 0 on error. */ static int run_snmp_request DK_P6(yalc_rq_t *,rq,char *,h,char *,c,char *,t,dk_stream_t *,cfg,char *,snmpvers) { return 0; } /** Run klpinfo request. @param rq YALC request. @param h SNMP host. @param c SNMP community. @param t ??? @param snmpvers SNMP version. @return 1 on success, 0 on error. */ static int run_snmp_short_request DK_P5(yalc_rq_t *,rq,char *,h,char *,c,char *,t,char *,snmpvers) { return 0; } #endif /** File name for configuratin file. */ static char configfile[] = { "/yanolc.cfg" }; /** File name for SNMP configuration file. */ static char snmpcfgfile[] = { "/snmpyalc.cfg" }; /** Check whether a file is available. @param fn File name. @return 1 if file is available, 0 if not. */ static int have_file DK_P1(char *,fn) { int back = 0; dk_stat_t *stptr; int ft; stptr = dkstat_open(fn); if(stptr) { ft = dkstat_filetype(stptr); if((ft & (~(DK_FT_SYMLINK))) == DK_FT_REG) { back = 1; } dkstat_close(stptr); } return back; } /** Retrieve a setting from registry key. @param rq YALC request. @param how Information sources (2=user, 1=system). @param key Entry name. @param buf Result buffer. @param sz Size of \a buffer. @return 1 on success, 0 on error. */ static int regkey_retrieve DK_P5(yalc_rq_t *, rq, int, how, char *, key, char *, buf, size_t, sz) { int back = 0; #if DK_HAVE_WINREG_H LONG retval; DWORD dwType, used_sz; used_sz = sz; if((how & 2) && (((rq->reg).what) & 2)) { retval = RegQueryValueExA( (rq->reg).hkcu, key, NULL, &dwType, buf, &used_sz ); if(retval == ERROR_SUCCESS) { if(dwType == REG_SZ) { if(used_sz <= sz) { if(used_sz == ((DWORD)sz)) { used_sz--; } buf[used_sz] = '\0'; back = 1; } } } } if(!back) { if((how & 1) && (((rq->reg).what) & 1)) { used_sz = sz; retval = RegQueryValueExA( (rq->reg).hklm, key, NULL, &dwType, buf, &used_sz ); if(retval == ERROR_SUCCESS) { if(dwType == REG_SZ) { if(used_sz <= sz) { if(used_sz == ((DWORD)sz)) { used_sz--; } buf[used_sz] = '\0'; back = 1; } } } } } #endif return back; } /** YANOLC alias information. */ typedef struct { char *name; /**< Alias name. */ char *value; /**< Target queue. */ } yalc_alias_info; /** Destroy alias information, release memory. @param yai Alias information to destroy. */ static void yai_remove DK_P1(yalc_alias_info *, yai) { char *x; if(yai) { x = yai->name; if(x) { dk_delete(x); } yai->name = NULL; x = yai->value; if(x) { dk_delete(x); } yai->value = NULL; dk_delete(yai); } } /** Create new alias information. @param name Alias name. @param value Alias value. @return Pointer to new alias information on success, NULL on error. */ static yalc_alias_info * yai_new DK_P2(char *, name, char *, value) { char *n, *v; yalc_alias_info *back = NULL; if(name && value) { back = dk_new(yalc_alias_info,1); if(back) { back->name = NULL; back->value = NULL; n = dkstr_dup(name); v = dkstr_dup(value); if(n && v) { back->name = n; back->value = v; } else { if(n) { dk_delete(n); } if(v) { dk_delete(v); } dk_delete(back); back = NULL; } } } return back; } /** YANOLC host information. */ typedef struct { char *name; /**< Host. */ int type; /**< Host type: 0=unknown, 1=LPRNG, 2=BSD, 3=raw, 4=jetdirect */ unsigned short portno; /**< Port number on host. */ unsigned short o_min; /**< Minimum local port. */ unsigned short o_max; /**< Maximum local port. */ char *xusers; /**< List of users allowed to change username */ int have_timeouts; /**< Which timeouts are defined. */ double lpr_timeout; /**< Timeout for LPR. */ double lpq_timeout; /**< Timeout for LPQ. */ double lprm_timeout; /**< Timeout for LPRM. */ double lpc_timeout; /**< Timeout for LPC. */ int data_file_first; /**< Data file first: 0=unknown, 1=control, 2=data. */ char *snmp_target; /**< Target for SNMP operations. */ } yalc_host_info; /** Create new host information. @param name Host name. @return Pointer to new host information on success, NULL on error. */ static yalc_host_info * yhi_new DK_P1(char *, name) { yalc_host_info *back = NULL; if(name) { back = dk_new(yalc_host_info,1); if(back) { back->name = NULL; back->type = 0; back->snmp_target = NULL; back->portno = back->o_min = back->o_max = 0; back->xusers = NULL; back->have_timeouts = 0; back->lpr_timeout = back->lpq_timeout = back->lprm_timeout = back->lpc_timeout = 0.0; back->name = dkstr_dup(name); if(!(back->name)) { dk_delete(back); back = NULL; } } } return back; } /** Destroy host information, release memory. @param yhi Host information. */ static void yhi_remove DK_P1(yalc_host_info *, yhi) { char *x; if(yhi) { x = yhi->name; if(x) { dk_delete(x); } yhi->name = NULL; yhi->type = 0; yhi->portno = yhi->o_min = yhi->o_max = 0; x = yhi->xusers; if(x) { dk_delete(x); } yhi->xusers = NULL; yhi->have_timeouts = 0; yhi->lpr_timeout = yhi->lpq_timeout = yhi->lprm_timeout = yhi->lpc_timeout = 0.0; x = yhi->snmp_target; if(x) { dk_delete(x); } yhi->snmp_target = NULL; dk_delete(yhi); } } /** YANOLC device information. */ typedef struct { char *name; /**< Device name, queue\@host or host%port. */ yalc_host_info i; /**< Options here overwrite host options. */ yalc_host_info *ip; /**< Host settings. */ } yalc_device_info; /** Create new device information. @param name Device name. @return Pointer to new device information on success, NULL on error. */ static yalc_device_info * ydi_new DK_P1(char *, name) { yalc_device_info *back = NULL; if(name) { back = dk_new(yalc_device_info,1); if(back) { back->name = NULL; (back->i).name = NULL; (back->i).type = 0; (back->i).portno = (back->i).o_min = (back->i).o_max = 0; (back->i).xusers = NULL; (back->i).have_timeouts = 0; (back->i).lpr_timeout = (back->i).lpq_timeout = (back->i).lprm_timeout = (back->i).lpc_timeout = 0.0; back->ip = NULL; back->name = dkstr_dup(name); if(!(back->name)) { dk_delete(back); back = NULL; } } } return back; } /** Destroy one device information, release memory. @param ydi Device information. */ static void ydi_remove DK_P1(yalc_device_info *, ydi) { char *x; if(ydi) { x = ydi->name; if(x) { dk_delete(x); } ydi->name = NULL; ydi->ip = NULL; (ydi->i).name = NULL; (ydi->i).type = 0; (ydi->i).portno = (ydi->i).o_min = (ydi->i).o_max = 0; x = (ydi->i).xusers; if(x) { dk_delete(x); } (ydi->i).xusers = NULL; (ydi->i).have_timeouts = 0; (ydi->i).lpq_timeout = (ydi->i).lpq_timeout = (ydi->i).lprm_timeout = (ydi->i).lpc_timeout = 0.0; dk_delete(ydi); } } /** YANOLC configuration. */ typedef struct { /* aliases */ dk_storage_t *a; /**< Aliases container. */ dk_storage_iterator_t *ai; /**< Aliases iterator. */ /* hosts */ dk_storage_t *h; /**< Hosts container. */ dk_storage_iterator_t *hi; /**< Hosts iterator. */ /* print queues */ dk_storage_t *p; /**< Queues container. */ dk_storage_iterator_t *pi; /**< Queues iterator. */ yalc_alias_info *first_alias; /**< First alias found. */ yalc_device_info *first_device; /**< First device found. */ yalc_host_info *first_host; /**< First host found. */ } yalc_cfg; /** Destroy configuration, release memory. @param cfg YANOLC configuration. */ static void forget_cfg DK_P1(yalc_cfg *, cfg) { yalc_alias_info *yai; yalc_host_info *yhi; yalc_device_info *ydi; if(cfg) { if(cfg->first_alias) { cfg->first_alias = NULL; } if(cfg->first_device) { cfg->first_device = NULL; } if(cfg->first_host) { cfg->first_host = NULL; } if(cfg->ai) { dksto_it_reset(cfg->ai); while((yai = (yalc_alias_info *)dksto_it_next(cfg->ai))) { yai_remove(yai); } } if(cfg->hi) { dksto_it_reset(cfg->hi); while((yhi = (yalc_host_info *)dksto_it_next(cfg->hi))) { yhi_remove(yhi); } } if(cfg->pi) { dksto_it_reset(cfg->pi); while((ydi = (yalc_device_info *)dksto_it_next(cfg->pi))) { ydi_remove(ydi); } } if(cfg->pi) { dksto_it_close(cfg->pi); } cfg->pi = NULL; if(cfg->hi) { dksto_it_close(cfg->hi); } cfg->hi = NULL; if(cfg->ai) { dksto_it_close(cfg->ai); } cfg->ai = NULL; if(cfg->p) { dksto_close(cfg->p); } cfg->p = NULL; if(cfg->h) { dksto_close(cfg->h); } cfg->h = NULL; if(cfg->a) { dksto_close(cfg->a); } cfg->a = NULL; dk_delete(cfg); } } /** Compare two alias informations by name. @param p1 Left alias information. @param p2 Right alias information or name. @param how Comparison criteria (1=alias/name, others=alias/alias). @return Comparison result. */ static int compare_yalc_alias_info DK_P3(void *, p1, void *, p2, int, how) { int back = 0; yalc_alias_info *i1, *i2; char *n; if(p1 && p2) { i1 = (yalc_alias_info *)p1; switch(how) { case 1: { n = (char *)p2; if(i1->name) { back = strcmp(i1->name, n); } } break; default : { i2 = (yalc_alias_info *)p2; if((i1->name) && (i2->name)) { back = strcmp(i1->name, i2->name); } } break; } } return back; } /** Compare two host informations by name. @param p1 Left host information. @param p2 Right host information or name. @param how Comparison criteria (1=information/name, others=information/information). @return Comparison result. */ static int compare_yalc_host_info DK_P3(void *, p1, void *, p2, int, how) { int back = 0; yalc_host_info *i1, *i2; char *n; if(p1 && p2) { switch(how) { case 1: { i1 = (yalc_host_info *)p1; n = (char *)p2; if(i1->name) { back = strcmp(i1->name,n); } } break; default: { i1 = (yalc_host_info *)p1; i2 = (yalc_host_info *)p2; if((i1->name) && (i2->name)) { back = strcmp(i1->name, i2->name); } } break; } } return back; } /** Compare two device informations. @param p1 Left device information. @param p2 Right device information. @param how Comparison criteria (1=device/name, others=device/device by name). @return Comparison result. */ static int compare_yalc_device_info DK_P3(void *, p1, void *, p2, int, how) { int back = 0; yalc_device_info *d1, *d2; char *n; if(p1 && p2) { d1 = (yalc_device_info *)p1; switch(how) { case 1: { n = (char *)p2; if(d1->name) { back = strcmp(d1->name, n); } } break; default : { d2 = (yalc_device_info *)p2; if((d1->name) && (d2->name)) { back = strcmp(d1->name, d2->name); } } break; } } return back; } /** Create a new (empty) YANOLC configuration. @return Pointer to new configuration on success, NULL on error. */ static yalc_cfg * yalc_cfg_new DK_P0() { yalc_cfg *back = NULL; back = dk_new(yalc_cfg,1); if(back) { back->first_host = NULL; back->first_alias = NULL; back->first_device = NULL; back->a = back->h = back->p = NULL; back->ai = back->hi = back->pi = NULL; back->a = dksto_open(0); back->h = dksto_open(0); back->p = dksto_open(0); if(back->a) back->ai = dksto_it_open(back->a); if(back->h) back->hi = dksto_it_open(back->h); if(back->p) back->pi = dksto_it_open(back->p); if(!((back->a) && (back->h) && (back->p) && (back->ai) && (back->hi) && (back->pi))) { forget_cfg(back); back = NULL; } else { dksto_set_comp(back->a, compare_yalc_alias_info, 0); dksto_set_comp(back->h, compare_yalc_host_info, 0); dksto_set_comp(back->p, compare_yalc_device_info, 0); } } return back; } /** Configuration keywords. */ static char *cfg_keywords[] = { /* 0 */ "type", /* 1 */ "port", /* 2 */ "originate", /* 3 */ "xusers", /* 4 */ "timeout.lpr", /* 5 */ "timeout.lpq", /* 6 */ "timeout.lprm", /* 7 */ "timeout.lpc", /* 8 */ "data-file-first", /* 9 */ "snmp", NULL }; /** Print server types. */ static char *pstype_keywords[] = { /* 0 */ "lprng", /* 1 */ "bsd", /* 2 */ "raw", /* 3 */ "jetdirect", NULL }; /** Set double variable from string. @param res Pointer to result variable. @param s Text containing the value. @return 1 on success, 0 on error. */ static int set_double DK_P2(double *,res,char *,s) { int back = 0; double to; if(sscanf(s,"%lf", &to) == 1) { *res = to; back = 1; } return back; } /** Add YANOLC host information. @param rq YALC request. @param yhi Yanolc host information. @param ptr Key. @param vptr Value. */ static void add_yhi_entry DK_P4(yalc_rq_t *,rq,yalc_host_info *,yhi,char *,ptr,char *,vptr) { unsigned x1, x2; char *xptr, *pa, *pb; switch(dkstr_array_index(cfg_keywords, ptr, 0)) { case 0: { if(vptr) { yhi->type = dkstr_array_index(pstype_keywords, vptr, 0) + 1; switch(yhi->type) { case YALC_METHOD_BSD: case YALC_METHOD_LPRNG: { if(yhi->portno == 0) { yhi->portno = 515; } } break; } } } break; case 1: { if(sscanf(vptr, "%u", &x1) == 1) { yhi->portno = x1; } } break; case 2: { xptr = dkstr_chr(vptr, '-'); if(xptr) { *xptr = ' '; if(sscanf(vptr, "%u %u", &x1, &x2) == 2) { yhi->o_min = x1; yhi->o_max = x2; } } else { if(sscanf(vptr, "%u", &x1) == 1) { yhi->o_min = yhi->o_max = x1; } } } break; case 3: { if(yhi->xusers) { xptr = yhi->xusers; dk_delete(xptr); yhi->xusers = NULL; } yhi->xusers = dkstr_dup(vptr); if(!(yhi->xusers)) { rq->read_cfg_res = 0; } } break; case 4: { if(set_double(&(yhi->lpr_timeout), vptr)) { yhi->have_timeouts |= 1; } else { yhi->have_timeouts &= (~(1)); } } break; case 5: { if(set_double(&(yhi->lpq_timeout), vptr)) { yhi->have_timeouts |= 2; } else { yhi->have_timeouts &= (~(2)); } } break; case 6: { if(set_double(&(yhi->lprm_timeout), vptr)) { yhi->have_timeouts |= 4; } else { yhi->have_timeouts &= (~(4)); } } break; case 7: { if(set_double(&(yhi->lpc_timeout), vptr)) { yhi->have_timeouts |= 8; } else { yhi->have_timeouts &= (~(8)); } } break; case 8: { yhi->data_file_first = 1; if(dkstr_is_on(vptr)) { yhi->data_file_first = 2; } } break; case 9: { pa = dkstr_dup(vptr); if(pa) { pb = yhi->snmp_target; if(pb) { dk_delete(pb); } yhi->snmp_target = pa; } else { rq->read_cfg_res = 0; if(rq->app) { dkapp_err_memory(rq->app,sizeof(char),(strlen(vptr)+1)); } } } break; } } /** Add file contents to YANOLC configuration. @param rq YALC request. @param c Configuration. @param filename Configuration file name. */ static void add_cfg DK_P3(yalc_rq_t *, rq, yalc_cfg *, c, char *, filename) { char *ptr, *vptr; FILE *f; int ende; char line[1024]; int what_section; yalc_alias_info *yai; yalc_host_info *yhi; yalc_device_info *ydi; ptr = filename; yai = NULL; yhi = NULL; ydi = NULL; while(*ptr) { #if DK_HAVE_FEATURE_BACKSLASH if(*ptr == '/') { *ptr = '\\'; } #else if(*ptr == '\\') { *ptr = '/'; } #endif ptr++; } if(rq) { if(rq->app) { f = dkapp_fopen(rq->app, filename, "r"); } else { f = dksf_fopen(filename, "r"); } } else { f = dksf_fopen(filename, "r"); } if(f) { rq->read_cfg_res = 1; ende = 0; what_section = 1; while(!ende) { if(fgets(line, sizeof(line), f)) { ptr = dkstr_chr(line, '#'); if(ptr) { *ptr = '\0'; } ptr = dkstr_start(line, NULL); if(ptr) { if(*ptr == '[') { what_section = 0; dkstr_chomp(ptr, NULL); if(strcmp(ptr, "[aliases]") == 0) { what_section = 1; yai = NULL; } else { if(strcmp(ptr, "[hosts]") == 0) { what_section = 2; yhi = NULL; } else { if(strcmp(ptr, "[devices]") == 0) { what_section = 3; ydi = NULL; } } } } else { vptr = dkstr_chr(ptr, '='); if(vptr) { *(vptr++) = '\0'; vptr = dkstr_start(vptr, NULL); if(vptr) { dkstr_chomp(vptr, NULL); dkstr_chomp(ptr, NULL); switch(what_section) { case 1: { /* aliases */ yai = dksto_it_find_like(c->ai,ptr,1); if(yai) { if(yai->value) { dk_delete(yai->value); } yai->value = dkstr_dup(vptr); if(!(yai->value)) { rq->read_cfg_res = 0; } } else { yai = yai_new(ptr, vptr); if(yai) { if(!(c->first_alias)) { c->first_alias = yai; } if(!dksto_add(c->a, (void *)yai)) { yai_remove(yai); yai = NULL; rq->read_cfg_res = 0; } } else { rq->read_cfg_res = 0; } } } break; case 2: { /* hosts */ if(yhi) { add_yhi_entry(rq, yhi, ptr, vptr); } } break; case 3: { /* devices */ if(ydi) { add_yhi_entry(rq, &(ydi->i), ptr, vptr); } } break; } } } else { dkstr_chomp(ptr, NULL); switch(what_section) { case 2: { /* hosts */ yhi = dksto_it_find_like(c->hi, ptr, 1); if(!yhi) { yhi = yhi_new(ptr); if(yhi) { if(!(c->first_host)) { c->first_host = yhi; } if(!dksto_add(c->h, (void *)yhi)) { yhi_remove(yhi); yhi = NULL; rq->read_cfg_res = 0; } } else { rq->read_cfg_res = 0; } } } break; case 3: { /* devices */ ydi = dksto_it_find_like(c->pi, ptr, 1); if(!ydi) { ydi = ydi_new(ptr); if(ydi) { if(!(c->first_device)) { c->first_device = ydi; } if(!dksto_add(c->p, (void *)ydi)) { rq->read_cfg_res = 0; ydi_remove(ydi); ydi = NULL; } } else { rq->read_cfg_res = 0; } } } break; } } } } } else { ende = 1; } } fclose(f); } } /** Preference key: Yanolc configuration file. */ static char cfg_file[] = { "/yanolc/config-file" }; /** Preference key: Yanolc SNMP configuratin file name. */ static char snmp_file[] = { "/yanolc/snmpcfg-file" }; /** Find and open yanolc.cfg file. @param rq YALC request. @return Pointer to stream on success, NULL on error. */ static dk_stream_t * yalc_snmp_cfg_open DK_P1(yalc_rq_t *, rq) { dk_stream_t *back = NULL; size_t mpl; int have_filename, x; char *fn, *logmsg[3]; if(rq) { have_filename = 0; mpl = dksf_get_maxpathlen(); fn = dk_new(char,mpl); if(fn) { /* command line preference or user preference */ if(!have_filename) { if(rq->app) { /* x = DK_APP_PREF_EXCL_CMD | DK_APP_PREF_EXCL_USER; x = (~(x)); */ x = DK_APP_PREF_EXCL_SYSTEM ; if(dkapp_get_pref(rq->app, snmp_file, fn, mpl, x)) { dksf_correct_fnsep(fn); if(have_file(fn)) { have_filename = 1; } else { } } else { } } } /* HKCU */ if(!have_filename) { if(regkey_retrieve(rq, 2, &(snmp_file[7]), fn, mpl)) { dksf_correct_fnsep(fn); if(have_file(fn)) { have_filename = 1; } else { } } else { } } if(!have_filename) { if(rq->app) { /* x = DK_APP_PREF_EXCL_SYSTEM; x = (~(x)); */ x = DK_APP_PREF_EXCL_USER | DK_APP_PREF_EXCL_CMD; if(dkapp_get_pref(rq->app, snmp_file, fn, mpl, x)) { dksf_correct_fnsep(fn); if(have_file(fn)) { have_filename = 1; } else { } } else { } } } if(!have_filename) { if(regkey_retrieve(rq, 1, &(snmp_file[7]), fn, mpl)) { dksf_correct_fnsep(fn); if(have_file(fn)) { have_filename = 1; } else { } } else { } } if(!have_filename) { if(rq->app) { have_filename = dkapp_find_file( rq->app, &(snmpcfgfile[1]), fn, mpl ); } } if(have_filename) { logmsg[0] = &(snmpcfgfile[1]); logmsg[1] = str_equal; logmsg[2] = fn; if(rq->app) { dkapp_log_msg(rq->app, DK_LOG_LEVEL_DEBUG, logmsg, 3); } if(rq->app) { back = dkapp_stream_openfile(rq->app, fn, "r"); } else { back = dkstream_openfile(fn, "r", 0, NULL); } } if(!back) { back = dkapp_read_file(rq->app, &(snmpcfgfile[1])); } dk_delete(fn); } else { if(rq->app) { dkapp_err_memory(rq->app, 1, mpl); } } } return back; } /** Read yanolc.conf file. @param rq YALC request. @return Pointer to configuration struct on success, NULL on error. */ static yalc_cfg * read_cfg DK_P1(yalc_rq_t *, rq) { yalc_cfg *back = NULL; char *logmsg[3]; size_t mpl = 0; char *fn = NULL; int have_filename = 0, x = 0; if(rq) { mpl = dksf_get_maxpathlen(); fn = dk_new(char,mpl); if(fn) { have_filename = 0; if(!have_filename) { if(rq->app) { x |= DK_APP_PREF_EXCL_CMD; x |= DK_APP_PREF_EXCL_PROG; x |= DK_APP_PREF_EXCL_USER; if(dkapp_get_pref(rq->app, cfg_file, fn, mpl, x)) { dksf_correct_fnsep(fn); if(have_file(fn)) { have_filename = 1; } } } } if(!have_filename) { if(regkey_retrieve(rq, 1, &(cfg_file[7]), fn, mpl)) { dksf_correct_fnsep(fn); if(have_file(fn)) { have_filename = 1; } } } if((!have_filename) && (rq->app)) { have_filename = dkapp_find_cfg( rq->app, &(configfile[1]), fn, mpl ); } if(have_filename) { logmsg[0] = &(configfile[1]); logmsg[1] = str_equal; logmsg[2] = fn; if(rq->app) { dkapp_log_msg(rq->app, DK_LOG_LEVEL_DEBUG, logmsg, 3); } back = yalc_cfg_new(); if(back) { rq->read_cfg_res = 0; add_cfg(rq, back, fn); } else { if(rq->app) { dkapp_err_memory(rq->app, sizeof(yalc_cfg), 1); } } } dk_delete(fn); } else { if(rq->app) { dkapp_err_memory(rq->app, 1, mpl); } } } return back; } /** Flag: SIGPIPE received. */ static #if DK_HAVE_VOLATILE volatile #endif int sig_pipe_received = 0; /** Flag: SIGINT received. */ static #if DK_HAVE_VOLATILE volatile #endif int sig_int_received = 0; /** Flag: Keyboard hit detected. */ static #if DK_HAVE_VOLATILE volatile #endif int kbhit_received = 0; /** Check whether we can continue. @return 1 if we can continue, 0 otherwise. */ static int can_continue DK_P0() { int back = 1; if(sig_pipe_received) back = 0; if(sig_int_received) back = 0; #if DK_HAVE__KBHIT if(kbhit_received) { back = 1; } else { if(_kbhit()) { kbhit_received = back = 1; #if DK_HAVE__GETCH _getch(); #endif } } #endif return back; } /** SIGINT handler. @param signo Signal number (SIGINT). */ static dk_signal_ret_t sig_int_handler DK_P1(int, signo) { dksignal_refresh(signo,sig_int_handler); sig_int_received = 1; } /** SIGPIPE handler. @param signo Signal number (SIGPIPE). */ static dk_signal_ret_t sig_pipe_handler DK_P1(int, signo) { dksignal_refresh(signo,sig_pipe_handler); sig_pipe_received = 1; } void yalc_init DK_P1(yalc_rq_t *, rq) { if(rq) { rq->printer_name = NULL; rq->server_name = NULL; rq->user_name = NULL; rq->app = NULL; rq->cmd = 0; rq->argc = 0; rq->argv = NULL; rq->data_file_first = 0; rq->snmp_host = NULL; rq->snmp_comm = NULL; rq->snmp_vers = NULL; rq->private_snmp = NULL; } } yalc_rq_t * yalc_new DK_P0() { yalc_rq_t *back = NULL; back = dk_new(yalc_rq_t,1); if(back) { yalc_init(back); } return back; } void yalc_delete DK_P1(yalc_rq_t *, rq) { char *x; if(rq) { rq->snmp_vers = NULL; rq->snmp_host = NULL; rq->snmp_comm = NULL; rq->printer_name = NULL; rq->server_name = NULL; rq->user_name = NULL; rq->app = NULL; rq->argc = 0; rq->argv = NULL; rq->cfg_file = NULL; x = rq->private_snmp; if(x) { dk_delete(x); } rq->private_snmp = NULL; dk_delete(rq); } } void yalc_set_lpr_filetype DK_P2(yalc_rq_t *, rq, int, t) { if(rq) { if((rq->cmd) == YALC_OP_LPR) { (rq->args).lpr.type = t; } } } void yalc_set_lpr_suppress_header DK_P2(yalc_rq_t *, rq, int, t) { if(rq) { if((rq->cmd) == YALC_OP_LPR) { (rq->args).lpr.suppress_header = t; } } } void yalc_set_lpr_indent_cols DK_P2(yalc_rq_t *, rq, int, t) { if(rq) { if((rq->cmd) == YALC_OP_LPR) { (rq->args).lpr.indent_cols = t; } } } void yalc_set_lpr_number_of_copies DK_P2(yalc_rq_t *, rq, int, t) { if(rq) { if((rq->cmd) == YALC_OP_LPR) { (rq->args).lpr.number_of_copies = t; } } } void yalc_set_lpr_keep_spool_queue DK_P2(yalc_rq_t *, rq, int, t) { if(rq) { if((rq->cmd) == YALC_OP_LPR) { (rq->args).lpr.keep_spool_queue = t; } } } void yalc_set_lpr_width DK_P2(yalc_rq_t *, rq, int, t) { if(rq) { if((rq->cmd) == YALC_OP_LPR) { (rq->args).lpr.with = t; } } } void yalc_set_lpr_class_name DK_P2(yalc_rq_t *, rq, char *, cln) { if(rq && cln) { if((rq->cmd) == YALC_OP_LPR) { (rq->args).lpr.class_name = cln; } } } void yalc_set_lpr_job_name DK_P2(yalc_rq_t *, rq, char *, cln) { if(rq && cln) { if((rq->cmd) == YALC_OP_LPR) { (rq->args).lpr.job_name = cln; } } } void yalc_set_lpr_mail_addr DK_P2(yalc_rq_t *, rq, char *, cln) { if(rq && cln) { if((rq->cmd) == YALC_OP_LPR) { (rq->args).lpr.mail_recipient = cln; } } } void yalc_set_lpr_remote_account DK_P2(yalc_rq_t *, rq, char *, cln) { if(rq && cln) { if((rq->cmd) == YALC_OP_LPR) { (rq->args).lpr.remote_account = cln; } } } void yalc_set_lpr_job_title DK_P2(yalc_rq_t *, rq, char *, cln) { if(rq && cln) { if((rq->cmd) == YALC_OP_LPR) { (rq->args).lpr.job_title = cln; } } } void yalc_set_lpr_other_options DK_P2(yalc_rq_t *, rq, char *, cln) { if(rq && cln) { if((rq->cmd) == YALC_OP_LPR) { (rq->args).lpr.other_options = cln; } } } void yalc_set_lpr DK_P1(yalc_rq_t *, rq) { if(rq) { rq->cmd = YALC_OP_LPR; (rq->args).lpr.type = 0; (rq->args).lpr.class_name = NULL; (rq->args).lpr.suppress_header = 1; (rq->args).lpr.indent_cols = 0; (rq->args).lpr.job_name = NULL; (rq->args).lpr.number_of_copies = 0; (rq->args).lpr.mail_recipient = NULL; (rq->args).lpr.keep_spool_queue = 0; (rq->args).lpr.remote_account = NULL; (rq->args).lpr.job_title = NULL; (rq->args).lpr.with = 0; (rq->args).lpr.other_options = NULL; } } void yalc_set_lprm DK_P2(yalc_rq_t *, rq, int, all) { if(rq) { rq->cmd = YALC_OP_LPRM; (rq->args).lprm.all = (all ? 1 : 0); } } void yalc_set_snmp_status DK_P1(yalc_rq_t *,rq) { if(rq) { rq->cmd = YALC_OP_SNMP_STATUS; (rq->args).snmp.force_output = 0; (rq->args).snmp.output_found = 0; (rq->args).snmp.run_verbose = 0; (rq->args).snmp.keep_logfile = 0; } } void yalc_set_snmp_short DK_P1(yalc_rq_t *,rq) { if(rq) { rq->cmd = YALC_OP_SNMP_SHORT; (rq->args).snmp.force_output = 0; (rq->args).snmp.output_found = 0; (rq->args).snmp.run_verbose = 0; (rq->args).snmp.keep_logfile = 0; } } void yalc_set_snmp_verbose DK_P1(yalc_rq_t *,rq) { if(rq) (rq->args).snmp.run_verbose = 1; } void yalc_set_snmp_force DK_P2(yalc_rq_t *,rq,int,val) { if(rq) { (rq->args).snmp.force_output = val; } } void yalc_set_lpc DK_P2(yalc_rq_t *, rq, int, all) { if(rq) { rq->cmd = YALC_OP_LPC; (rq->args).lpc.all = (all ? 1 : 0); } } void yalc_set_lpq DK_P7(yalc_rq_t *, rq, int, mv, int, v, int, s, int, p, int, pt, int, rdj) { if(rq) { rq->cmd = YALC_OP_LPQ; (rq->args).lpq.max_verbosity = mv; (rq->args).lpq.verbosity = v; (rq->args).lpq.short_status = s; (rq->args).lpq.periodically = p; (rq->args).lpq.period_time = pt; (rq->args).lpq.remove_filter_status = 0; (rq->args).lpq.remove_done_jobs = rdj; } } void yalc_set_printer DK_P2(yalc_rq_t *, rq, char *, pn) { if(rq && pn) { rq->printer_name = pn; } } void yalc_set_snmp_host DK_P2(yalc_rq_t *,rq,char *,hn) { if(rq && hn) { rq->snmp_host = hn; } } void yalc_set_snmp_comm DK_P2(yalc_rq_t *,rq,char *,co) { if(rq && co) { rq->snmp_comm = co; } } void yalc_set_snmp_vers DK_P2(yalc_rq_t *,rq, char *,v) { if(rq && v) { rq->snmp_vers = v; } } void yalc_set_snmp_type DK_P2(yalc_rq_t *,rq, char *,v) { if(rq && v) { rq->snmp_type = v; } } void yalc_set_server DK_P2(yalc_rq_t *, rq, char *, pn) { if(rq && pn) { rq->server_name = pn; } } void yalc_set_user DK_P2(yalc_rq_t *, rq, char *, pn) { if(rq && pn) { rq->user_name = pn; } } void yalc_set_app DK_P2(yalc_rq_t *, rq, dk_app_t *, a) { if(rq && a) { rq->app = a; } } void yalc_set_args DK_P3(yalc_rq_t *, rq, int, argc, char **, argv) { if(rq && argv && (argc > 0)) { rq->argc = argc; rq->argv = argv; } } #if DEBUG static void debug_hi DK_P2(yalc_host_info *, h, FILE *, f) { if(h->name) { fprintf(f, "Name: %s\n", h->name); } fprintf(f, "Type: %d\n", h->type); fprintf(f, "Port: %u\n", (unsigned)(h->portno)); fprintf(f, "Orig: %u %u\n", (unsigned)(h->o_min), (unsigned)(h->o_max) ); fprintf(f, "Time: %lf %lf %lf %lf\n", (((h->have_timeouts) & 1) ? (h->lpr_timeout) : 0.0), (((h->have_timeouts) & 2) ? (h->lpq_timeout) : 0.0), (((h->have_timeouts) & 4) ? (h->lprm_timeout) : 0.0), (((h->have_timeouts) & 8) ? (h->lpc_timeout) : 0.0) ); } static void print_cfg DK_P2(yalc_cfg *,c, FILE *,f) { yalc_alias_info *yai; yalc_host_info *yhi; yalc_device_info *ydi; dksto_it_reset(c->ai); while(yai = dksto_it_next(c->ai)) { fprintf(f, "ALIAS\n%s=%s\n", yai->name, yai->value); } dksto_it_reset(c->hi); while(yhi = dksto_it_next(c->hi)) { fprintf(f, "HOST\n"); debug_hi(yhi, f); } dksto_it_reset(c->pi); while(ydi = dksto_it_next(c->pi)) { fprintf(f, "PRINTER\n"); if(ydi->name) { fprintf(f, "Name: %s\n", ydi->name); } debug_hi(&(ydi->i), f); } } #endif #if DK_HAVE_WINREG_H /** Registry key name. */ static char myRegistryDefaultsKey[] = { "Software\\DKrause\\Yanolc" }; /** Open registry keys. @param rq YALC request. */ static void regkey_open DK_P1(yalc_rq_t *, rq) { HKEY hkTemp; PHKEY phkSubkey; DWORD disp; LONG retval; (rq->reg).what = 0; hkTemp = 0; phkSubkey = &hkTemp; retval = RegCreateKeyExA( HKEY_LOCAL_MACHINE, myRegistryDefaultsKey, 0, NULL, REG_OPTION_NON_VOLATILE, KEY_QUERY_VALUE, NULL, phkSubkey, &disp ); if(retval == ERROR_SUCCESS) { (rq->reg).what |= 1; (rq->reg).hklm = hkTemp; } else { } hkTemp = 0; phkSubkey = &hkTemp; retval = RegCreateKeyExA( HKEY_CURRENT_USER, myRegistryDefaultsKey, 0, NULL, REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, phkSubkey, &disp ); if(retval == ERROR_SUCCESS) { (rq->reg).what |= 2; (rq->reg).hkcu = hkTemp; } else { } } /** Close registry keys used by YALC request. @param rq YALC request. */ static void regkey_close DK_P1(yalc_rq_t *, rq) { if(((rq->reg).what) & 1) { RegCloseKey((rq->reg).hklm); } if(((rq->reg).what) & 2) { RegCloseKey((rq->reg).hkcu); } (rq->reg).what = 0; } #endif /** Preference key: Default printer. */ static char key_default_printer[] = { "/yanolc/default-printer" }; /** Preference key: Default print host. */ static char key_default_host[] = { "/yanolc/print-host" }; /** Preference key: Print destination. */ static char default_printer_name[] = { "lp" }; /** Preference key: Alias. */ static char key_alias[] = { "/yanolc/alias/" }; /** Preference key: Device. */ static char key_device[] = { "/yanolc/device/" }; /** Preference key: Server host. */ static char key_host[] = { "/yanolc/host/" }; /** Preference key: Print queue type. */ static char key_type[] = { "/type" }; /** Preference key: Users which can use -U. */ static char key_xusers[] = { "/xusers" }; /** Preference key: General timeout. */ static char key_timeout[] = { "/timeout" }; /** Preference key: Timeout for lpr. */ static char key_timeout_lpr[] = { "/timeout.lpr" }; /** Preference key: Timeout for lpq. */ static char key_timeout_lpq[] = { "/timeout.lpq" }; /** Preference key: Timeout for lprm. */ static char key_timeout_lprm[] = { "/timeout.lprm" }; /** Preference key: Timeout for lpc. */ static char key_timeout_lpc[] = { "/timeout.lpc" }; /** Preference key: Local ports. */ static char key_originate[] = { "/originate" }; /** Preference key: Send data file first. */ static char key_data_file_first[] = { "/data-file-first" }; /** Preference key: SNMP settings. */ static char key_snmp[] = { "/snmp" }; /** Resolve alias for queue name. @param rq YALC request. */ static void get_alias DK_P1(yalc_rq_t *, rq) { char key[512], val[sizeof(key)]; yalc_cfg *ycfg; yalc_alias_info *ai; if((strlen(key_alias) + strlen(rq->printer_name)) < sizeof(key)) { strcpy(key, key_alias); strcat(key, rq->printer_name); } #if DK_HAVE_WINREG_H if(regkey_retrieve(rq, 3, &(key[7]), val, sizeof(val))) { rq->dev = dkstr_dup(val); } #endif if(!(rq->dev)) { if(rq->app) { if(dkapp_get_pref(rq->app, key, val, sizeof(val), 0)) { rq->dev = dkstr_dup(val); } } } if(!(rq->dev)) { if(rq->cfg_file) { ycfg = ((yalc_cfg *)(rq->cfg_file)); ai = (yalc_alias_info *)dksto_it_find_like(ycfg->ai, rq->printer_name, 1); if(ai) { if(ai->value) { rq->dev = dkstr_dup(ai->value); } } } } } /** Get configuration value. @param rq YALC request. @param k Key. @param h Configuration sources (2=user, 1=system). @param v Result buffer. @param s Size of \a v. @return 1 on success, 0 on error. */ static int get_config_value DK_P5(yalc_rq_t *, rq, char *, k, int, h, char *, v, size_t, s) { int back = 0; char key[256]; size_t sz; int ex; yalc_cfg *ycfg; yalc_host_info *yh1, *yh2; yalc_device_info *yd; if(!back) { if(h & 2) { if(rq->app) { if(rq->dev) { sz = strlen(k); sz += strlen(key_device); sz += strlen(rq->dev); if(sz < sizeof(key)) { strcpy(key, key_device); strcat(key, rq->dev); strcat(key, k); ex = DK_APP_PREF_EXCL_SYSTEM; if(dkapp_get_pref(rq->app, key, v, s, ex)) { back = 1; } } } } } } if(!back) { if(h & 2) { if(rq->dev) { sz = strlen(k); sz += strlen(key_device); sz += strlen(rq->dev); if(sz < sizeof(key)) { strcpy(key, key_device); strcat(key, rq->dev); strcat(key, k); if(regkey_retrieve(rq, 2, &(key[7]), v, s)) { back = 1; } } } } } if(!back) { if(h & 2) { if(rq->app) { if(rq->host) { sz = strlen(k); sz += strlen(key_host); sz += strlen(rq->host); if(sz < sizeof(key)) { strcpy(key, key_host); strcat(key, rq->host); strcat(key, k); ex = DK_APP_PREF_EXCL_SYSTEM; if(dkapp_get_pref(rq->app, key, v, s, ex)) { back = 1; } } } } } } if(!back) { if(h & 2) { if(rq->host) { sz = strlen(k); sz += strlen(key_host); sz += strlen(rq->host); if(sz < sizeof(key)) { strcpy(key, key_host); strcat(key, rq->host); strcat(key, k); if(regkey_retrieve(rq, 2, &(key[7]), v, s)) { back = 1; } } } } } if(!back) { if(h & 1) { if(rq->app) { if(rq->dev) { sz = strlen(k); sz += strlen(key_device); sz += strlen(rq->dev); if(sz < sizeof(key)) { strcpy(key, key_device); strcat(key, rq->dev); strcat(key, k); ex = DK_APP_PREF_EXCL_CMD; ex |= DK_APP_PREF_EXCL_PROG; ex |= DK_APP_PREF_EXCL_USER; if(dkapp_get_pref(rq->app, key, v, s, ex)) { back = 1; } } } } } } if(!back) { if(h & 1) { if(rq->dev) { sz = strlen(k); sz += strlen(key_device); sz += strlen(rq->dev); if(sz < sizeof(key)) { strcpy(key, key_device); strcat(key, rq->dev); strcat(key, k); if(regkey_retrieve(rq, 1, &(key[7]), v, s)) { back = 1; } } } } } if(!back) { if(h & 1) { if(rq->host) { if(rq->app) { sz = strlen(k); sz += strlen(key_host); sz += strlen(rq->host); if(sz < sizeof(key)) { strcpy(key, key_host); strcat(key, rq->host); strcat(key, k); ex = DK_APP_PREF_EXCL_CMD; ex |= DK_APP_PREF_EXCL_PROG; ex |= DK_APP_PREF_EXCL_USER; if(dkapp_get_pref(rq->app, key, v, s, ex)) { back = 1; } } } } } } if(!back) { if(h & 1) { if(rq->host) { sz = strlen(k); sz += strlen(key_host); sz += strlen(rq->host); if(sz < sizeof(key)) { strcpy(key, key_host); strcat(key, rq->host); strcat(key, k); if(regkey_retrieve(rq, 1, &(key[7]), v, s)) { back = 1; } } } } } if((rq->cfg_file) && (rq->read_cfg_res)) { ycfg = ((yalc_cfg *)(rq->cfg_file)); yh1 = NULL; yh2 = NULL; yd = NULL; if(rq->dev) { yd = (yalc_device_info *)dksto_it_find_like((ycfg->pi), (rq->dev), 1); if(yd) { yh1 = &(yd->i); } } if(rq->host) { yh2 = (yalc_host_info *)dksto_it_find_like((ycfg->hi), (rq->host), 1); } if(!back) { if(strcmp(k, key_type) == 0) { if(yh1) { if((yh1->type) != YALC_METHOD_UNKNOWN) { sprintf(v, "%s", pstype_keywords[(yh1->type) - 1]); back = 1; } } if(!back) { if(yh2) { if((yh2->type) != YALC_METHOD_UNKNOWN) { sprintf(v, "%s", pstype_keywords[(yh2->type) - 1]); back = 1; } } } } else { if(strcmp(k, key_xusers) == 0) { if(yh1) { if(yh1->xusers) { if(strlen(yh1->xusers) < s) { strcpy(v, yh1->xusers); back = 1; } } } if(!back) { if(yh2) { if(yh2->xusers) { if(strlen(yh2->xusers) < s) { strcpy(v, yh2->xusers); back = 1; } } } } } else { if(strcmp(k, key_originate) == 0) { if(yh1) { if(yh1->o_min) { sprintf(v, "%u-%u", ((unsigned)(yh1->o_min)), ((unsigned)(yh1->o_max))); back = 1; } } if(!back) { if(yh2) { if(yh2->o_min) { sprintf(v, "%u-%u", ((unsigned)(yh2->o_min)), ((unsigned)(yh2->o_max))); back = 1; } } } } else { if(strcmp(k, key_timeout_lpr) == 0) { if(yh1) { if((yh1->have_timeouts) & 1) { sprintf(v, "%lf", yh1->lpr_timeout); back = 1; } } if(!back) { if(yh2) { if((yh2->have_timeouts) & 1) { sprintf(v, "%lf", yh2->lpr_timeout); back = 1; } } } } else { if(strcmp(k, key_timeout_lpq) == 0) { if(yh1) { if((yh1->have_timeouts) & 2) { sprintf(v, "%lf", yh1->lpq_timeout); back = 1; } } if(!back) { if(yh2) { if((yh2->have_timeouts) & 2) { sprintf(v, "%lf", yh2->lpq_timeout); back = 1; } } } } else { if(strcmp(k, key_timeout_lprm) == 0) { if(yh1) { if((yh1->have_timeouts) & 4) { sprintf(v, "%lf", yh1->lprm_timeout); back = 1; } } if(!back) { if(yh2) { if((yh2->have_timeouts) & 4) { sprintf(v, "%lf", yh2->lprm_timeout); back = 1; } } } } else { if(strcmp(k, key_timeout_lpc) == 0) { if(yh1) { if((yh1->have_timeouts) & 8) { sprintf(v, "%lf", yh1->lpc_timeout); back = 1; } } if(!back) { if(yh2) { if((yh2->have_timeouts) & 8) { sprintf(v, "%lf", yh2->lpc_timeout); back = 1; } } } } else { if(strcmp(k, key_data_file_first) == 0) { if(yh1) { if(yh1->data_file_first) { back = 1; if(yh1->data_file_first == 2) { sprintf(v, "yes"); } else { sprintf(v, "no"); } } } if(!back) { if(yh2) { if(yh2->data_file_first) { back = 1; if(yh2->data_file_first == 2) { sprintf(v, "yes"); } else { sprintf(v, "no"); } } } } } else { if(strcmp(k, key_snmp) == 0) { if(yh1) { if(yh1->snmp_target) { if(strlen(yh1->snmp_target) < s) { strcpy(v, yh1->snmp_target); back = 1; } } } if((!back) && (yh2)) { if(yh2->snmp_target) { if(strlen(yh1->snmp_target) < s) { strcpy(v, yh1->snmp_target); back = 1; } } } } else { /* OTHER OPTIONS HERE */ } } } } } } } } } } } return back; } /** Set up request type. @param rq YALC request. */ static void setup_type DK_P1(yalc_rq_t *, rq) { char val[256]; if(get_config_value(rq, key_type, 3, val, sizeof(val))) { rq->type = dkstr_array_index(pstype_keywords, val, 0) + 1; switch(rq->type) { case YALC_METHOD_LPRNG: case YALC_METHOD_BSD: { if(rq->portno == 0) { rq->portno = 515; } } break; } } } /** Set up internal list of users allowed to use -U. @param rq YALC request. */ static void setup_xusers DK_P1(yalc_rq_t *, rq) { char val[256], username[256], *ptr1, *ptr2; rq->xuser_allowed = 0; if(get_config_value(rq, key_xusers, 1, val, sizeof(val))) { if(dksf_get_uname(username, sizeof(username))) { ptr1 = dkstr_start(val, NULL); if(ptr1) { dkstr_chomp(ptr1, NULL); while(ptr1) { ptr2 = dkstr_next(ptr1, NULL); if(strcmp(ptr1, username) == 0) { rq->xuser_allowed = 1; } else { if(strcmp(ptr1, "*") == 0) { rq->xuser_allowed = 1; } } ptr1 = ptr2; } } } } } /** Set up local port range if necessary. @param rq YALC request. */ static void setup_originate DK_P1(yalc_rq_t *, rq) { char val[256], *ptr1; unsigned u1, u2; if(get_config_value(rq, key_originate, 3, val, sizeof(val))) { ptr1 = dkstr_chr(val, '-'); if(ptr1) { *ptr1 = ' '; if(sscanf(val, "%u %u", &u1, &u2) == 2) { rq->o_min = u1; rq->o_max = u2; } } else { if(sscanf(val, "%u %u", &u1, &u2) == 2) { rq->o_min = u1; rq->o_max = u2; } else { if(sscanf(val, "%u", &u1) == 1) { rq->o_min = u1; rq->o_max = u1; } } } } } /** Find LPR-specific timeout. @param rq YALC request. */ static void setup_timeout_lpr DK_P1(yalc_rq_t *, rq) { char val[256]; double d; if(rq->cmd == YALC_OP_LPR) { if(get_config_value(rq, key_timeout_lpr, 3, val, sizeof(val))) { if(strcmp(val, "-")) { if(sscanf(val, "%lf", &d) == 1) { rq->have_timeout = 1; rq->to = d; } } } } } /** Find LPQ-specific timeout. @param rq YALC request. */ static void setup_timeout_lpq DK_P1(yalc_rq_t *, rq) { char val[256]; double d; if(rq->cmd == YALC_OP_LPQ) { if(get_config_value(rq, key_timeout_lpq, 3, val, sizeof(val))) { if(strcmp(val, "-")) { if(sscanf(val, "%lf", &d) == 1) { rq->have_timeout = 1; rq->to = d; } } } } } /** Find LPRM-specific timeout. @param rq YALC request. */ static void setup_timeout_lprm DK_P1(yalc_rq_t *, rq) { char val[256]; double d; if(rq->cmd == YALC_OP_LPRM) { if(get_config_value(rq, key_timeout_lprm, 3, val, sizeof(val))) { if(strcmp(val, "-")) { if(sscanf(val, "%lf", &d) == 1) { rq->have_timeout = 1; rq->to = d; } } } } } /** Find LPC-specific timeout. @param rq YALC request. */ static void setup_timeout_lpc DK_P1(yalc_rq_t *, rq) { char val[256]; double d; if(rq->cmd == YALC_OP_LPC) { if(get_config_value(rq, key_timeout_lpc, 3, val, sizeof(val))) { if(strcmp(val, "-")) { if(sscanf(val, "%lf", &d) == 1) { rq->have_timeout = 1; rq->to = d; } } } } } /** Setup for SNMP request. @param rq YALC request. */ static void setup_snmp DK_P1(yalc_rq_t *, rq) { char val[256], *pa, *pb, *p1, *p2, *p3, *p4; if((rq->cmd == YALC_OP_SNMP_STATUS) || (rq->cmd == YALC_OP_SNMP_SHORT)) { if(get_config_value(rq, key_snmp, 3, val, sizeof(val))) { pa = dkstr_dup(val); if(pa) { pb = rq->private_snmp; if(pb) { dk_delete(pb); } rq->private_snmp = pa; p1 = p2 = p3 = p4 = NULL; p1 = dkstr_start(rq->private_snmp, NULL); if(p1) { p2 = dkstr_chr(p1, ':'); if(p2) { *(p2++) = (char)0; p2 = dkstr_start(p2, NULL); if(p2) { p3 = dkstr_chr(p2, ':'); if(p3) { *(p3++) = (char)0; p3 = dkstr_start(p3, NULL); if(p3) { p4 = dkstr_chr(p3, ':'); if(p4) { *(p4++) = (char)0; p4 = dkstr_start(p4, NULL); } } } } } } if(p1 && (!(rq->snmp_host))) { rq->snmp_host = p1; } if(p2 && (!(rq->snmp_type))) { rq->snmp_type = p2; } if(p3 && (!(rq->snmp_comm))) { rq->snmp_comm = p3; } if(p4 && (!(rq->snmp_vers))) { rq->snmp_vers = p4; } } else { if(rq->app) { dkapp_err_memory(rq->app,sizeof(char),(strlen(val)+1)); } } } } } /** Set option "data file first". @param rq YALC request. */ static void setup_data_file_first DK_P1(yalc_rq_t *, rq) { char val[256]; if(get_config_value(rq, key_data_file_first, 3, val, sizeof(val))) { if(dkstr_is_on(val)) { rq->data_file_first = 1; } } } /** Setup timeouts for operations. @param rq YALC request. */ static void setup_timeouts DK_P1(yalc_rq_t *, rq) { char val[256]; double d; if(get_config_value(rq, key_timeout, 3, val, sizeof(val))) { if(strcmp(val, "-")) { if(sscanf(val, "%lf", &d) == 1) { rq->have_timeout = 1; rq->to = d; } else { rq->have_timeout = 0; rq->to = 0.0; } } else { rq->have_timeout = 0; rq->to = 0.0; } } } /** Find printer name. @param rq YALC request. */ static void get_printer_name DK_P1(yalc_rq_t *, rq) { char *ptr, val[128]; unsigned u; size_t sz; int exclreg; yalc_cfg *ycfg; /* Printer name from command line */ ycfg = NULL; if(rq->cfg_file) { ycfg = (yalc_cfg *)(rq->cfg_file); } if(!(rq->printer_name)) { if(rq->app) { exclreg = DK_APP_PREF_EXCL_SYSTEM; exclreg |= DK_APP_PREF_EXCL_USER; exclreg |= DK_APP_PREF_EXCL_PROG; if(dkapp_get_pref(rq->app,key_default_printer,val,sizeof(val),exclreg)) { rq->printer_from_env = dkstr_dup(val); if(rq->printer_from_env) { rq->printer_name = rq->printer_from_env; } } } } /* Printer name from environment variables */ if(!(rq->printer_name)) { ptr = getenv("NGPRINTER"); if(ptr) { rq->printer_from_env = dkstr_dup(ptr); if(rq->printer_from_env) { rq->printer_name = rq->printer_from_env; } } } if(!(rq->printer_name)) { ptr = getenv("NPRINTER"); if(ptr) { rq->printer_from_env = dkstr_dup(ptr); if(rq->printer_from_env) { rq->printer_name = rq->printer_from_env; } } } if(!(rq->printer_name)) { ptr = getenv("LPDEST"); if(ptr) { rq->printer_from_env = dkstr_dup(ptr); if(rq->printer_from_env) { rq->printer_name = rq->printer_from_env; } } } if(!(rq->printer_name)) { ptr = getenv("PRINTER"); if(ptr) { rq->printer_from_env = dkstr_dup(ptr); if(rq->printer_from_env) { rq->printer_name = rq->printer_from_env; } } } /* Printer from user preferences */ if(!(rq->printer_name)) { if(rq->app) { exclreg = DK_APP_PREF_EXCL_SYSTEM; exclreg |= DK_APP_PREF_EXCL_CMD; if(dkapp_get_pref(rq->app,key_default_printer,val,sizeof(val),exclreg)) { rq->printer_from_env = dkstr_dup(val); if(rq->printer_from_env) { rq->printer_name = rq->printer_from_env; } } } } /* Printer name from registry HKCU */ #if DK_HAVE_WINREG_H if(!(rq->printer_name)) { if(regkey_retrieve(rq, 2, &(key_default_printer[7]), val, sizeof(val))) { rq->printer_from_env = dkstr_dup(val); if(rq->printer_from_env) { rq->printer_name = rq->printer_from_env; } } } #endif /* Printer name from system preferences */ if(!(rq->printer_name)) { if(rq->app) { exclreg = DK_APP_PREF_EXCL_USER; exclreg |= DK_APP_PREF_EXCL_PROG; exclreg |= DK_APP_PREF_EXCL_CMD; if(dkapp_get_pref(rq->app,key_default_printer,val,sizeof(val),exclreg)) { rq->printer_from_env = dkstr_dup(val); if(rq->printer_from_env) { rq->printer_name = rq->printer_from_env; } } } } /* Printer name from registry HKLM */ #if DK_HAVE_WINREG_H if(!(rq->printer_name)) { if(regkey_retrieve(rq, 1, &(key_default_printer[7]), val, sizeof(val))) { rq->printer_from_env = dkstr_dup(val); if(rq->printer_from_env) { rq->printer_name = rq->printer_from_env; } } } #endif if(!(rq->printer_name)) { if(ycfg) { if(ycfg->first_alias) { if((ycfg->first_alias)->value) { rq->printer_from_env = dkstr_dup( (ycfg->first_alias)->value ); if(rq->printer_from_env) { rq->printer_name = rq->printer_from_env ; } } } if(!(rq->printer_name)) { if(ycfg->first_device) { if((ycfg->first_device)->name) { rq->printer_from_env = dkstr_dup( (ycfg->first_device)->name ); if(rq->printer_from_env) { rq->printer_name = rq->printer_from_env ; } } } } } } if(!(rq->printer_name)) { rq->printer_name = default_printer_name; } /* Get the print host now */ if(rq->printer_name) { ptr = dkstr_chr(rq->printer_name, '@'); if(ptr) { rq->queue = dkstr_dup(rq->printer_name); ptr++; rq->host = dkstr_dup(ptr); rq->dev = dkstr_dup(rq->printer_name); if(rq->queue) { ptr = dkstr_chr(rq->queue, '@'); *ptr = '\0'; } rq->type = YALC_METHOD_BSD; rq->portno = 515; } else { ptr = dkstr_chr(rq->printer_name, '%'); if(ptr) { rq->host = dkstr_dup(rq->printer_name); rq->dev = dkstr_dup(rq->printer_name); if(rq->host) { ptr = dkstr_chr(rq->host, '%'); if(ptr) { *(ptr++) = '\0'; if(sscanf(ptr, "%u", &u) == 1) { rq->portno = u; rq->type = YALC_METHOD_RAWTCPIP; } } } } else { if(rq->server_name) { rq->queue = dkstr_dup(rq->printer_name); rq->host = dkstr_dup(rq->server_name); sz = strlen(rq->printer_name) + strlen(rq->server_name) + 2; rq->dev = dk_new(char,sz); if(rq->dev) { strcpy(rq->dev, rq->printer_name); strcat(rq->dev, "@"); strcat(rq->dev, rq->server_name); } rq->type = YALC_METHOD_BSD; rq->portno = 515; } else { get_alias(rq); if(rq->dev) { ptr = dkstr_chr(rq->dev, '@'); if(ptr) { rq->queue = dkstr_dup(rq->dev); if(rq->queue) { ptr = dkstr_chr(rq->queue, '@'); if(ptr) { *(ptr++) = '\0'; rq->host = dkstr_dup(ptr); rq->type = YALC_METHOD_BSD; rq->portno = 515; } } } else { ptr = dkstr_chr(rq->dev, '%'); if(ptr) { rq->host = dkstr_dup(rq->dev); if(rq->host) { ptr = dkstr_chr(rq->host, '%'); if(ptr) { *(ptr++) = '\0'; if(sscanf(ptr, "%u", &u) == 1) { rq->portno = u; rq->type = YALC_METHOD_RAWTCPIP; } } } } } } else { ptr = getenv("PRINTHOST"); if(ptr) { rq->server_name = dkstr_dup(ptr); } if(!(rq->server_name)) { /* User prefereneces */ exclreg = DK_APP_PREF_EXCL_SYSTEM; exclreg |= DK_APP_PREF_EXCL_CMD; if(dkapp_get_pref(rq->app,key_default_host,val,sizeof(val),exclreg)) { rq->server_name = dkstr_dup(val); } } #if DK_HAVE_WINREG_H if(!(rq->server_name)) { /* HKCU */ if(regkey_retrieve(rq,2,&(key_default_host[7]),val,sizeof(val))) { rq->server_name = dkstr_dup(val); } } #endif if(!(rq->server_name)) { /* System preferences */ exclreg = DK_APP_PREF_EXCL_USER; exclreg |= DK_APP_PREF_EXCL_PROG; exclreg |= DK_APP_PREF_EXCL_CMD; if(dkapp_get_pref(rq->app,key_default_host,val,sizeof(val),exclreg)) { rq->server_name = dkstr_dup(val); } } #if DK_HAVE_WINREG_H if(!(rq->server_name)) { /* HKLM */ if(regkey_retrieve(rq,1,&(key_default_host[7]),val,sizeof(val))) { rq->server_name = dkstr_dup(val); } } #endif if(!(rq->server_name)) { if(ycfg) { if(ycfg->first_host) { if((ycfg->first_host)->name) { rq->server_name = dkstr_dup( (ycfg->first_host)->name ); } } } } if(rq->server_name) { rq->queue = dkstr_dup(rq->printer_name); rq->host = dkstr_dup(rq->server_name); sz = strlen(rq->printer_name) + strlen(rq->server_name) + 2; rq->dev = dk_new(char,sz); if(rq->dev) { strcpy(rq->dev, rq->printer_name); strcat(rq->dev, "@"); strcat(rq->dev, rq->server_name); } rq->type = YALC_METHOD_BSD; rq->portno = 515; } } } } } if(rq->dev) { /* type */ setup_type(rq); /* xusers */ setup_xusers(rq); /* originate */ setup_originate(rq); /* all timeouts */ setup_timeouts(rq); /* timeout lpr */ setup_timeout_lpr(rq); /* timeout lpq */ setup_timeout_lpq(rq); /* timeout lprm */ setup_timeout_lprm(rq); /* timeout lpc */ setup_timeout_lpc(rq); /* check whether to send data or control file first */ setup_data_file_first(rq); /* create SNMP setup */ setup_snmp(rq); } if((rq->xuser_allowed) && (rq->user_name)) { rq->user = dkstr_dup(rq->user_name); } else { if(dksf_get_uname(val, sizeof(val))) { rq->user = dkstr_dup(val); } } } } /** Complete request (insert defaults for missing settings). @param rq YALC request. @return 1 on success, 0 on error. */ static int complete_request DK_P1(yalc_rq_t *, rq) { int back = 1; switch(rq->cmd) { case YALC_OP_LPR : { get_printer_name(rq); } break; case YALC_OP_LPQ : { get_printer_name(rq); } break; case YALC_OP_LPRM : { get_printer_name(rq); } break; case YALC_OP_LPC : { /* printer name from argc/argv first, if no name available, get_printer_name() */ if((rq->argv) && ((rq->argc) > 1)) { rq->printer_name = (rq->argv)[1]; } get_printer_name(rq); } break; case YALC_OP_SNMP_STATUS: case YALC_OP_SNMP_SHORT: { get_printer_name(rq); } break; } return back; } /** Chech whether or not a character is printable. @param c Character to test. @return 1 for printable characters, 0 otherwise. */ static int my_isprintable DK_P1(char, c) { int back = 0; if((c >= 0x20) && (c <= 0x7F)) { back = 1; } else { switch(c) { case '\r' : case '\n' : case '\t' : case 'ä' : case 'ö' : case 'ü' : case 'Ä' : case 'Ö' : case 'Ü' : case 'ß' : { back = 1; } break; } } return back; } /** Remove unprintable characters from output line. @param buf Buffer containing printer response. @param sz Number of bytes used in \a buf. */ static void remove_unprintables DK_P2(char *,buf, size_t *, sz) { /* char *ptr, *ptra, *ptrb; size_t max, x, y; max = *sz; x = 0; ptr = buf; while(x < max) { if(my_isprintable(*ptr)) { ptr++; x++; } else { ptra = ptrb = ptr; ptrb++; y = max - x; y--; while(y--) { *(ptra++) = *(ptrb++); } max--; } } *sz = max; */ } /** Keywords, used to remove filter status lines from output. */ static char *keywords_to_remove[] = { "Status:", "Filter_status:", NULL }; /** Keyword, used to remove completed jobs. */ static char *keyword_done[] = { "done", NULL }; /** Check whether a string starts with one value from an array. @param str String to check. @param array Array of patterns which might occur at start. @return 1 if \a str starts with one of the strings from \a array, 0 otherwise. */ static int start_with DK_P2(char *, str, char **, array) { int back = 0; char **ptr; size_t lgt1, lgt2; ptr = array; lgt1 = strlen(str); while((*ptr) && (!back)) { lgt2 = strlen(*ptr); if(lgt1 >= lgt2) { if(strncmp(str, *ptr, lgt2) == 0) { back = 1; } } ptr++; } return back; } /** Run LPRM request. @param rq YALC request. @return 1 on success, 0 on error. */ static int run_lprm DK_P1(yalc_rq_t *, rq) { int back = 0; char *request = NULL; char response[8192]; size_t sz; char opcode; unsigned long mpl; char *tmpfilename; int i, ende; FILE *f; dk_tcpip_t *sock; dk_ip_addr_t *addr; opcode = 0x05; mpl = dksf_get_maxpathlen(); tmpfilename = dk_new(char,mpl); if(tmpfilename) { if(rq->app) { if(dkapp_tmpnam(rq->app, tmpfilename, (size_t)mpl)) { request = NULL; if((rq->args).lprm.all) { sz = strlen(rq->user) + 12; request = dk_new(char,sz); if(request) { sprintf(request, "%call %s all\n", opcode, rq->user); } } else { sz = strlen(rq->user) + strlen(rq->queue) + 6; if((rq->argc) && (rq->argv)) { for(i = 0; i < rq->argc; i++) { if((rq->argv)[i]) { sz += (1 + strlen((rq->argv)[i])); } } request = dk_new(char,sz); if(request) { sprintf(request, "%c%s %s", opcode, rq->queue, rq->user ); for(i = 0; i < rq->argc; i++) { if((rq->argv)[i]) { strcat(request, " "); strcat(request, (rq->argv)[i]); } } strcat(request, "\n"); } } else { sz = strlen(rq->user) + strlen(rq->queue) + 10; request = dk_new(char,sz); if(request) { sprintf(request, "%c%s %s all\n", opcode, rq->queue, rq->user ); } } } if(request) { f = dkapp_fopen(rq->app, tmpfilename, "wb"); if(f) { sock = dktcpip_new(); if(sock) { dktcpip_set_reuse(sock, 1); if(rq->have_timeout) { dktcpip_set_timeout(sock, rq->to); } addr = dktcpip_get_addr(sock, DK_IP_ADDR_LOCAL_WISHED); dktcpip_addr_set_port(addr, rq->o_min, rq->o_max); ymp_configure_local_nic(); if(dktcpipaddr_set_ip_any(addr)) { ymp_local_nic_configured(); addr = dktcpip_get_addr(sock, DK_IP_ADDR_REMOTE_WISHED); dktcpip_addr_set_port(addr, rq->portno, rq->portno); ymp_lookup_remote(rq->host); if(dktcpipaddr_set_ip_byname(addr,rq->host,sock)) { ymp_looked_up_remote(rq->host); ymp_connect(rq->host); if(dktcpip_up(sock)) { ymp_connected(rq->host); sz = strlen(request); ymp_try_send(sz); if(dktcpip_write(sock, request, &sz)) { ymp_have_send(sz); dktcpip_closewrite(sock); back = 1; ende = 0; while(!ende) { sz = sizeof(response); ymp_try_receive(sz); if(dktcpip_read(sock, response, &sz)) { ymp_have_received(sz); if(sz > 0) { remove_unprintables(response, &sz); if(sz > 0) { (void)fwrite(response,1,sz,f); } } else { ende = 1; } } else { ende = 1; } } } else { yme_error_while_sending(); } dktcpip_closewrite(sock); ymp_close_conn(); dktcpip_down(sock); ymp_have_closed_conn(); } else { yme_failed_to_establish_connection(rq->host); } } else { yme_failed_to_find_remote_host(rq->host); } } else { yme_failed_to_find_local_network_address(); } dktcpip_delete(sock); } fclose(f); f = dkapp_fopen(rq->app, tmpfilename, "r"); if(f) { ende = 0; while(!ende) { sz = fread(response,1,sizeof(response),f); if(sz > 0) { (void)fwrite(response,1,sz,stdout); } else { ende = 1; } } fclose(f); } else { yme_failed_to_read_from_file(tmpfilename); } } else { yme_failed_to_write_to_file(tmpfilename); } dk_delete(request); } } else { yme_could_not_find_temp_filename(); } } else { yme_incomplete_configuration(); } dk_delete(tmpfilename); } else { if(rq->app) { dkapp_err_memory(rq->app, 1, mpl); } } return back; } /** Lpc commands. */ static char *lpc_keywords[] = { /* 0 */ "start", /* 1 */ "stop", /* 2 */ "enable", /* 3 */ "disable", /* 4 */ "abort", /* 5 */ "kill", /* 6 */ "topq", /* 7 */ "status", /* ----- END OF RFC1179 commands ----- */ /* 8 */ "hold", /* 9 */ "holdall", /* 10 */ "release", /* 11 */ "move", /* 12 */ "redirect", /* 13 */ "active", /* 14 */ "lpd", /* 15 */ "reread", NULL }; /** @defgroup yanolclpccommands [yanolc] LPC commands. */ /*@{*/ /** Start print queue. */ #define LPC_START 0 /** Stop print queue. */ #define LPC_STOP 1 /** Enable queueing to queue. */ #define LPC_ENABLE 2 /** Disable queueing to queue. */ #define LPC_DISABLE 3 /** Abort current job. */ #define LPC_ABORT 4 /** Kill current job. */ #define LPC_KILL 5 /** Move job to top of queue. */ #define LPC_TOPQ 6 /** Show queue status. */ #define LPC_STATUS 7 /* ----- END OF RFC1179 commands ----- */ /** Hold job. */ #define LPC_HOLD 8 /** Hold all jobs. */ #define LPC_HOLDALL 9 /** Release job. */ #define LPC_RELEASE 10 /** ??? */ #define LPC_MOVE 11 /** Redirect job to another queue. */ #define LPC_REDIRECT 12 /** Check whether queue is active. */ #define LPC_ACTIVE 13 /** ??? */ #define LPC_LPD 14 /** Reread configuration. */ #define LPC_REREAD 15 /*@}*/ /** Run LPC request. @param rq YALC request. @return 1 on success, 0 on error. */ static int run_lpc DK_P1(yalc_rq_t *, rq) { int back = 0; unsigned long mpl; char *tmpfilename; char opcode; size_t sz; char *request; char response[8192]; int i, ende; FILE *f; dk_tcpip_t *sock; dk_ip_addr_t *addr; mpl = dksf_get_maxpathlen(); tmpfilename = dk_new(char,mpl); if(tmpfilename) { if(rq->app) { if(dkapp_tmpnam(rq->app, tmpfilename, mpl)) { opcode = 0x06; if(rq->argc > 0) { ende = dkstr_array_index(lpc_keywords, (rq->argv)[0], 1); if(ende >= 0) { if((rq->cmd = YALC_METHOD_LPRNG) || (ende < LPC_HOLD)) { sz = strlen(rq->queue); sz += strlen(rq->user); sz += 5; if((rq->argc) && (rq->argv)) { for(i = 0; i < (rq->argc); i++) { if((rq->argv)[i]) { if(i == 1) { sz += (1 + strlen(rq->queue)); } else { sz += (1 + strlen((rq->argv)[i])); } } } } request = dk_new(char,sz); if(request) { sprintf(request, "%c%s %s", opcode, rq->queue, rq->user ); if((rq->argc) && (rq->argv)) { for(i = 0; i < (rq->argc); i++) { if((rq->argv)[i]) { strcat(request, " "); if(i == 1) { strcat(request, rq->queue); } else { strcat(request, (rq->argv)[i]); } } } } strcat(request, "\n"); f = dkapp_fopen(rq->app, tmpfilename, "wb"); if(f) { sock = dktcpip_new(); if(sock) { dktcpip_set_reuse(sock, 1); if(rq->have_timeout) { dktcpip_set_timeout(sock, rq->to); } addr = dktcpip_get_addr(sock, DK_IP_ADDR_LOCAL_WISHED); dktcpip_addr_set_port(addr, rq->o_min, rq->o_max); ymp_configure_local_nic(); if(dktcpipaddr_set_ip_any(addr)) { ymp_local_nic_configured(); addr = dktcpip_get_addr(sock, DK_IP_ADDR_REMOTE_WISHED); dktcpip_addr_set_port(addr, rq->portno, rq->portno); ymp_lookup_remote(rq->host); if(dktcpipaddr_set_ip_byname(addr,rq->host,sock)) { ymp_looked_up_remote(rq->host); ymp_connect(rq->host); if(dktcpip_up(sock)) { ymp_connected(rq->host); sz = strlen(request); ymp_try_send(sz); if(dktcpip_write(sock, request, &sz)) { ymp_have_send(sz); dktcpip_closewrite(sock); ende = 0; while((!ende) && (can_continue())) { sz = sizeof(response); ymp_try_receive(sz); if(dktcpip_read(sock, response, &sz)) { ymp_have_received(sz); back = 1; if(sz > 0) { remove_unprintables(response, &sz); if(sz > 0) { (void)fwrite(response,1,sz,f); } } else { ende = 1; } } else { ende = 1; } } } else { yme_error_while_sending(); } ymp_close_conn(); dktcpip_down(sock); ymp_have_closed_conn(); } else { yme_failed_to_establish_connection(rq->host); } } else { yme_failed_to_find_remote_host(rq->host); } } else { yme_failed_to_find_local_network_address(); } dktcpip_delete(sock); } else { if(rq->app) { dkapp_err_memory(rq->app, sizeof(dk_tcpip_t), 1); } } fclose(f); f = dkapp_fopen(rq->app, tmpfilename, "rb"); if(f) { ende = 0; while(!ende) { sz = fread(response,1,sizeof(response),f); if(sz > 0) { (void)fwrite(response,1,sz,stdout); } else { ende = 1; } } fclose(f); } else { yme_failed_to_read_from_file(tmpfilename); } } else { yme_failed_to_write_to_file(tmpfilename); } dk_delete(request); } else { if(rq->app) { dkapp_err_memory(rq->app, 1, sz); } } } else { yme_lpc_for_lprng_only(); } } else { yme_unknown_command_in_lpc(); } } else { yme_missing_command_in_lpc(); } } else { yme_could_not_find_temp_filename(); } } else { } dk_delete(tmpfilename); } else { if(rq->app) { dkapp_err_memory(rq->app, 1, mpl); } } return back; } /** Run LPQ request. @param rq YALC request. @return 1 on success, 0 on error. */ static int run_lpq DK_P1(yalc_rq_t *, rq) { int back = 0; unsigned long mpl; char *tmpfilename, *ptr; char opcode; size_t sz; char *request; char response[8192]; int i, ende, t, must_print; dk_tcpip_t *sock; dk_ip_addr_t *addr; FILE *f; mpl = dksf_get_maxpathlen(); tmpfilename = dk_new(char,mpl); if(tmpfilename) { if(rq->app) { if(dkapp_tmpnam(rq->app, tmpfilename, mpl)) { opcode = 0x04; (rq->args).lpq.remove_filter_status = 1; if((rq->args).lpq.short_status) { opcode = 0x03; } else { if(rq->type == YALC_METHOD_LPRNG) { if(((rq->args).lpq.verbosity) || ((rq->args).lpq.max_verbosity)) { (rq->args).lpq.remove_filter_status = 0; } if((rq->args).lpq.max_verbosity) { opcode = 0x09; } } else { if((rq->type) == YALC_METHOD_BSD) { if(((rq->args).lpq.verbosity) || ((rq->args).lpq.max_verbosity)) { (rq->args).lpq.remove_filter_status = 0; } } } } sz = strlen(rq->queue) + 2; if((rq->argc) && (rq->argv)) { for(i = 0; i < rq->argc; i++) { sz += (1 + strlen((rq->argv)[i])); } } request = dk_new(char,sz); if(request) { sprintf(request, "%c%s", opcode, rq->queue); if((rq->argc) && (rq->argv)) { for(i = 0; i < rq->argc; i++) { strcat(request, " "); strcat(request, ((rq->argv)[i])); } } strcat(request, "\n"); back = 1; sig_int_received = sig_pipe_received = kbhit_received = 0; #if !DK_HAVE_SLEEP if((rq->args).lpq.periodically) { yme_no_sleep(); } #endif do { ende = 0; f = dkapp_fopen(rq->app, tmpfilename, "wb"); if(f) { sock = dktcpip_new(); if(sock) { dktcpip_set_reuse(sock, 1); if(rq->have_timeout) { dktcpip_set_timeout(sock, rq->to); } addr = dktcpip_get_addr(sock, DK_IP_ADDR_LOCAL_WISHED); dktcpip_addr_set_port(addr, rq->o_min, rq->o_max); ymp_configure_local_nic(); if(dktcpipaddr_set_ip_any(addr)) { ymp_local_nic_configured(); addr = dktcpip_get_addr(sock, DK_IP_ADDR_REMOTE_WISHED); dktcpip_addr_set_port(addr, rq->portno, rq->portno); ymp_lookup_remote(rq->host); if(dktcpipaddr_set_ip_byname(addr,rq->host,sock)) { ymp_looked_up_remote(rq->host); ymp_connect(rq->host); if(dktcpip_up(sock)) { ymp_connected(rq->host); sz = strlen(request); ymp_try_send(sz); if(dktcpip_write(sock, request, &sz)) { ymp_have_send(sz); dktcpip_closewrite(sock); ende = 0; while((!ende) && can_continue()) { sz = sizeof(response); ymp_try_receive(sz); if(dktcpip_read(sock, response, &sz)) { ymp_have_received(sz); if(sz > 0) { remove_unprintables(response, &sz); if(sz > 0) { (void)fwrite(response,1,sz,f); } } else { ende = 1; } } else { ende = 1; } } } else { back = 0; yme_error_while_sending(); } ymp_close_conn(); dktcpip_down(sock); ymp_have_closed_conn(); } else { back = 0; yme_failed_to_establish_connection(rq->host); } } else { back = 0; yme_failed_to_find_remote_host(rq->host); } } else { back = 0; yme_failed_to_find_local_network_address(); } dktcpip_delete(sock); } else { back = 0; if(rq->app) { dkapp_err_memory(rq->app, sizeof(dk_tcpip_t), 1); } } fclose(f); if(ende && can_continue()) { f = dkapp_fopen(rq->app, tmpfilename, "r"); if(f) { must_print = 0; if((rq->args).lpq.remove_filter_status) { must_print = 1; } if((rq->args).lpq.remove_done_jobs) { must_print = 1; } if(must_print) { /* zeilenweise einlesen, Zeilen herausfiltern */ ende = 0; while((!ende) && can_continue()) { if(fgets(response,sizeof(response),f)) { must_print = 1; ptr = response; if((response[0] == ' ') || (response[0] == '\t')) { ptr = dkstr_start(response, NULL); if(ptr) { if((rq->args).lpq.remove_filter_status) { if(start_with(ptr, keywords_to_remove)) { must_print = 0; } } } else { ptr = response; } } if(must_print) { if((rq->args).lpq.remove_done_jobs) { if(start_with(ptr, keyword_done)) { must_print = 0; } } } if(must_print) { printf("%s", response); } } else { ende = 1; } } } else { ende = 0; while((!ende) && can_continue()) { sz = fread(response,1,sizeof(response),f); if(sz > 0) { (void)fwrite(response,1,sz,stdout); } else { ende = 1; } } } fclose(f); } else { back = 0; yme_failed_to_read_from_file(tmpfilename); } } } else { back = 0; yme_failed_to_write_to_file(tmpfilename); } if(((rq->args).lpq.periodically) && can_continue()) { t = (rq->args).lpq.period_time; if(t < 1) t = 1; #if DK_HAVE_SLEEP sleep(t); #endif } } while(can_continue() && ((rq->args).lpq.periodically)); dk_delete(request); } else { if(rq->app) { dkapp_err_memory(rq->app, 1, sz); } } } else { yme_could_not_find_temp_filename(); } } else { } dk_delete(tmpfilename); } else { if(rq->app) { dkapp_err_memory(rq->app, 1, mpl); } } return back; } #if DK_HAVE_WINREG_H /** Registry key name to store job ID. */ static char job_number_key[] = { "Software\\DKrause\\Shared\\Yanolc" }; /** Registry value name to store job ID. */ static char job_id_key[] = { "JobId" }; #else /** File name to store job ID. */ static char job_number_file[] = { "lpr-job.id" }; #endif /** Get 3-digit job ID for print job. @param rq YALC request. @return 1 on success, 0 on error. */ static int get_job_number DK_P1(yalc_rq_t *, rq) { int back = 0; char buffer[16]; unsigned u; #if DK_HAVE_WINREG_H HKEY hkTemp; PHKEY phkSubkey; DWORD disp; LONG retval; DWORD dwType, used_sz; #else unsigned long mpl; char *fn; FILE *f; #endif u = rq->job_number = 0; #if DK_HAVE_WINREG_H hkTemp = 0; phkSubkey = &hkTemp; retval = RegCreateKeyExA( HKEY_LOCAL_MACHINE, job_number_key, 0, NULL, REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, phkSubkey, &disp ); if(retval == ERROR_SUCCESS) { back = 1; used_sz = sizeof(buffer); retval = RegQueryValueExA( hkTemp, job_id_key, NULL, &dwType, buffer, &used_sz ); if(retval == ERROR_SUCCESS) { if(dwType == REG_SZ) { if(used_sz < sizeof(buffer)) { buffer[used_sz] = '\0'; } else { buffer[sizeof(buffer)-1] = '\0'; } u = 0; if(sscanf(buffer, "%u", &u) == 1) { rq->job_number = (unsigned short)u; } } } u = (unsigned)(rq->job_number); u++; if(u > 999) { u = 0; } back = 1; sprintf(buffer, "%u", u); retval = RegSetValueExA( hkTemp, job_id_key, 0, REG_SZ, buffer, (strlen(buffer) + 1) ); if(retval != ERROR_SUCCESS) { yme_err_save_jobid(); } RegCloseKey(hkTemp); } else { yme_err_open_jobid_regkey(job_number_key); } #else mpl = dksf_get_maxpathlen(); fn = dk_new(char,mpl); if(fn) { if(dksf_get_tempdir(fn,mpl)) { if(mpl > (strlen(fn) + strlen(job_number_file) + strlen(fnsep))) { strcat(fn, fnsep); strcat(fn, job_number_file); if(rq) { if(rq->app) { f = dkapp_fopen(rq->app, fn, "r"); } else { f = dksf_fopen(fn, "r"); } } else { f = dksf_fopen(fn, "r"); } if(f) { if(fgets(buffer, sizeof(buffer), f)) { if(sscanf(buffer, "%u", &u) == 1) { rq->job_number = u; } } fclose(f); } u = rq->job_number; u++; if(u > 999) u = 0; f = dkapp_fopen(rq->app, fn, "w"); if(f) { fprintf(f, "%u\n", u); back = 1; fclose(f); } } else { yme_file_name_too_long(fn); } } else { yme_could_not_find_temp_directory(); } dk_delete(fn); } else { if(rq->app) { dkapp_err_memory(rq->app, 1, mpl); } } #endif return back; } /** Print on file by submitting an LPR request. @param rq YALC request. @param fn File name. @return 1 on success, 0 on error. */ static int lpr_one_file DK_P2(yalc_rq_t *, rq, char *, fn) { int back = 0; char host_name[128], domain_name[128], response[8192]; #if DK_HAVE_LONG_LONG_INT char ullbuffer[128]; #endif char *short_file_name, *ptr; int flags, ende, x; FILE *f; dk_tcpip_t *sock; dk_ip_addr_t *addr; size_t sz, sz1, sz2; dk_long_long_unsigned_t ctrl_file_length, data_file_length, bytes_transmitted; dk_stat_t *st; ymp_print_one(fn); switch(rq->type) { case YALC_METHOD_RAWTCPIP: case YALC_METHOD_JETDIRECT: { if(rq) { if(rq->app) { f = dkapp_fopen(rq->app, fn, "rb"); } else { f = dksf_fopen(fn, "rb"); } } else { f = dksf_fopen(fn, "rb"); } if(f) { sock = dktcpip_new(); if(sock) { dktcpip_set_reuse(sock, 1); if(rq->have_timeout) { dktcpip_set_timeout(sock, rq->to); } addr = dktcpip_get_addr(sock, DK_IP_ADDR_LOCAL_WISHED); dktcpip_addr_set_port(addr, rq->o_min, rq->o_max); ymp_configure_local_nic(); if(dktcpipaddr_set_ip_any(addr)) { ymp_local_nic_configured(); addr = dktcpip_get_addr(sock, DK_IP_ADDR_REMOTE_WISHED); dktcpip_addr_set_port(addr, rq->portno, rq->portno); ymp_lookup_remote(rq->host); if(dktcpipaddr_set_ip_byname(addr,rq->host,sock)) { ymp_looked_up_remote(rq->host); ymp_connect(rq->host); if(dktcpip_up(sock)) { ymp_connected(rq->host); back = 1; ende = 0; while((!ende) && (can_continue())) { ymp_try_read(fn, sizeof(response)); sz = fread(response,1,sizeof(response),f); ymp_have_read(fn, sz); if(sz > 0) { sz1 = sz; ymp_try_send(sz); if(!dktcpip_write(sock,response,&sz)) { ende = 1; yme_error_while_sending(); } else { ymp_have_send(sz); if(sz1 != sz) { ende = 1; yme_error_while_sending(); } } } else { ende = 1; } } dktcpip_closewrite(sock); ymp_close_conn(); dktcpip_down(sock); ymp_have_closed_conn(); } else { yme_failed_to_establish_connection(rq->host); } } else { yme_failed_to_find_remote_host(rq->host); } } else { yme_failed_to_find_local_network_address(); } dktcpip_delete(sock); } else { if(rq->app) { dkapp_err_memory(rq->app, sizeof(dk_tcpip_t), 1); } } fclose(f); } } break; case YALC_METHOD_LPRNG: case YALC_METHOD_BSD: { f = dkapp_fopen(rq->app, rq->control_file_name, "wb"); if(f) { flags = 0; if(dksf_get_domainname(domain_name, sizeof(domain_name))) { flags |= 1; } if(dksf_get_hostname(host_name, sizeof(host_name))) { char *myptr; flags |= 2; /* 2009-10-01 Shorten host name if necessary and possible. */ if(strlen(host_name) >= 32) { myptr = strchr(host_name, '.'); if(myptr) { *myptr = '\0'; } } } short_file_name = dkstr_rchr(fn, fnsep[0]); if(short_file_name) { short_file_name++; } else short_file_name = fn; if(get_job_number(rq)) { if(flags & 2) { if(strlen(host_name) < 32) { if(rq->user) { if(strlen(rq->user) < 32) { if(flags & 1) { /* 2009-10-01 Append domain name only if the name does not contain the domain name yet. */ if(strchr(host_name, '.') == NULL) { if((strlen(host_name) + strlen(domain_name) + 1) < 32) { flags |= 4; } } } back = 1; /* H */ fprintf(f, "H%s", host_name); if(flags & 4) { fprintf(f, ".%s", domain_name); } fprintf(f, "\n"); /* J */ ptr = (rq->args).lpr.job_title; if(!ptr) { ptr = short_file_name; } if(ptr) { fprintf(f, "J"); x = 0; while(*ptr && (x < 100)) { fprintf(f, "%c", *(ptr++)); x++; } fprintf(f, "\n"); } /* C */ fprintf(f, "C"); ptr = (rq->args).lpr.class_name; if(ptr) { x = 0; while(*ptr && (x < 32)) { fprintf(f, "%c", *(ptr++)); x++; } } else { fprintf(f, "A"); } fprintf(f, "\n"); /* L */ if(!((rq->args).lpr.suppress_header)) { fprintf(f, "L"); if(rq->user) { fprintf(f, "%s", rq->user); } fprintf(f, "\n"); } /* T */ if((rq->args).lpr.job_title) { ptr = (rq->args).lpr.job_title; fprintf(f, "T"); x = 0; while(*ptr && (x < 80)) { fprintf(f, "%c", *(ptr++)); x++; } fprintf(f, "\n"); } /* W */ if((rq->args).lpr.with) { fprintf(f, "W%d\n", (rq->args).lpr.with); } /* I */ if((rq->args).lpr.indent_cols) { fprintf(f, "I%d\n", (rq->args).lpr.indent_cols); } /* A */ if(rq->type == YALC_METHOD_LPRNG) { fprintf(f, "A%s@%s+%u\n", rq->user, host_name, rq->job_number ); } /* P */ fprintf(f, "P%s\n", rq->user); /* Q */ if(rq->type == YALC_METHOD_LPRNG) { } /* R */ if(rq->type == YALC_METHOD_LPRNG) { } /* Z */ if(rq->type == YALC_METHOD_LPRNG) { } /* M */ if((rq->args).lpr.mail_recipient) { fprintf(f, "M%s\n", (rq->args).lpr.mail_recipient); } /* f */ switch((rq->args).lpr.type) { case YALC_TYPE_CIFPLOT: fprintf(f, "c"); break; case YALC_TYPE_DVI : fprintf(f, "d"); break; case YALC_TYPE_PLOT : fprintf(f, "g"); break; case YALC_TYPE_TROFF_N: fprintf(f, "n"); break; case YALC_TYPE_FILTER : fprintf(f, "f"); break; case YALC_TYPE_TROFF_T: fprintf(f, "t"); break; case YALC_TYPE_PR : fprintf(f, "p"); break; case YALC_TYPE_RASTER : fprintf(f, "v"); break; default : fprintf(f, "l"); break; } fprintf(f, "dfA%03u%s", rq->job_number, host_name); if(flags & 4) { fprintf(f, ".%s", domain_name); } fprintf(f, "\n"); /* N */ if(strlen(short_file_name) < 132) { fprintf(f, "N%s\n", short_file_name); } /* U */ fprintf(f, "UdfA%03u%s", rq->job_number, host_name); if(flags & 4) { fprintf(f, ".%s", domain_name); } fprintf(f, "\n"); } else { yme_err_username_too_long(rq->user); } } else { yme_err_no_user_name(); } } else { yme_err_hostname_too_long(host_name); } } else { yme_err_no_hostname(); } } else { yme_failed_to_find_job_number(); } fclose(f); if(back) { back = 0; #if DEBUG #line 5520 "yalc.ctr" #line 5521 "yalc.ctr" #endif ctrl_file_length = data_file_length = ULLZERO; st = dkstat_open(rq->control_file_name); if(st) { ctrl_file_length = dkstat_size(st); dkstat_close(st); st = dkstat_open(fn); if(st) { data_file_length = dkstat_size(st); dkstat_close(st); if(strlen(rq->queue) < (sizeof(response) - 2)) { sprintf(response, "%c%s\n", 0x02, rq->queue); if(data_file_length && ctrl_file_length) { sock = dktcpip_new(); if(sock) { dktcpip_set_reuse(sock, 1); if(rq->have_timeout) { dktcpip_set_timeout(sock, rq->to); } addr = dktcpip_get_addr(sock, DK_IP_ADDR_LOCAL_WISHED); dktcpip_addr_set_port(addr, rq->o_min, rq->o_max); ymp_configure_local_nic(); if(dktcpipaddr_set_ip_any(addr)) { ymp_local_nic_configured(); addr = dktcpip_get_addr(sock, DK_IP_ADDR_REMOTE_WISHED); dktcpip_addr_set_port(addr, rq->portno, rq->portno); ymp_lookup_remote(rq->host); if(dktcpipaddr_set_ip_byname(addr,rq->host,sock)) { ymp_looked_up_remote(rq->host); ymp_connect(rq->host); if(dktcpip_up(sock)) { ymp_connected(rq->host); sz = strlen(response); ymp_try_send(sz); if(dktcpip_write(sock,response,&sz)) { ymp_have_send(sz); if(sz == strlen(response)) { sz = 2; ymp_try_receive(sz); if(dktcpip_read(sock,response,&sz)) { ymp_have_received(sz); if(sz > 0) { if(!response[0]) { if(rq->data_file_first) { /* send data file first */ back = 1; if(back) { #if DK_HAVE_LONG_LONG_INT ull_to_string(ullbuffer, data_file_length); sprintf(response, "%c%s dfA%03u%s", 0x03, ullbuffer, rq->job_number, host_name ); #else sprintf(response, "%c%lu dfA%03u%s", 0x03, data_file_length, rq->job_number, host_name ); #endif if(flags & 4) { strcat(response, "."); strcat(response, domain_name); } strcat(response, "\n"); sz = strlen(response); ymp_try_send(sz); if(dktcpip_write(sock, response, &sz)) { ymp_have_send(sz); if(sz == strlen(response)) { sz = 2; ymp_try_receive(sz); if(dktcpip_read(sock, response, &sz)) { ymp_have_received(sz); if(sz) { if(!response[0]) { if(rq) { if(rq->app) { f = dkapp_fopen(rq->app, fn, "rb"); } else { f = dksf_fopen(fn, "rb"); } } else { f = dksf_fopen(fn, "rb"); } if(f) { bytes_transmitted = data_file_length; while(back && bytes_transmitted && can_continue()) { if(bytes_transmitted > (dk_long_long_unsigned_t)sizeof(response)) { sz = sizeof(response); } else { sz = (size_t)bytes_transmitted; } sz1 = sz; ymp_try_read(fn,sz); sz1 = fread(response,1,sz,f); ymp_have_read(fn,sz1); if(sz1 > 0) { if(sz1 < sz) { back = 0; } sz2 = sz1; ymp_try_send(sz2); if(dktcpip_write(sock,response,&sz2)) { ymp_have_send(sz2); if(sz2 != sz1) { back = 0; yme_error_while_sending(); } /* bytes_transmitted -= ((unsigned long)(sz2)); */ if(bytes_transmitted > (dk_long_long_unsigned_t)sz2) { bytes_transmitted -= ((dk_long_long_unsigned_t)sz2); } else { bytes_transmitted = ULLZERO; } } else { back = 0; yme_error_while_sending(); } } else { back = 0; yme_failed_to_read_from_file(fn); } } if(back) { response[0] = '\0'; sz = 1; ymp_try_send(sz); if(dktcpip_write(sock,response,&sz)) { ymp_have_send(sz); if(sz != 1) { yme_error_while_sending(); } } else { yme_error_while_sending(); } } if(back) { sz = 2; ymp_try_receive(sz); if(dktcpip_read(sock,response,&sz)) { ymp_have_received(sz); if(sz) { if(response[0]) { back = 0; yme_server_does_not_accept_jobs(); } else { } } else { back = 0; yme_error_while_receiving(); } } else { back = 0; yme_error_while_receiving(); } } fclose(f); } else { back = 0; yme_failed_to_read_from_file(fn); } } else { back = 0; yme_server_does_not_accept_jobs(); } } else { back = 0; yme_error_while_receiving(); } } else { back = 0; yme_error_while_receiving(); } } else { back = 0; yme_error_while_sending(); } } else { back = 0; yme_error_while_sending(); } } if(back) { #if DK_HAVE_LONG_LONG_INT ull_to_string(ullbuffer, ctrl_file_length); sprintf(response, "%c%s cfA%03u%s", 0x02, ullbuffer, rq->job_number, host_name ); #else sprintf(response, "%c%lu cfA%03u%s", 0x02, ctrl_file_length, rq->job_number, host_name ); #endif if(flags & 4) { strcat(response, "."); strcat(response, domain_name); } strcat(response, "\n"); sz = strlen(response); ymp_try_send(sz); if(dktcpip_write(sock, response, &sz)) { ymp_have_send(sz); if(sz == strlen(response)) { sz = 2; ymp_try_receive(sz); if(dktcpip_read(sock, response, &sz)) { ymp_have_received(sz); if(sz) { if(!response[0]) { if(rq) { if(rq->app) { f = dkapp_fopen(rq->app, rq->control_file_name, "rb"); } else { f = dksf_fopen(rq->control_file_name, "rb"); } } else { f = dksf_fopen(rq->control_file_name, "rb"); } if(f) { bytes_transmitted = ctrl_file_length; while(back && bytes_transmitted && can_continue()) { if(bytes_transmitted > (dk_long_long_unsigned_t)sizeof(response)) { sz = sizeof(response); } else { sz = (size_t)bytes_transmitted; } sz1 = sz; ymp_try_read(rq->control_file_name,sz); sz1 = fread(response,1,sz,f); ymp_have_read(rq->control_file_name,sz1); if(sz1 > 0) { if(sz1 < sz) { back = 0; } sz2 = sz1; ymp_try_send(sz2); if(dktcpip_write(sock,response,&sz2)) { ymp_have_send(sz2); if(sz2 != sz1) { back = 0; yme_error_while_sending(); } /* bytes_transmitted -= ((unsigned long)(sz2)); */ if(bytes_transmitted > (dk_long_long_unsigned_t)sz2) { bytes_transmitted -= ((dk_long_long_unsigned_t)sz2); } else { bytes_transmitted = ULLZERO; } } else { back = 0; yme_error_while_sending(); } } else { back = 0; yme_failed_to_read_from_file(rq->control_file_name); } } if(back) { response[0] = '\0'; sz = 1; ymp_try_send(sz); if(dktcpip_write(sock,response,&sz)) { ymp_have_send(sz); if(sz != 1) { yme_error_while_sending(); } } else { yme_error_while_sending(); } } if(back) { sz = 2; ymp_try_receive(sz); if(dktcpip_read(sock,response,&sz)) { ymp_have_received(sz); if(sz) { if(response[0]) { back = 0; yme_server_does_not_accept_jobs(); } else { } } else { back = 0; yme_error_while_receiving(); } } else { back = 0; yme_error_while_receiving(); } } fclose(f); } else { back = 0; yme_failed_to_read_from_file(rq->control_file_name); } } else { back = 0; yme_server_does_not_accept_jobs(); } } else { back = 0; yme_error_while_receiving(); } } else { back = 0; yme_error_while_receiving(); } } else { back = 0; yme_error_while_sending(); } } else { back = 0; yme_error_while_sending(); } } } else { /* send control file first */ back = 1; if(back) { #if DK_HAVE_LONG_LONG_INT ull_to_string(ullbuffer, ctrl_file_length); sprintf(response, "%c%s cfA%03u%s", 0x02, ullbuffer, rq->job_number, host_name ); #else sprintf(response, "%c%lu cfA%03u%s", 0x02, ctrl_file_length, rq->job_number, host_name ); #endif if(flags & 4) { strcat(response, "."); strcat(response, domain_name); } strcat(response, "\n"); sz = strlen(response); ymp_try_send(sz); if(dktcpip_write(sock, response, &sz)) { ymp_have_send(sz); if(sz == strlen(response)) { sz = 2; ymp_try_receive(sz); if(dktcpip_read(sock, response, &sz)) { ymp_have_received(sz); if(sz) { if(!response[0]) { if(rq) { if(rq->app) { f = dkapp_fopen(rq->app, rq->control_file_name, "rb"); } else { f = dksf_fopen(rq->control_file_name, "rb"); } } else { f = dksf_fopen(rq->control_file_name, "rb"); } if(f) { bytes_transmitted = ctrl_file_length; while(back && bytes_transmitted && can_continue()) { if(bytes_transmitted > (dk_long_long_unsigned_t)sizeof(response)) { sz = sizeof(response); } else { sz = (size_t)bytes_transmitted; } sz1 = sz; ymp_try_read(rq->control_file_name, sz); sz1 = fread(response,1,sz,f); ymp_have_read(rq->control_file_name, sz1); if(sz1 > 0) { if(sz1 < sz) { back = 0; } sz2 = sz1; ymp_try_send(sz2); if(dktcpip_write(sock,response,&sz2)) { ymp_have_send(sz2); if(sz2 != sz1) { back = 0; yme_error_while_sending(); } /* bytes_transmitted -= ((unsigned long)(sz2)); */ if(bytes_transmitted > (dk_long_long_unsigned_t)sz2) { bytes_transmitted -= ((dk_long_long_unsigned_t)sz2); } else { bytes_transmitted = ULLZERO; } } else { back = 0; yme_error_while_sending(); } } else { back = 0; yme_failed_to_read_from_file(rq->control_file_name); } } if(back) { response[0] = '\0'; sz = 1; ymp_try_send(sz); if(dktcpip_write(sock,response,&sz)) { ymp_have_send(sz); if(sz != 1) { yme_error_while_sending(); } } else { yme_error_while_sending(); } } if(back) { sz = 2; ymp_try_receive(sz); if(dktcpip_read(sock,response,&sz)) { ymp_have_received(sz); if(sz) { if(response[0]) { back = 0; yme_server_does_not_accept_jobs(); } else { } } else { back = 0; yme_error_while_receiving(); } } else { back = 0; yme_error_while_receiving(); } } fclose(f); } else { back = 0; yme_failed_to_read_from_file(rq->control_file_name); } } else { back = 0; yme_server_does_not_accept_jobs(); } } else { back = 0; yme_error_while_receiving(); } } else { back = 0; yme_error_while_receiving(); } } else { back = 0; yme_error_while_sending(); } } else { back = 0; yme_error_while_sending(); } } if(back) { #if DK_HAVE_LONG_LONG_INT ull_to_string(ullbuffer, data_file_length); sprintf(response, "%c%s dfA%03u%s", 0x03, ullbuffer, rq->job_number, host_name ); #else sprintf(response, "%c%lu dfA%03u%s", 0x03, data_file_length, rq->job_number, host_name ); #endif if(flags & 4) { strcat(response, "."); strcat(response, domain_name); } strcat(response, "\n"); sz = strlen(response); ymp_try_send(sz); if(dktcpip_write(sock, response, &sz)) { ymp_have_send(sz); if(sz == strlen(response)) { sz = 2; ymp_try_receive(sz); if(dktcpip_read(sock, response, &sz)) { ymp_have_received(sz); if(sz) { if(!response[0]) { if(rq) { if(rq->app) { f = dkapp_fopen(rq->app, fn, "rb"); } else { f = dksf_fopen(fn, "rb"); } } else { f = dksf_fopen(fn, "rb"); } if(f) { bytes_transmitted = data_file_length; while(back && bytes_transmitted && can_continue()) { if(bytes_transmitted > (dk_long_long_unsigned_t)sizeof(response)) { sz = sizeof(response); } else { sz = (size_t)bytes_transmitted; } sz1 = sz; ymp_try_read(fn, sz); sz1 = fread(response,1,sz,f); ymp_have_read(fn, sz1); if(sz1 > 0) { if(sz1 < sz) { back = 0; } sz2 = sz1; ymp_try_send(sz2); if(dktcpip_write(sock,response,&sz2)) { ymp_have_send(sz2); if(sz2 != sz1) { back = 0; yme_error_while_sending(); } /* bytes_transmitted -= ((unsigned long)(sz2)); */ if(bytes_transmitted > (dk_long_long_unsigned_t)sz2) { bytes_transmitted -= ((dk_long_long_unsigned_t)sz2); } else { bytes_transmitted = ULLZERO; } } else { back = 0; yme_error_while_sending(); } } else { back = 0; yme_failed_to_read_from_file(fn); } } if(back) { response[0] = '\0'; sz = 1; ymp_try_send(sz); if(dktcpip_write(sock,response,&sz)) { ymp_have_send(sz); if(sz != 1) { yme_error_while_sending(); } } else { yme_error_while_sending(); } } if(back) { sz = 2; ymp_try_receive(sz); if(dktcpip_read(sock,response,&sz)) { ymp_have_received(sz); if(sz) { if(response[0]) { back = 0; yme_server_does_not_accept_jobs(); } else { } } else { back = 0; yme_error_while_receiving(); } } else { back = 0; yme_error_while_receiving(); } } fclose(f); } else { back = 0; yme_failed_to_read_from_file(fn); } } else { back = 0; yme_server_does_not_accept_jobs(); } } else { back = 0; yme_error_while_receiving(); } } else { back = 0; yme_error_while_receiving(); } } else { back = 0; yme_error_while_sending(); } } else { back = 0; yme_error_while_sending(); } } } } else { yme_server_does_not_accept_jobs(); } } else { yme_error_while_receiving(); } } else { yme_error_while_receiving(); } } else { yme_error_while_sending(); } } else { yme_error_while_sending(); } } else { if(rq->host) { yme_failed_to_establish_connection(rq->host); } } } else { if(rq->host) { yme_failed_to_find_remote_host(rq->host); } } } else { yme_failed_to_find_local_network_address(); } dktcpip_delete(sock); } else { if(rq->app) { dkapp_err_memory(rq->app, sizeof(dk_tcpip_t), 1); } } } else { yme_illegal_file_length(ctrl_file_length, data_file_length); } } else { yme_queue_name_too_long(rq->queue); } } else { yme_stat_failed_for_file(fn); } } else { yme_stat_failed_for_file(rq->control_file_name); } } else { /* yme_failed_to_find_job_number(); */ } } else { yme_failed_to_write_to_file(rq->control_file_name); } } break; } ymp_printed_one(fn); return back; } /** Run LPR request. @param rq YALC request. @return 1 on success, 0 on error. */ static int run_lpr DK_P1(yalc_rq_t *, rq) { int back = 0; unsigned long mpl; char response[8192]; char *pchr, *tmpfn1, *tmpfn2, *tmpfn3; size_t sz; int ende, i, j; FILE *f; #if DK_HAVE_FEATURE_BACKSLASH dk_fne_t *fne; #endif mpl = dksf_get_maxpathlen(); tmpfn1 = dk_new(char,mpl); tmpfn2 = dk_new(char,mpl); tmpfn3 = dk_new(char,mpl); sig_int_received = sig_pipe_received = kbhit_received = 0; if(tmpfn1 && tmpfn2 && tmpfn3) { if((rq->args).lpr.number_of_copies == 0) { (rq->args).lpr.number_of_copies = 1; } rq->control_file_name = tmpfn2; if(rq->app) { if(dkapp_tmpnam(rq->app,tmpfn1,mpl)) { if(dkapp_tmpnam(rq->app,tmpfn2,mpl)) { if(!((rq->argc) && (rq->argv))) { f = dkapp_fopen(rq->app, tmpfn1, "wb"); if(f) { rq->argv = &tmpfn1; rq->argc = 1; ende = 0; while((!ende) && (can_continue())) { sz = fread(response,1,sizeof(response),stdin); if(sz > 0) { if(!(fwrite(response,1,sz,f) == sz)) { ende = 1; } } else { ende = 1; } } fclose(f); } else { yme_failed_to_write_to_file(tmpfn1); } } if((rq->argc) && (rq->argv)) { for(i = 0; i < (rq->argc); i++) { pchr = ((rq->argv)[i]); if(strlen(pchr) < mpl) { strcpy(tmpfn3, pchr); dksf_correct_fnsep(tmpfn3); #if DK_HAVE_FEATURE_BACKSLASH if (dksf_must_expand_filename(tmpfn3)) { fne = dkfne_open(tmpfn3, 1, 0); if(fne) { back = 1; while(dkfne_next(fne)) { for(j = 0; j < ((rq->args).lpr.number_of_copies); j++) { if(!lpr_one_file(rq, dkfne_get_fullname(fne))) { back = 0; } } } dkfne_close(fne); } else { yme_failed_to_open_filename_expander(tmpfn3); } } else { back = 1; for(j = 0; j < ((rq->args).lpr.number_of_copies); j++) { if(!lpr_one_file(rq, tmpfn3)) { back = 0; } } } #else back = 1; for(j = 0; j < ((rq->args).lpr.number_of_copies); j++) { if(!lpr_one_file(rq, tmpfn3)) { back = 0; } } #endif } else { yme_file_name_too_long(pchr); } } } else { yme_no_data_to_print(); } } else { yme_could_not_find_temp_filename(); } } else { yme_could_not_find_temp_filename(); } } else { yme_incomplete_configuration(); } } else { if(rq->app) { dkapp_err_memory(rq->app, sizeof(char), mpl); } } if(tmpfn1) { dk_delete(tmpfn1); } if(tmpfn2) { dk_delete(tmpfn2); } if(tmpfn3) { dk_delete(tmpfn3); } return back; } /** SNMP community: public. */ static char str_snmp_comm_public[] = { "public" }; /** SNMP version: 1. */ static char str_snmp_vers_1[] = { "1" }; /** Run snmpyalc request (SNMP status). @param rq YALC request. @return 1 on success, 0 on error. */ static int run_snmp_status DK_P1(yalc_rq_t *,rq) { int back = 0; dk_stream_t *cfg_stream; if((rq->app) && (rq->snmp_host) && (rq->snmp_type)) { /* cfg_stream = dkapp_read_file(rq->app, "snmp.cfg"); */ cfg_stream = yalc_snmp_cfg_open(rq); if(cfg_stream) { back = run_snmp_request( rq, rq->snmp_host, ((rq->snmp_comm) ? (rq->snmp_comm) : str_snmp_comm_public), rq->snmp_type, cfg_stream, ((rq->snmp_vers) ? (rq->snmp_vers) : str_snmp_vers_1) ); dkstream_close(cfg_stream); } else { yme_snmp_failed_to_open_configuration(); } } else { if(!(rq->snmp_host)) { yme_snmp_no_host(); } if(!(rq->snmp_type)) { yme_snmp_no_type(); } } return back; } /** Run klpinfo request (SNMP short). @param rq YALC request. @return 1 on success, NULL on error. */ static int run_snmp_short DK_P1(yalc_rq_t *,rq) { int back = 0; dk_stream_t *cfg_stream; if((rq->app) && (rq->snmp_host) && (rq->snmp_type)) { /* cfg_stream = dkapp_read_file(rq->app, "snmp.cfg"); */ cfg_stream = yalc_snmp_cfg_open(rq); if(cfg_stream) { back = run_snmp_short_request( rq, rq->snmp_host, ((rq->snmp_comm) ? (rq->snmp_comm) : str_snmp_comm_public), rq->snmp_type, ((rq->snmp_vers) ? (rq->snmp_vers) : str_snmp_vers_1) ); dkstream_close(cfg_stream); } else { yme_snmp_failed_to_open_configuration(); } } else { if(!(rq->snmp_host)) { yme_snmp_no_host(); } if(!(rq->snmp_type)) { yme_snmp_no_type(); } } return back; } int yalc_run DK_P1(yalc_rq_t *, rq) { int back = 0; #ifdef SIGINT dk_signal_disp_t old_disp_int; #endif #ifdef SIGPIPE dk_signal_disp_t old_disp_pipe; #endif char *x; if(rq) { ym_init(rq->app); #ifdef SIGINT old_disp_int = dksignal_set(SIGINT, sig_int_handler); #endif #ifdef SIGPIPE old_disp_pipe = dksignal_set(SIGPIPE, sig_pipe_handler); #endif #if DK_HAVE_WINREG_H regkey_open(rq); #endif rq->cfg_file = NULL; rq->read_cfg_res = 1; rq->cfg_file = (void *)read_cfg(rq); rq->queue = NULL; rq->host = NULL; rq->dev = NULL; rq->user = NULL; rq->data_file_first = 0; rq->printer_from_env = NULL; rq->type = YALC_METHOD_UNKNOWN; rq->portno = 0; rq->o_min = 0; rq->o_max = 0; rq->xuser_allowed = 0; ymp_going_to_complete_request(); if(complete_request(rq)) { ymp_request_completed(); #if DEBUG /* print_cfg((yalc_cfg *)(rq->cfg_file), stdout); */ printf( "Readcfg: %d\n", rq->read_cfg_res); if(rq->printer_name) { printf("Printer: %s\n", rq->printer_name); } if(rq->dev) { printf("Device: %s\n", rq->dev); } if(rq->queue) { printf("Queue: %s\n", rq->queue); } if(rq->host) { printf("Host: %s\n", rq->host); } printf( "Type: %d\n", rq->type); printf( "Port: %u\n", ((unsigned)(rq->portno))); printf( "Origin: %u %u\n", ((unsigned)(rq->o_min)), ((unsigned)(rq->o_max)) ); printf( "Timeout: %d %lf\n", rq->have_timeout, rq->to); printf( "Xu: %d\n", rq->xuser_allowed); printf( "User: %s\n", ((rq->user) ? (rq->user) : ("-")) ); #endif switch(rq->cmd) { case YALC_OP_LPR : { switch(rq->type) { case YALC_METHOD_RAWTCPIP: case YALC_METHOD_JETDIRECT : { if((rq->dev) && (rq->host) && (rq->app)) { back = run_lpr(rq); } } break; case YALC_METHOD_LPRNG: case YALC_METHOD_BSD: { if((rq->dev) && (rq->queue) && (rq->host) && (rq->app)) { back = run_lpr(rq); } } break; default: { yme_requires_type_rjlb(); } break; } } break; case YALC_OP_LPQ : { switch(rq->type) { case YALC_METHOD_LPRNG: case YALC_METHOD_BSD: { if((rq->dev) && (rq->queue) && (rq->host) && (rq->app)) { back = run_lpq(rq); } } break; default : { yme_requires_type_lb(); } break; } } break; case YALC_OP_LPRM : { switch(rq->type) { case YALC_METHOD_LPRNG: case YALC_METHOD_BSD: { if((rq->queue) && (rq->host) && (rq->user) && (rq->app)) { if(rq->dev) { back = run_lprm(rq); } } } break; default : { yme_requires_type_lb(); } break; } } break; case YALC_OP_LPC : { switch(rq->type) { case YALC_METHOD_LPRNG: case YALC_METHOD_BSD: { if((rq->queue) && (rq->host) && (rq->user) && (rq->app)) { if(rq->dev) { back = run_lpc(rq); } } else { yme_incomplete_configuration(); } } break; default: { yme_requires_type_lb(); } break; } } break; case YALC_OP_SNMP_STATUS: { (rq->args).snmp.output_found = 0; back = run_snmp_status(rq); if((rq->args).snmp.force_output) { if(!((rq->args).snmp.output_found)) { printf("-\n"); (rq->args).snmp.output_found = 1; } } } break; case YALC_OP_SNMP_SHORT: { (rq->args).snmp.output_found = 0; back = run_snmp_short(rq); if((rq->args).snmp.force_output) { if(!((rq->args).snmp.output_found)) { printf("-\n"); (rq->args).snmp.output_found = 1; } } } break; } } else { yme_failed_to_complete_request(); } #if DK_HAVE_WINREG_H regkey_close(rq); #endif if(rq->cfg_file) { forget_cfg(rq->cfg_file); rq->cfg_file = NULL; } x = rq->user; if(x) { dk_delete(x); } rq->user = NULL; x = rq->queue; if(x) { dk_delete(x); } rq->queue = NULL; x = rq->host; if(x) { dk_delete(x); } rq->host = NULL; x = rq->dev; if(x) { dk_delete(x); } rq->dev = NULL; x = rq->printer_from_env; if(x) { dk_delete(x); } rq->printer_from_env = NULL; #ifdef SIGINT (void)dksignal_set(SIGINT, old_disp_int); #endif #ifdef SIGPIPE (void)dksignal_set(SIGPIPE, old_disp_pipe); #endif } else { yme_incomplete_configuration(); } return back; } /** Yanolc version text. */ char *yalc_version[] = { "", "yanolc - Yet ANOther Lpr(ng) Client (klpr/klq/klprm/klpc), version " VERSNUMB, "Copyright (C) 2001-2010 - Dipl.-Ing. Dirk Krause", "http://dktools.sourceforge.net/yanolc.html", "", "Redistribution and use in source and binary forms, with or without", "modification, are permitted provided that the following conditions are met:", "* Redistributions of source code must retain the above copyright notice, this", " list of conditions and the following disclaimer.", "* Redistributions in binary form must reproduce the above copyright notice,", " this list of conditions and the following disclaimer in the documentation", " and/or other materials provided with the distribution.", "* Neither the name of the Dirk Krause nor the names of other contributors may", " be used to endorse or promote products derived from this software without", " specific prior written permission.", "THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\"", "AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE", "IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE", "ARE DISCLAIMED.", "IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY", "DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES", "(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;", "LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND", "ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT", "(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS", "SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.", NULL }; char **yalc_get_version DK_P0() { return yalc_version; }