1 /*
2 	WARNING: This file was generated by the dkct program (see
3 	http://dktools.sourceforge.net/ for details).
4 	Changes you make here will be lost if dkct is run again!
5 	You should modify the original source and run dkct on it.
6 	Original source: dk3print.ctr
7 */
8 
9 /*
10 Copyright (C) 2013-2021, Dirk Krause
11 
12 Redistribution and use in source and binary forms, with or without
13 modification, are permitted provided that the following conditions are met:
14 
15 * Redistributions of source code must retain the above copyright notice,
16   this list of conditions and the following disclaimer.
17 * Redistributions in binary form must reproduce the above opyright notice,
18   this list of conditions and the following disclaimer in the documentation
19   and/or other materials provided with the distribution.
20 * Neither the name of the author nor the names of contributors may be used
21   to endorse or promote products derived from this software without specific
22   prior written permission.
23 
24 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
25 AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
26 IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
27 ARE DISCLAIMED.
28 IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
29 DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
30 (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
31 LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
32 ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
33 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
34 THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
35 */
36 
37 /**	@file dk3print.c The dk3print module.
38 */
39 
40 
41 
42 
43 #include <libdk3c/dk3all.h>
44 #include <wprclean/dk3print.h>
45 #include <wprclean/dk3prcfg.h>
46 #include <wprclean/dk3prreq.h>
47 #include <libdk3c/dk3unused.h>
48 
49 
50 
51 
52 
53 
54 
55 /**	Keywords used by the module, not localized.
56 */
57 static dkChar const * const dk3print_nl[] = {
58 /* 0 */
59 dkT("dk3print.conf"),
60 
61 /* 1 */
62 dkT("dk3print.str"),
63 
64 /* 2 */
65 dkT("PS"),
66 
67 /* 3 */
68 dkT("PostScript"),
69 
70 /* 4 */
71 dkT("Ghostscript PDF"),
72 
73 /* 5 */
74 dkT("/print/ps/level"),
75 
76 /* 6 */
77 dkT("%d"),
78 
79 NULL
80 
81 };
82 
83 
84 
85 /**	Texts used by the module, normaly replaced by localized texts.
86 */
87 static dkChar const * const dk3print_msg[] = {
88 /* 0 */
89 dkT("PRINTER:"),
90 
91 /* 1 */
92 dkT("PRIMARY CONFIGURATION:"),
93 
94 /* 2 */
95 dkT("SECONDARY CONFIGURATION:"),
96 
97 /* 3 */
98 dkT("Printer type:    "),
99 
100 /* 4 */
101 dkT("Host:            "),
102 
103 /* 5 */
104 dkT("Queue:           "),
105 
106 /* 6 */
107 dkT("Port:            "),
108 
109 /* 7 */
110 dkT("Connect timeout: "),
111 
112 /* 8 */
113 dkT("Send timeout:    "),
114 
115 /* 9 */
116 dkT("Receive timeout: "),
117 
118 /* 10 */
119 dkT("PS level:        "),
120 
121 /* 11 */
122 dkT("Default:         "),
123 
124 /* 12 */
125 dkT("SNMP host:       "),
126 
127 /* 13 */
128 dkT("SNMP community:  "),
129 
130 /* 14 */
131 dkT("SNMP version:    "),
132 
133 /* 15 */
134 dkT("Orderly release: "),
135 
136 /* 16 */
137 dkT("unknown"),
138 
139 /* 17 */
140 dkT("Windows"),
141 
142 /* 18 */
143 dkT("Socket"),
144 
145 /* 19 */
146 dkT("LPD"),
147 
148 /* 20 */
149 dkT("LPRng"),
150 
151 /* 21 */
152 dkT("yes"),
153 
154 /* 22 */
155 dkT("no"),
156 
157 /* 23 */
158 dkT("1"),
159 
160 /* 24 */
161 dkT("2c"),
162 
163 /* 25 */
164 dkT("2p"),
165 
166 /* 26 */
167 dkT("3"),
168 
169 /* 27 */
170 dkT("Missing closing bracket ']'!"),
171 
172 /* 28 */
173 dkT("Keyword \""),
174 
175 /* 29 */
176 dkT("\" not allowed here, must be \"host\" or \"printer\"!"),
177 
178 /* 30 */
179 dkT("Missing name for printer or host!"),
180 
181 /* 31 */
182 dkT("Printer \""),
183 
184 /* 32 */
185 dkT("\" already exists!"),
186 
187 /* 33 */
188 dkT("Printer alias \""),
189 
190 /* 34 */
191 dkT("\" already exists!"),
192 
193 /* 35 */
194 dkT("Option \""),
195 
196 /* 36 */
197 dkT("\" requires an argument!"),
198 
199 /* 37 */
200 dkT("Queue type is already set!"),
201 
202 /* 38 */
203 dkT("Unknown print queue type \""),
204 
205 /* 39 */
206 dkT("\"!"),
207 
208 /* 40 */
209 dkT("Overwriting host name \""),
210 
211 /* 41 */
212 dkT("\"!"),
213 
214 /* 42 */
215 dkT("Option \""),
216 
217 /* 43 */
218 dkT("\" invalid for printer type!"),
219 
220 /* 44 */
221 dkT("Overwriting queue name \""),
222 
223 /* 45 */
224 dkT("\"!"),
225 
226 /* 46 */
227 dkT("Overwriting port number "),
228 
229 /* 47 */
230 dkT("!"),
231 
232 /* 48 */
233 dkT("Numeric overflow!"),
234 
235 /* 49 */
236 dkT("Illegal PS level \""),
237 
238 /* 50 */
239 dkT("\", must be 2 or 3!"),
240 
241 /* 51 */
242 dkT("Overwriting SNMP host \""),
243 
244 /* 52 */
245 dkT("\"!"),
246 
247 /* 53 */
248 dkT("Overwriting SNMP community \""),
249 
250 /* 54 */
251 dkT("\"!"),
252 
253 /* 55 */
254 dkT("Overwriting SNMP version!"),
255 
256 /* 56 */
257 dkT("Unknown SNMP version \""),
258 
259 /* 57 */
260 dkT("\"!"),
261 
262 /* 58 */
263 dkT("Overwriting receive timeout \""),
264 
265 /* 59 */
266 dkT("\"!"),
267 
268 /* 60 */
269 dkT("Overwriting send timeout \""),
270 
271 /* 61 */
272 dkT("\"!"),
273 
274 /* 62 */
275 dkT("Overwriting connect timeout \""),
276 
277 /* 63 */
278 dkT("\"!"),
279 
280 /* 64 */
281 dkT("Unknown configuration option \""),
282 
283 /* 65 */
284 dkT("\"!"),
285 
286 /* 66 */
287 dkT("Print host \""),
288 
289 /* 67 */
290 dkT("\" already exists!"),
291 
292 /* 68 */
293 dkT("Print host alias \""),
294 
295 /* 69 */
296 dkT("\" already exists!"),
297 
298 /* 70 */
299 dkT("Illegal encoding \""),
300 
301 /* 71 */
302 dkT("\" for LPD protocol!"),
303 
304 /* 72 */
305 dkT("Line outside scope, not belonging to printer or host!"),
306 
307 NULL
308 
309 };
310 
311 
312 
313 void
dk3print_win_det_cleanup(dk3_printer_windows_details_t * ptr)314 dk3print_win_det_cleanup(dk3_printer_windows_details_t *ptr)
315 {
316 
317   if(ptr) {
318   }
319 
320 }
321 
322 
323 
324 void
dk3print_lprng_det_cleanup(dk3_printer_lprng_details_t * ptr)325 dk3print_lprng_det_cleanup(dk3_printer_lprng_details_t *ptr)
326 {
327 
328   if(ptr) {
329     dk3_release(ptr->hostname);
330     dk3_release(ptr->queuename);
331   }
332 
333 }
334 
335 
336 
337 void
dk3print_socket_det_cleanup(dk3_printer_socket_t * ptr)338 dk3print_socket_det_cleanup(dk3_printer_socket_t *ptr)
339 {
340 
341   if(ptr) {
342     dk3_release(ptr->hostname);
343     ptr->portno = 0;
344     ptr->ordrel = 0x00;
345   }
346 
347 }
348 
349 
350 
351 void
dk3print_det_cleanup(int tp,dk3_printer_details_t * ptr)352 dk3print_det_cleanup(int tp, dk3_printer_details_t *ptr)
353 {
354 
355   if(ptr) {
356     switch(tp) {
357       case DK3_PRINTER_TYPE_WINDOWS: {
358         dk3print_win_det_cleanup(&(ptr->win));
359       } break;
360       case DK3_PRINTER_TYPE_SOCKET: {
361         dk3print_socket_det_cleanup(&(ptr->sock));
362       } break;
363       case DK3_PRINTER_TYPE_LPD: {
364         dk3print_lprng_det_cleanup(&(ptr->lprng));
365       } break;
366       case DK3_PRINTER_TYPE_LPRNG: {
367         dk3print_lprng_det_cleanup(&(ptr->lprng));
368       } break;
369     }
370   }
371 
372 }
373 
374 
375 
376 void
dk3print_printer_delete(dk3_printer_t * ptr)377 dk3print_printer_delete(dk3_printer_t *ptr)
378 {
379 
380   if(ptr) {
381     dk3print_det_cleanup(ptr->t_p, &(ptr->det_p));
382     dk3print_det_cleanup(ptr->t_s, &(ptr->det_s));
383     dk3_release(ptr->name);
384     dk3_release(ptr->h_snmp);
385     dk3_release(ptr->c_snmp);
386     dk3_delete(ptr);
387   }
388 }
389 
390 
391 
392 dk3_printer_t *
dk3print_printer_new(dk3_print_conf_t * pc,dkChar const * name)393 dk3print_printer_new(dk3_print_conf_t *pc, dkChar const *name)
394 {
395   dk3_printer_t		*back = NULL;
396   if((pc) && (name)) {
397     back =
398     (dk3_printer_t *)dk3sto_it_find_like(pc->iPrinters, (void *)name, 1);
399     if(!(back)) {
400       back = dk3_new_app(dk3_printer_t,1,pc->app);
401       if(back) {
402         back->name = NULL;
403 	back->h_snmp = NULL;
404 	back->c_snmp = 0;
405 	back->t_p = DK3_PRINTER_TYPE_NONE;
406 	back->t_s = DK3_PRINTER_TYPE_NONE;
407 	back->v_snmp = DK3_SNMP_VERSION_UNKNOWN;
408 	back->ps = 0;
409 	back->name = dk3str_dup_app(name, pc->app);
410 	if(back->name) {
411 	  if(!dk3sto_add(pc->sPrinters, back)) {
412 	    dk3print_printer_delete(back);
413 	    back = NULL;
414 	  }
415 	} else {
416 	  dk3print_printer_delete(back);
417 	  back = NULL;
418 	}
419       }
420     }
421     if(back) {
422       if(!(pc->defPrinter)) {
423         pc->defPrinter = back;
424       }
425     }
426   }
427   return back;
428 }
429 
430 
431 
432 void
dk3print_alias_delete(dk3_printer_alias_t * ptr)433 dk3print_alias_delete(dk3_printer_alias_t *ptr)
434 {
435 
436   if(ptr) {
437     dk3_release(ptr->name);
438     ptr->printer = NULL;
439     dk3_delete(ptr);
440   }
441 
442 }
443 
444 
445 
446 void
dk3print_host_delete(dk3_print_host_t * ptr)447 dk3print_host_delete(dk3_print_host_t *ptr)
448 {
449 
450   if(ptr) {
451     dk3_release(ptr->name);
452     dk3_delete(ptr);
453   }
454 
455 }
456 
457 
458 
459 dk3_print_host_t *
dk3print_host_new(dk3_print_conf_t * pc,dkChar const * name)460 dk3print_host_new(dk3_print_conf_t *pc, dkChar const *name)
461 {
462   dk3_print_host_t	*back = NULL;
463   if((pc) && (name)) {
464     back =
465     (dk3_print_host_t *)dk3sto_it_find_like(pc->iPrintHosts, (void *)name, 1);
466     if(!(back)) {
467       back = dk3_new_app(dk3_print_host_t,1,pc->app);
468       if(back) {
469         back->name = NULL;
470 	/* Further initialization. */
471 	back->to_c = -1.0;
472 	back->to_r = -1.0;
473 	back->to_s = -1.0;
474 	back->enc  = DK3_ENCODING_UTF8;
475 	/* Save name. */
476 	back->name = dk3str_dup_app(name, pc->app);
477 	if(back->name) {
478 	  /* Add to configuration. */
479 	  if(!dk3sto_add(pc->sPrintHosts, back)) {
480 	    dk3print_host_delete(back);
481 	    back = NULL;
482 	  }
483 	} else {
484 	  dk3print_host_delete(back);
485 	  back = NULL;
486 	}
487       }
488     }
489     if(back) {
490       if(!(pc->defHost)) {
491         pc->defHost = back;
492       }
493     }
494   }
495   return back;
496 }
497 
498 
499 
500 void
dk3print_host_alias_delete(dk3_print_host_alias_t * ptr)501 dk3print_host_alias_delete(dk3_print_host_alias_t *ptr)
502 {
503 
504   if(ptr) {
505     dk3_release(ptr->name);
506     ptr->host = NULL;
507     dk3_delete(ptr);
508   }
509 
510 }
511 
512 
513 
514 void
dk3print_conf_delete(dk3_print_conf_t * pc)515 dk3print_conf_delete(dk3_print_conf_t *pc)
516 {
517   void		*vptr;	/* Current element to delete. */
518 
519 
520   if(pc) {
521     pc->defPrinter = NULL;
522     pc->defHost = NULL;
523     if(pc->sHostAliases) {
524       if(pc->iHostAliases) {
525         dk3sto_it_reset(pc->iHostAliases);
526 	while(NULL != (vptr = dk3sto_it_next(pc->iHostAliases))) {
527 	  dk3print_host_alias_delete((dk3_print_host_alias_t *)vptr);
528 	}
529 	dk3sto_it_close(pc->iHostAliases);
530       }
531       dk3sto_close(pc->sHostAliases);
532     } pc->sHostAliases = NULL; pc->iHostAliases = NULL;
533     if(pc->sPrintHosts) {
534       if(pc->iPrintHosts) {
535         dk3sto_it_reset(pc->iPrintHosts);
536 	while(NULL != (vptr = dk3sto_it_next(pc->iPrintHosts))) {
537 	  dk3print_host_delete((dk3_print_host_t *)vptr);
538 	}
539 	dk3sto_it_close(pc->iPrintHosts);
540       }
541       dk3sto_close(pc->sPrintHosts);
542     } pc->sPrintHosts = NULL; pc->iPrintHosts = NULL;
543     if(pc->sPrintAliases) {
544       if(pc->iPrintAliases) {
545         dk3sto_it_reset(pc->iPrintAliases);
546 	while(NULL != (vptr = dk3sto_it_next(pc->iPrintAliases))) {
547 	  dk3print_alias_delete((dk3_printer_alias_t *)vptr);
548 	}
549 	dk3sto_it_close(pc->iPrintAliases);
550       }
551       dk3sto_close(pc->sPrintAliases);
552     } pc->sPrintAliases = NULL; pc->iPrintAliases = NULL;
553     if(pc->sPrinters) {
554       if(pc->iPrinters) {
555         dk3sto_it_reset(pc->iPrinters);
556 	while(NULL != (vptr = dk3sto_it_next(pc->iPrinters))) {
557 	  dk3print_printer_delete((dk3_printer_t *)vptr);
558 	}
559 	dk3sto_it_close(pc->iPrinters);
560       }
561       dk3sto_close(pc->sPrinters);
562     } pc->sPrinters = NULL; pc->iPrinters = NULL;
563     pc->app = NULL;
564     pc->msg = NULL;
565     dk3_delete(pc);
566   }
567 }
568 
569 
570 
571 /**	Compare two printers by name.
572 	@param	l	Left object.
573 	@param	r	Right object or name.
574 	@param	cr	Comparison criteria (0=printer/printer, 1=printer/name).
575 	@return	Comparison result.
576 */
577 static
578 int
dk3print_compare_printer(void const * l,void const * r,int cr)579 dk3print_compare_printer(void const *l, void const *r, int cr)
580 {
581   int		 back = 0;
582   dk3_printer_t const	*pl;		/* Pointer to left printer. */
583   dk3_printer_t const	*pr;		/* Pointer to right printer. */
584   dkChar const		*n;		/* Pointer to right name. */
585   if(l) {
586     if(r) {
587       pl = (dk3_printer_t const *)l;
588       switch(cr) {
589         case 1: {
590 	  n  = (dkChar const *)r;
591 	  if(pl->name) {
592 	    back = dk3str_cmp(pl->name, n);
593 	    if(back < 0) back = -1;
594 	    if(back > 0) back =  1;
595 	  } else {
596 	    back = -1;
597 	  }
598 	} break;
599 	default: {
600 	  pr = (dk3_printer_t const *)r;
601 	  if(pl->name) {
602 	    if(pr->name) {
603 	      back = dk3str_cmp(pl->name, pr->name);
604 	      if(back < 0) back = -1;
605 	      if(back > 0) back =  1;
606 	    } else {
607 	      back = 1;
608 	    }
609 	  } else {
610 	    if(pr->name) {
611 	      back = -1;
612 	    }
613 	  }
614 	} break;
615       }
616     } else {
617       back = 1;
618     }
619   } else {
620     if(r) {
621       back = -1;
622     }
623   }
624   return back;
625 }
626 
627 
628 
629 /**	Compare two printer aliases by name.
630 	@param	l	Left object.
631 	@param	r	Right object or name.
632 	@param	cr	Comparison criteria (0=alias/alias, 1=alias/name).
633 	@return	Comparison result.
634 */
635 static
636 int
dk3print_compare_print_alias(void const * l,void const * r,int cr)637 dk3print_compare_print_alias(void const *l, void const *r, int cr)
638 {
639   int				 back = 0;
640   dk3_printer_alias_t const	*pl;		/* Left printer alias. */
641   dk3_printer_alias_t const	*pr;		/* Right printer alias. */
642   dkChar const			*n;		/* Right alias name. */
643   if(l) {
644     if(r) {
645       pl = (dk3_printer_alias_t const *)l;
646       switch(cr) {
647         case 1: {
648 	  n = (dkChar const *)r;
649 	  if(pl->name) {
650 	    back = dk3str_cmp(pl->name, n);
651 	    if(back < 0) back = -1;
652 	    if(back > 0) back =  1;
653 	  } else {
654 	    back = -1;
655 	  }
656 	} break;
657 	default: {
658 	  pr = (dk3_printer_alias_t const *)r;
659 	  if(pl->name) {
660 	    if(pr->name) {
661 	      back = dk3str_cmp(pl->name, pr->name);
662 	      if(back < 0) back = -1;
663 	      if(back > 0) back =  1;
664 	    } else {
665 	      back = 1;
666 	    }
667 	  } else {
668 	    if(pr->name) {
669 	      back = -1;
670 	    }
671 	  }
672 	} break;
673       }
674     } else {
675       back = 1;
676     }
677   } else {
678     if(r) {
679       back = -1;
680     }
681   }
682   return back;
683 }
684 
685 
686 
687 /**	Compare two print hosts by name.
688 	@param	l	Left object.
689 	@param	r	Right object or name.
690 	@param	cr	Comparison criteria (0=host/host, 1=host/name).
691 	@return	Comparison result.
692 */
693 static
694 int
dk3print_compare_host(void const * l,void const * r,int cr)695 dk3print_compare_host(void const *l, void const *r, int cr)
696 {
697   int		 back = 0;
698   dk3_print_host_t const	*pl;	/* Left print host. */
699   dk3_print_host_t const	*pr;	/* Right print host. */
700   dkChar const			*n;	/* Right print host name. */
701   if(l) {
702     if(r) {
703       pl = (dk3_print_host_t const *)l;
704       switch(cr) {
705         case 1: {
706 	  n = (dkChar const *)r;
707 	  if(pl->name) {
708 	    back = dk3str_cmp(pl->name, n);
709 	    if(back < 0) back = -1;
710 	    if(back > 0) back =  1;
711 	  } else {
712 	    back = -1;
713 	  }
714 	} break;
715 	default: {
716 	  pr = (dk3_print_host_t const *)r;
717 	  if(pl->name) {
718 	    if(pr->name) {
719 	      back = dk3str_cmp(pl->name, pr->name);
720 	      if(back < 0) back = -1;
721 	      if(back > 0) back =  1;
722 	    } else {
723 	      back = 1;
724 	    }
725 	  } else {
726 	    if(pr->name) {
727 	      back = -1;
728 	    }
729 	  }
730 	} break;
731       }
732     } else {
733       back = 1;
734     }
735   } else {
736     if(r) {
737       back = -1;
738     }
739   }
740   return back;
741 }
742 
743 
744 
745 /**	Compare two print host aliases by name.
746 	@param	l	Left object.
747 	@param	r	Right object or name.
748 	@param	cr	Comparison criteria (0=alias/alias, 1=alias/name).
749 	@return	Comparison result.
750 */
751 static
752 int
dk3print_compare_host_alias(void const * l,void const * r,int cr)753 dk3print_compare_host_alias(void const *l, void const *r, int cr)
754 {
755   int		 		 back = 0;
756   dk3_print_host_alias_t const	*pl;		/* Left host alias. */
757   dk3_print_host_alias_t const	*pr;		/* Right host alias. */
758   dkChar const			*n;		/* Right alias name. */
759   if(l) {
760     if(r) {
761       pl = (dk3_print_host_alias_t const *)l;
762       switch(cr) {
763         case 1: {
764 	  n = (dkChar const *)r;
765 	  if(pl->name) {
766 	    back = dk3str_cmp(pl->name, n);
767 	    if(back < 0) back = -1;
768 	    if(back > 0) back =  1;
769 	  } else {
770 	    back = -1;
771 	  }
772 	} break;
773 	default: {
774 	  pr = (dk3_print_host_alias_t const *)r;
775 	  if(pl->name) {
776 	    if(pr->name) {
777 	      back = dk3str_cmp(pl->name, pr->name);
778 	      if(back < 0) back = -1;
779 	      if(back > 0) back =  1;
780 	    } else {
781 	      back = 1;
782 	    }
783 	  } else {
784 	    if(pr->name) {
785 	      back = -1;
786 	    }
787 	  }
788 	} break;
789       }
790     } else {
791       back = 1;
792     }
793   } else {
794     if(r) {
795       back = -1;
796     }
797   }
798   return back;
799 }
800 
801 
802 
803 dk3_print_conf_t *
dk3print_config_new(dk3_app_t * app)804 dk3print_config_new(dk3_app_t *app)
805 {
806   dk3_print_conf_t	*back	= NULL;
807   int			 ok	= 0;	/* Flag: Success. */
808 
809   if(app) {
810     back = dk3_new_app(dk3_print_conf_t,1,app);
811     if(back) {
812       /* Initialize members. */
813       back->sPrinters = NULL; back->iPrinters = NULL;
814       back->sPrintAliases = NULL; back->iPrintAliases = NULL;
815       back->sPrintHosts = NULL; back->iPrintHosts = NULL;
816       back->defPrinter = NULL;
817       back->defHost = NULL;
818       back->defPsl = 3;
819       back->app = app;
820       back->msg = dk3app_messages(app, dk3print_nl[1], dk3print_msg);
821       if(!(back->msg)) { back->msg = dk3print_msg; }
822       /* Allocate resources for storages. */
823       back->sPrinters = dk3sto_open_app(app);
824       if(back->sPrinters) {
825         dk3sto_set_comp(back->sPrinters, dk3print_compare_printer, 0);
826         back->iPrinters = dk3sto_it_open(back->sPrinters);
827         if(back->iPrinters) {
828           back->sPrintAliases = dk3sto_open_app(app);
829 	  if(back->sPrintAliases) {
830 	    dk3sto_set_comp(back->sPrintAliases,dk3print_compare_print_alias,0);
831 	    back->iPrintAliases = dk3sto_it_open(back->sPrintAliases);
832 	    if(back->iPrintAliases) {
833 	      back->sPrintHosts = dk3sto_open_app(app);
834 	      if(back->sPrintHosts) {
835 	        dk3sto_set_comp(back->sPrintHosts, dk3print_compare_host, 0);
836 	        back->iPrintHosts = dk3sto_it_open(back->sPrintHosts);
837 	        if(back->iPrintHosts) {
838 	          back->sHostAliases = dk3sto_open_app(app);
839 		  if(back->sHostAliases) {
840 		    dk3sto_set_comp(
841 		      back->sHostAliases, dk3print_compare_host_alias, 0
842 		    );
843 		    back->iHostAliases = dk3sto_it_open(back->sHostAliases);
844 		    if(back->iHostAliases) {
845 		      ok = 1;
846 		    }
847 		  }
848 	        }
849 	      }
850 	    }
851 	  }
852         }
853       }
854       /* Destroy configuration if allocations failed. */
855       if(!(ok)) {
856         dk3print_conf_delete(back);
857         back = NULL;
858       }
859     }
860   }
861   return back;
862 }
863 
864 
865 #if DK3_ON_WINDOWS
866 
867 /**	Check whether a printer name contains the words
868 	"PostScript" or "PS".
869 	@param	pc	Print configuration to set up.
870 	@param	pr	Printer structure to modify.
871 	@param	str	Printer string to check.
872 */
873 static
874 void
dk3print_check_postscript(dk3_print_conf_t * pc,dk3_printer_t * pr,dkChar const * str)875 dk3print_check_postscript(
876   dk3_print_conf_t	*pc,
877   dk3_printer_t		*pr,
878   dkChar const		*str
879 )
880 {
881   dkChar		 buf[DK3_MAX_PATH];	/* Private copy. */
882   dkChar		*c;			/* Current string. */
883   dkChar		*n;			/* Next string. */
884 
885   if(!(pr->ps)) {
886     if(dk3str_len(str) < DK3_SIZEOF(buf,dkChar)) {
887       dk3str_cpy_not_overlapped(buf, str);
888       c = dk3str_start(buf, NULL);
889       while(c) {
890         n = dk3str_next(c, NULL);
891 	if(dk3str_cmp(c, dk3print_nl[2]) == 0) {
892 	  pr->ps = pc->defPsl;
893 	} else {
894 	  if(dk3str_casecmp(c, dk3print_nl[3]) == 0) {
895 	    pr->ps = pc->defPsl;
896 	  }
897 	}
898 	c = n;
899       }
900     }
901     if(!(pr->ps)) {
902       if(dk3str_casecmp(str, dk3print_nl[4]) == 0) {
903         pr->ps = pc->defPsl;
904       }
905     }
906   }
907 }
908 
909 #endif
910 
911 
912 
913 #if DK3_ON_WINDOWS
914 /* + Windows */
915 
916 /**	Read printer information from system.
917 	@param	pc	Print configuration to set up.
918 	@return	1 on success, 0 on error.
919 */
920 static
921 int
dk3print_read_system(dk3_print_conf_t * pc)922 dk3print_read_system(dk3_print_conf_t *pc)
923 {
924   dkChar		 buf[1024];	/* Default printer name. */
925   char			*peb;		/* Result buffer. */
926 #if DK3_CHAR_SIZE > 1
927   PRINTER_INFO_2W	*pi2;		/* Printer information. */
928 #else
929   PRINTER_INFO_2A	*pi2;		/* Printer information. */
930 #endif
931   dk3_printer_t		*printer;	/* New printer to create. */
932   DWORD			 cbNeeded;	/* Bytes needed. */
933   DWORD			 cbReturned;	/* Bytes returned. */
934   DWORD			 szPeb;		/* Size of peb. */
935   DWORD			 i;		/* Index of current information. */
936   DWORD			 dwSz;		/* Buffer size. */
937   BOOL			 res;		/* Operation result. */
938   int			 back = 1;
939 
940   cbNeeded = cbReturned = szPeb = (DWORD)0UL;
941 #if DK3_CHAR_SIZE > 1
942   EnumPrintersW(PRINTER_ENUM_LOCAL,NULL,2,NULL,szPeb,&cbNeeded,&cbReturned);
943 #else
944   EnumPrintersA(PRINTER_ENUM_LOCAL,NULL,2,NULL,szPeb,&cbNeeded,&cbReturned);
945 #endif
946   if(cbNeeded > 0) {
947     szPeb = cbNeeded;
948     peb = dk3_new_app(char,(size_t)cbNeeded,pc->app);
949     if(peb) {
950       cbNeeded = cbReturned = (DWORD)0UL;
951 #if DK3_CHAR_SIZE > 1
952       res = EnumPrintersW(
953         PRINTER_ENUM_LOCAL,NULL,2,(LPBYTE)peb,szPeb,&cbNeeded,&cbReturned
954       );
955 #else
956       res = EnumPrintersA(
957         PRINTER_ENUM_LOCAL,NULL,2,(LPBYTE)peb,szPeb,&cbNeeded,&cbReturned
958       );
959 #endif
960       if(res) {
961         if((DWORD)0UL < cbReturned) {
962 #if DK3_CHAR_SIZE > 1
963 	  pi2 = (PRINTER_INFO_2W *)peb;
964 #else
965 	  pi2 = (PRINTER_INFO_2A *)peb;
966 #endif
967 	  for(i = (DWORD)0UL; i < cbReturned; i++) {
968 	    printer = dk3print_printer_new(pc, pi2->pPrinterName);
969 	    if(printer) {
970 	      printer->t_p = DK3_PRINTER_TYPE_WINDOWS;
971 	      if(pi2->pDriverName) {
972 	        dk3print_check_postscript(pc, printer, pi2->pDriverName);
973 	      }
974 	      if(pi2->pComment) {
975 	        dk3print_check_postscript(pc, printer, pi2->pComment);
976 	      }
977 	    } else {
978 	      back = 0;
979 	    }
980 	    pi2++;
981 	  }
982 	} else {
983 	}
984       } else {
985         back = 0;
986       }
987       dk3_delete(peb);
988     } else {
989       back = 0;
990     }
991     if(back) {
992       dwSz = (DWORD)DK3_SIZEOF(buf,dkChar) ;
993 #if DK3_CHAR_SIZE > 1
994       res = GetDefaultPrinterW(buf, &dwSz);
995 #else
996       res = GetDefaultPrinterA(buf, &dwSz);
997 #endif
998       if(res) {
999         if(dwSz > (DWORD)0UL) {
1000 	  if(dwSz < DK3_SIZEOF(buf,dkChar)) {
1001 	    buf[dwSz - 1] = dkT('\0');
1002 	    printer =
1003 	    (dk3_printer_t *)dk3sto_it_find_like(pc->iPrinters, (void *)buf, 1);
1004 	    if(printer) {
1005 	      pc->defPrinter = printer;
1006 	    }
1007 	  }
1008 	}
1009       }
1010     }
1011   } else {
1012   }
1013 
1014   return back;
1015 }
1016 
1017 /* - Windows */
1018 
1019 #else
1020 /* + non-Windows */
1021 
1022 /**	Read printer information from system.
1023 	@param	pc	Print configuration to set up.
1024 	@return	1 on success, 0 on error.
1025 */
1026 static
1027 int
dk3print_read_system(dk3_print_conf_t * DK3_ARG_UNUSED (pc))1028 dk3print_read_system(dk3_print_conf_t * DK3_ARG_UNUSED(pc) )
1029 {
1030   int		 back = 1;
1031 
1032   DK3_UNUSED_ARG(pc)
1033   /* ##### Read /etc/printcap */
1034 
1035   return back;
1036 }
1037 
1038 /* - non-Windows */
1039 #endif
1040 
1041 
1042 /**	Read print configuration data from system and/or configuration files.
1043 	@param	pc		Print configuration to set up.
1044 	@param	useConfigFiles	Flag: Use dk3print conf files.
1045 	@return	1 on success, 0 on error.
1046 */
1047 static
1048 int
dk3print_read_configuration(dk3_print_conf_t * pc,int useConfigFiles)1049 dk3print_read_configuration(dk3_print_conf_t *pc, int useConfigFiles)
1050 {
1051   dkChar	 buf[512];	/* Buffer used for values in diagnostics. */
1052   int		 i;		/* Temporary conversion result (PS level). */
1053   int		 back = 0;
1054 
1055 
1056   /* Find default PS level from preferences */
1057   if(pc->app) {
1058     if(dk3app_get_pref(pc->app, dk3print_nl[5], buf, DK3_SIZEOF(buf,dkChar))) {
1059 #if VERSION_BEFORE_20140716
1060       if(dk3sf_sscanf3(buf, dk3print_nl[6], &i) == 1)
1061 #else
1062       if (0 != dk3ma_i_from_string(&i, buf, NULL))
1063 #endif
1064       {
1065         if((2 <= i) && (3 >= i)) {
1066 	  pc->defPsl = i;
1067 	} else {
1068 	  /* ERROR: PS level out of range! */
1069 	  dk3app_log_3(pc->app, DK3_LL_ERROR, pc->msg, 49, 50, buf);
1070 	}
1071       } else {
1072         /* ERROR: PS level not numeric! */
1073 	dk3app_log_3(pc->app, DK3_LL_ERROR, pc->msg, 49, 50, buf);
1074       }
1075     }
1076   }
1077   /* Read system printers and configuration files. */
1078   if(dk3print_read_system(pc)) {
1079     if(useConfigFiles) {
1080       if(dk3print_read_config_files(pc)) {
1081         back = 1;
1082       }
1083     } else {
1084       back = 1;
1085     }
1086   }
1087   return back;
1088 }
1089 
1090 
1091 
1092 dk3_print_conf_t *
dk3print_conf_open(dk3_app_t * app,int useConfigFiles)1093 dk3print_conf_open(dk3_app_t *app, int useConfigFiles)
1094 {
1095   dk3_print_conf_t	*back = NULL;
1096 
1097   if(app) {
1098     back = dk3print_config_new(app);
1099     if(back) {
1100       if(!dk3print_read_configuration(back, useConfigFiles)) {
1101         dk3print_conf_delete(back);
1102         back = NULL;
1103       }
1104     }
1105   }
1106   return back;
1107 }
1108 
1109 
1110 
1111 void
dk3print_conf_close(dk3_print_conf_t * pc)1112 dk3print_conf_close(dk3_print_conf_t *pc)
1113 {
1114 
1115   if(pc) {
1116     dk3print_conf_delete(pc);
1117   }
1118 }
1119 
1120 
1121 
1122 void
dk3print_set_det(dk3_printer_details_t * det,int tp)1123 dk3print_set_det(dk3_printer_details_t *det, int tp)
1124 {
1125 
1126   if(det) {
1127     switch(tp) {
1128       case DK3_PRINTER_TYPE_WINDOWS: {
1129         (det->win).dummy = 0;
1130       } break;
1131       case DK3_PRINTER_TYPE_SOCKET: {
1132         (det->sock).hostname = NULL;
1133 	(det->sock).portno = 0;
1134 	(det->sock).ordrel = 0x00;
1135 	(det->sock).to_c = -1.0;
1136 	(det->sock).to_r = -1.0;
1137 	(det->sock).to_s = -1.0;
1138       } break;
1139       case DK3_PRINTER_TYPE_LPD: case DK3_PRINTER_TYPE_LPRNG: {
1140         (det->lprng).hostname = NULL;
1141 	(det->lprng).queuename = NULL;
1142 	(det->lprng).to_c = -1.0;
1143 	(det->lprng).to_r = -1.0;
1144 	(det->lprng).to_s = -1.0;
1145       } break;
1146       default: {
1147       } break;
1148     }
1149   }
1150 }
1151 
1152 
1153 
1154 dk3_printer_t *
dk3print_get_printer(dk3_print_conf_t * pc,dkChar const * pn)1155 dk3print_get_printer(dk3_print_conf_t *pc, dkChar const *pn)
1156 {
1157   dk3_printer_t		*back = NULL;
1158   dk3_printer_alias_t	*al = NULL;	/* Alias for printer. */
1159 
1160   if((pc) && (pn)) {
1161     back = (dk3_printer_t *)dk3sto_it_find_like(pc->iPrinters, (void *)pn, 1);
1162     if(!(back)) {
1163       al = (dk3_printer_alias_t *)dk3sto_it_find_like(
1164         pc->iPrintAliases, (void *)pn, 1
1165       );
1166       if(al) {
1167         back = al->printer;
1168       }
1169     }
1170   }
1171   return back;
1172 }
1173 
1174 
1175 dk3_print_host_t *
dk3print_get_host(dk3_print_conf_t * pc,dkChar const * hn)1176 dk3print_get_host(dk3_print_conf_t *pc, dkChar const *hn)
1177 {
1178   dk3_print_host_t		*back = NULL;
1179   dk3_print_host_alias_t	*al = NULL;	/* Alias for host. */
1180 
1181   if((pc) && (hn)) {
1182     back = (dk3_print_host_t *)dk3sto_it_find_like(
1183       pc->iPrintHosts, (void *)hn, 1
1184     );
1185     if(!(back)) {
1186       al = (dk3_print_host_alias_t *)dk3sto_it_find_like(
1187         pc->iHostAliases, (void *)hn, 1
1188       );
1189       if(al) {
1190         back = al->host;
1191       }
1192     }
1193   }
1194   return back;
1195 }
1196 
1197