/*
	WARNING: This file was generated by dkct.
	Changes you make here will be lost if dkct is run again!
	You should modify the original source and run dkct on it.
	Original source: dk3prcfg.ctr
*/

/*
Copyright (C) 2013, Dirk Krause

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 author 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 dk3prcfg.c The dk3prcfg module.
*/


#line 25 "dk3prcfg.ctr"


#include "dk3all.h"
#include "dk3print.h"
#include "dk3prcfg.h"





#line 34 "dk3prcfg.ctr"



/**	Print configuration file processor.
*/
typedef struct {
  dk3_print_conf_t		*pc;	/**< Print configuration to set up. */
  dk3_printer_t			*pr;	/**< Current printer to modify. */
  dk3_print_host_t		*ho;	/**< Current host to modify. */
} dk3_print_config_processor_t;



/**	Keywords used by the module, not localized.
*/
static dkChar const * const	dk3prcfg_nl[] = {
/* 0 */
dkT("dk3print.conf"),

/* 1 */
dkT("%u"),

/* 2 */
dkT("%d"),

/* 3 */
dkT("%lf"),

NULL


#line 68 "dk3prcfg.ctr"
};



/**	SNMP versions.
*/
static dkChar const * const	dk3prcfg_snmp_versions[] = {
/* 0 */
dkT("1"),

/* 1 */
dkT("2c"),

/* 2 */
dkT("2p"),

/* 3 */
dkT("3"),

NULL


#line 81 "dk3prcfg.ctr"
};



/**	Keywords for section start.
*/
static dkChar const * const	dk3prcfg_host_or_printer[] = {
/* 0 */
dkT("host"),

/* 1 */
dkT("printer"),

NULL


#line 92 "dk3prcfg.ctr"
};



/**	Keywords for printer configuration lines.
*/
static dkChar const * const	dk3prcfg_printer_keywords[] = {
/* 0 */
dkT("alias"),

/* 1 */
dkT("type"),

/* 2 */
dkT("host"),

/* 3 */
dkT("queue"),

/* 4 */
dkT("port"),

/* 5 */
dkT("ps"),

/* 6 */
dkT("ps level"),

/* 7 */
dkT("default"),

/* 8 */
dkT("snmp host"),

/* 9 */
dkT("snmp community"),

/* 10 */
dkT("snmp version"),

/* 11 */
dkT("connect timeout"),

/* 12 */
dkT("send timeout"),

/* 13 */
dkT("receive timeout"),

/* 14 */
dkT("orderly release"),

NULL


#line 161 "dk3prcfg.ctr"
};



/**	Keywords to configure print hosts.
*/
static dkChar const * const	dk3prcfg_host_keywords[] = {
/* 0 */
dkT("alias"),

/* 1 */
dkT("encoding"),

/* 2 */
dkT("connect timeout"),

/* 3 */
dkT("send timeout"),

/* 4 */
dkT("receive timeout"),

/* 5 */
dkT("default"),

NULL


#line 194 "dk3prcfg.ctr"
};



/**	Print queues host types.
*/
static dkChar const * const	dk3print_queue_types[] = {
/* 0 */
dkT("socket"),

/* 1 */
dkT("lpd"),

/* 2 */
dkT("lprng"),

NULL


#line 206 "dk3prcfg.ctr"
};



/**	Initialize a print configuration processor.
	@param	pr	Processor to initialize.
	@param	pc	Print configuration to set up.
*/
static
void
dk3print_initialize_print_config_processor(
  dk3_print_config_processor_t	*pr,
  dk3_print_conf_t		*pc
)
{
  pr->pc = pc;
  pr->pr = NULL;
  pr->ho = NULL;
}



/**	Process configuration line to process current printer or host.
	@param	proc	Configuration processor.
	@param	pc	Print configuration to set up.
	@param	il	Input line to process.
	@return	1 on succuess, 0 on recoverable errors, -1 on
	unrecoverable errors.
*/
static
int
dk3print_lh_printer_or_host(
  dk3_print_config_processor_t	*proc,
  dk3_print_conf_t		*pc,
  dkChar			*il
)
{
  dkChar		*p1;		/* Start of value. */
  dkChar		*p2;		/* Finalizing square bracket. */
  dkChar		*p3;		/* Start of input line. */
  int			 back = 0;
  

#line 248 "dk3prcfg.ctr"
  p3 = il;
  p3++;
  p3 = dk3str_start(p3, NULL);
  if(p3) {
    p1 = dk3str_next(p3, NULL);
    if(p1) {				

#line 254 "dk3prcfg.ctr"
      p2 = dk3str_chr(p1, dkT(']'));
      if(p2) { *p2 = dkT('\0'); }
      else {				

#line 257 "dk3prcfg.ctr"
        /* WARNING: Missing closing bracket! */
	dk3app_log_1(pc->app, DK3_LL_WARNING, pc->msg, 27);
      }
      switch(dk3str_array_index(dk3prcfg_host_or_printer, p3, 0)) {
        case 1: {		

#line 262 "dk3prcfg.ctr"
          proc->pr = dk3print_printer_new(pc, p1);
	  if(proc->pr) {
	    back = 1;
	  } else {
	    back = -1;
	  }
        } break;
        case 0: {		

#line 270 "dk3prcfg.ctr"
          proc->ho = dk3print_host_new(pc, p1);
	  if(proc->ho) {
	    back = 1;
	  } else {
	    back = -1;
	  }
        } break;
        default: {		

#line 278 "dk3prcfg.ctr"
          /* ERROR: Not "host" or "printer"! */
	  dk3app_log_3(pc->app, DK3_LL_ERROR, pc->msg, 28, 29, p3);
        } break;
      }
    } else {				

#line 283 "dk3prcfg.ctr"
      /* ERROR: Printer or host name is missing! */
      dk3app_log_1(pc->app, DK3_LL_ERROR, pc->msg, 30);
    }
  }
  

#line 288 "dk3prcfg.ctr"
  return back;
}



/**	Create a printer alias.
	@param	pc	Print configuration to set up.
	@param	pr	Current printer.
	@param	vptr	Alias name.
	@return	1 on success, 0 on recoverable, -1 on unrecoverable error.
*/
static
int
dk3print_lh_pr_alias(
  dk3_print_conf_t	*pc,
  dk3_printer_t		*pr,
  dkChar const		*vptr
)
{
  dk3_printer_alias_t	*al;		/* Alias already found. */
  int			 back = -1;
  

#line 310 "dk3prcfg.ctr"
  if(vptr) {
    if(dk3sto_it_find_like(pc->iPrinters, (void *)vptr, 1)) {
      /* ERROR: Printer name already exists! */
      dk3app_log_3(pc->app, DK3_LL_ERROR, pc->msg, 31, 32, vptr);
    } else {
      if(dk3sto_it_find_like(pc->iPrintAliases, (void *)vptr, 1)) {
        /* ERROR: Alias name already exists! */
	dk3app_log_3(pc->app, DK3_LL_ERROR, pc->msg, 33, 34, vptr);
      } else {
        al = dk3_new_app(dk3_printer_alias_t,1,pc->app);
        if(al) {
	  al->printer = pr;
	  al->name = dk3str_dup_app(vptr, pc->app);
	  if(al->name) {
	    if(dk3sto_add(pc->sPrintAliases, (void *)al)) {
	      back = 1;
	    } else {
	      dk3print_alias_delete(al);
	    }
	  } else {
	    dk3print_alias_delete(al);
	  }
        }
      }
    }
  } else {
    /* ERROR: Argument required! */
    dk3app_log_3(
      pc->app, DK3_LL_ERROR, pc->msg, 35, 36,
      dk3prcfg_printer_keywords[0]
    );
  } 

#line 342 "dk3prcfg.ctr"
  return back;
}



/**	Set print queue type.
	@param	pc	Print configuration to set up.
	@param	pr	Current printer.
	@param	pqt	New print queue type.
	@return	1 on success, 0 on recoverable, -1 on unrecoverable errors.
*/
static
int
dk3print_lh_pr_set_pqt(
  dk3_print_conf_t	*pc,
  dk3_printer_t		*pr,
  int			 pqt
)
{
  int			 back = -1;
  

#line 363 "dk3prcfg.ctr"
  switch(pr->t_p) {
    case DK3_PRINTER_TYPE_NONE: {
      pr->t_p = pqt;
      dk3print_set_det(&(pr->det_p), pqt);
      back = 1;
    } break;
    case DK3_PRINTER_TYPE_WINDOWS: {
      switch(pr->t_s) {
        case DK3_PRINTER_TYPE_NONE: {
	  pr->t_s = pqt;
	  dk3print_set_det(&(pr->det_s), pqt);
	  back = 1;
	} break;
	default: {
	  /* ERROR: Queue type already set up! */
	  dk3app_log_1(pc->app, DK3_LL_ERROR, pc->msg, 37);
	} break;
      }
    } break;
    default: {
      /* ERROR: Queue type already set up! */
      dk3app_log_1(pc->app, DK3_LL_ERROR, pc->msg, 37);
    } break;
  } 

#line 387 "dk3prcfg.ctr"
  return back;
}



/**	Set printer type.
	@param	pc	Print configuration to set up.
	@param	pr	Current printer.
	@param	vptr	New value.
	@return	1 on success, 0 on recoverable, -1 on unrecoverable error.
*/
static
int
dk3print_lh_pr_type(
  dk3_print_conf_t	*pc,
  dk3_printer_t		*pr,
  dkChar const		*vptr
)
{
  int			 pqt;		/* Print queue type. */
  int			 back = -1;
  

#line 409 "dk3prcfg.ctr"
  if(vptr) {
    pqt = dk3str_array_index(dk3print_queue_types, vptr, 0);
    if(-1 < pqt) {
      pqt = 2 + pqt;
      back = dk3print_lh_pr_set_pqt(pc, pr, pqt);
    } else {
      /* ERROR: Unknown print queue type! */
      dk3app_log_3(pc->app, DK3_LL_ERROR, pc->msg, 38, 39, vptr);
    }
  } else {
    /* ERRROR: Argument required! */
    dk3app_log_3(
      pc->app, DK3_LL_ERROR, pc->msg, 35, 36,
      dk3prcfg_printer_keywords[1]
    );
  } 

#line 425 "dk3prcfg.ctr"
  return back;
}



/**	Process line containing host details.
	@param	pc	Print configuration to modify.
	@param	det	Current details structure to modify.
	@param	tp	Current printer type.
	@param	name	Text to apply.
	@return	1 on success, 0 on errors.
*/
static
int
dk3print_lh_pr_det_host(
  dk3_print_conf_t	*pc,
  dk3_printer_details_t	*det,
  int			 tp,
  dkChar const		*name
)
{
  int			 back = -1;
  

#line 448 "dk3prcfg.ctr"
  switch(tp) {
    case DK3_PRINTER_TYPE_SOCKET: {
      if((det->sock).hostname) {
        /* WARNING: Overwriting configured host name! */
	dk3app_log_3(
	  pc->app, DK3_LL_ERROR, pc->msg, 40, 41,
	  (det->sock).hostname
	);
	dk3_release((det->sock).hostname)
      }
      (det->sock).hostname = dk3str_dup_app(name, pc->app);
      if((det->sock).hostname) {
        back = 1;
      }
    } break;
    case DK3_PRINTER_TYPE_LPD:
    case DK3_PRINTER_TYPE_LPRNG: {
      if((det->lprng).hostname) {
        /* WARNING: Overwriting configured host name! */
	dk3app_log_3(
	  pc->app, DK3_LL_ERROR, pc->msg, 40, 41,
	  (det->lprng).hostname
	);
	dk3_release((det->lprng).hostname)
      }
      (det->lprng).hostname = dk3str_dup_app(name, pc->app);
      if((det->lprng).hostname) {
        back = 1;
      }
    } break;
  } 

#line 479 "dk3prcfg.ctr"
  return back;
}



/**	Set printer host.
	@param	pc	Print configuration to set up.
	@param	pr	Current printer.
	@param	vptr	New value.
	@return	1 on success, 0 on recoverable, -1 on unrecoverable error.
*/
static
int
dk3print_lh_pr_host(
  dk3_print_conf_t	*pc,
  dk3_printer_t		*pr,
  dkChar const		*vptr
)
{
  int			 back = -1;
  

#line 500 "dk3prcfg.ctr"
  if(vptr) {
    switch(pr->t_p) {
      case DK3_PRINTER_TYPE_WINDOWS: {
        switch(pr->t_s) {
	  case DK3_PRINTER_TYPE_SOCKET:
	  case DK3_PRINTER_TYPE_LPD:
	  case DK3_PRINTER_TYPE_LPRNG: {
	    back = dk3print_lh_pr_det_host(pc, &(pr->det_s), pr->t_s, vptr);
	  } break;
	  default: {
	    /* ERROR: Option not available for this printer type! */
	    dk3app_log_3(
	      pc->app, DK3_LL_ERROR, pc->msg, 42, 43,
	      dk3prcfg_printer_keywords[2]
	    );
	  } break;
	}
      } break;
      case DK3_PRINTER_TYPE_SOCKET:
      case DK3_PRINTER_TYPE_LPD:
      case DK3_PRINTER_TYPE_LPRNG: {
        back = dk3print_lh_pr_det_host(pc, &(pr->det_p), pr->t_p, vptr);
      } break;
      default: {
        /* ERROR: Option not available for this printer type! */
	dk3app_log_3(
	  pc->app, DK3_LL_ERROR, pc->msg, 42, 43,
	  dk3prcfg_printer_keywords[2]
	);
      } break;
    }
  } else {
    /* ERROR: Argument required! */
    dk3app_log_3(
      pc->app, DK3_LL_ERROR, pc->msg, 35, 36,
      dk3prcfg_printer_keywords[2]
    );
  }
  

#line 539 "dk3prcfg.ctr"
  return back;
}



/**	Set print queue entry for current printer.
	@param	pc	Print configuration to modify.
	@param	det	Details structure for current printer.
	@param	tp	Current printer type.
	@param	name	Configuration text to apply.
	@return	1 on success, 0 on error.
*/
static
int
dk3print_lh_pr_set_queue(
  dk3_print_conf_t	*pc,
  dk3_printer_details_t	*det,
  int			 tp,
  dkChar const		*name
)
{
  int			 back = -1;
  

#line 562 "dk3prcfg.ctr"
  switch(tp) {
    case DK3_PRINTER_TYPE_LPD:
    case DK3_PRINTER_TYPE_LPRNG: {
      if((det->lprng).queuename) {
        /* WARNING: Overriding queue name! */
	dk3app_log_3(
	  pc->app, DK3_LL_WARNING, pc->msg, 44, 45,
	  (det->lprng).queuename
	);
	dk3_release((det->lprng).queuename)
      }
      (det->lprng).queuename = dk3str_dup_app(name, pc->app);
      if((det->lprng).queuename) {
        back = 1;
      }
    } break;
  } 

#line 579 "dk3prcfg.ctr"
  return back;
}



/**	Set printer queue.
	@param	pc	Print configuration to set up.
	@param	pr	Current printer.
	@param	vptr	New value.
	@return	1 on success, 0 on recoverable, -1 on unrecoverable error.
*/
static
int
dk3print_lh_pr_queue(
  dk3_print_conf_t	*pc,
  dk3_printer_t		*pr,
  dkChar const		*vptr
)
{
  int			 back = -1;
  

#line 600 "dk3prcfg.ctr"
  if(vptr) {
    switch(pr->t_p) {
      case DK3_PRINTER_TYPE_WINDOWS: {
        switch(pr->t_s) {
	  case DK3_PRINTER_TYPE_LPD:
	  case DK3_PRINTER_TYPE_LPRNG: {
	    back = dk3print_lh_pr_set_queue(pc, &(pr->det_s), pr->t_s, vptr);
	  } break;
	  default: {
	    /* ERROR: Option not available for printer type! */
	    dk3app_log_3(
	      pc->app, DK3_LL_ERROR, pc->msg, 42, 43,
	      dk3prcfg_printer_keywords[3]
	    );
	  } break;
	}
      } break;
      case DK3_PRINTER_TYPE_LPD:
      case DK3_PRINTER_TYPE_LPRNG: {
        back = dk3print_lh_pr_set_queue(pc, &(pr->det_p), pr->t_p, vptr);
      } break;
      default: {
        /* ERROR: Option not available for printer type! */
	dk3app_log_3(
	  pc->app, DK3_LL_ERROR, pc->msg, 42, 43,
	  dk3prcfg_printer_keywords[3]
	);
      } break;
    }
  } else {
    /* ERROR: Argument required! */
    dk3app_log_3(
      pc->app, DK3_LL_ERROR, pc->msg, 35, 36,
      dk3prcfg_printer_keywords[3]
    );
  } 

#line 636 "dk3prcfg.ctr"
  return back;
}



/**	Set port number for current printer.
	@param	pc	Print configuration to modify.
	@param	det	Details structure for current printer.
	@param	tp	Current printer type.
	@param	name	Configuration text to apply.
	@return	1 on success, 0 on error.
*/
static
int
dk3print_lh_pr_set_port(
  dk3_print_conf_t	*pc,
  dk3_printer_details_t	*det,
  int			 tp,
  dkChar const		*name
)
{
  dkChar		 buf[64];	/* Used to show existing port no. */
  int			 back = -1;
  unsigned 		 u;		/* Temporary conversion result. */
  unsigned short	 us;		/* New port number. */
  

#line 662 "dk3prcfg.ctr"
  switch(tp) {
    case DK3_PRINTER_TYPE_SOCKET: {	

#line 664 "dk3prcfg.ctr"
      if((det->sock).portno) {
        /* Warning: Overriding port number! */
	dk3sf_sprintf3(buf,dkT("%u"),(unsigned)((det->sock).portno));
	dk3app_log_3(pc->app, DK3_LL_WARNING, pc->msg, 46, 47, buf);
      }
      if(dk3sf_sscanf3(name, dk3prcfg_nl[1], &u)) {
        us = (unsigned short)u;
	if(u == (unsigned)us) {				

#line 672 "dk3prcfg.ctr"
	  (det->sock).portno = us;
	  back = 1;
	} else {					

#line 675 "dk3prcfg.ctr"
	  /* ERROR: Numeric overflow! */
	  dk3app_log_1(pc->app, DK3_LL_ERROR, pc->msg, 48);
	}
      } else {						

#line 679 "dk3prcfg.ctr"
        /* ERROR: Not a number! */
	dk3app_log_i3(pc->app, DK3_LL_ERROR, 141, 142, name);
      }
    } break;
    default: {				

#line 684 "dk3prcfg.ctr"
    } break;
  } 

#line 686 "dk3prcfg.ctr"
  return back;
}



/**	Set printer port.
	@param	pc	Print configuration to set up.
	@param	pr	Current printer.
	@param	vptr	New value.
	@return	1 on success, 0 on recoverable, -1 on unrecoverable error.
*/
static
int
dk3print_lh_pr_port(
  dk3_print_conf_t	*pc,
  dk3_printer_t		*pr,
  dkChar const		*vptr
)
{
  int			 back = -1;
  

#line 707 "dk3prcfg.ctr"
  if(vptr) {
    switch(pr->t_p) {
      case DK3_PRINTER_TYPE_WINDOWS: {
        switch(pr->t_s) {
	  case DK3_PRINTER_TYPE_SOCKET: {	

#line 712 "dk3prcfg.ctr"
	    back = dk3print_lh_pr_set_port(pc, &(pr->det_s), pr->t_s, vptr);
	  } break;
	  default: {
	    /* ERROR: Option not available for print queue type! */
	    dk3app_log_3(
	      pc->app, DK3_LL_ERROR, pc->msg, 42, 43,
	      dk3prcfg_printer_keywords[4]
	    );
	  } break;
	}
      } break;
      case DK3_PRINTER_TYPE_SOCKET: {		

#line 724 "dk3prcfg.ctr"
        back = dk3print_lh_pr_set_port(pc, &(pr->det_p), pr->t_p, vptr);
      } break;
      default: {
        /* ERROR: Option not available for print queue type! */
	dk3app_log_3(
	  pc->app, DK3_LL_ERROR, pc->msg, 42, 43,
	  dk3prcfg_printer_keywords[4]
	);
      } break;
    }
  } else {
    /* ERROR: Argument required! */
    dk3app_log_3(
      pc->app, DK3_LL_ERROR, pc->msg, 35, 36,
      dk3prcfg_printer_keywords[4]
    );
  } 

#line 741 "dk3prcfg.ctr"
  return back;
}



/**	Set printer PS.
	@param	pc	Print configuration to set up.
	@param	pr	Current printer.
	@param	vptr	New value.
	@return	1 on success, 0 on recoverable, -1 on unrecoverable error.
*/
static
int
dk3print_lh_pr_ps(
  dk3_print_conf_t	*pc,
  dk3_printer_t		*pr,
  dkChar const		*vptr
)
{
  int			 back = -1;
  

#line 762 "dk3prcfg.ctr"
  if(vptr) {
    if(dk3str_is_bool(vptr)) {
      pr->ps = ((dk3str_is_on(vptr)) ? (pc->defPsl) : (0));
    } else {
      /* ERROR: Not a boolean value! */
      dk3app_log_i3(pc->app, DK3_LL_ERROR, 146, 147, vptr);
    }
  } else {
    pr->ps = pc->defPsl;
  } 

#line 772 "dk3prcfg.ctr"
  return back;
}



/**	Set printer PS level.
	@param	pc	Print configuration to set up.
	@param	pr	Current printer.
	@param	vptr	New value.
	@return	1 on success, 0 on recoverable, -1 on unrecoverable error.
*/
static
int
dk3print_lh_pr_psl(
  dk3_print_conf_t	*pc,
  dk3_printer_t		*pr,
  dkChar const		*vptr
)
{
  int			 back = -1;
  int			 i;		/* Temporary conversion result. */
  

#line 794 "dk3prcfg.ctr"
  if(vptr) {
    if(dk3sf_sscanf3(vptr,dk3prcfg_nl[2],&i)) {
      if((2 <= i) && (3 >= i)) {
        pr->ps = i;
	back = 1;
      } else {
        /* ERROR: Out of range! */
	dk3app_log_3(pc->app, DK3_LL_ERROR, pc->msg, 49, 50, vptr);
      }
    } else {
      /* ERROR: Not a number! */
      dk3app_log_i3(pc->app, DK3_LL_ERROR, 141, 142, vptr);
    }
  } else {
    /* ERROR: Value required! */
    dk3app_log_3(
      pc->app, DK3_LL_ERROR, pc->msg, 35, 36,
      dk3prcfg_printer_keywords[6]
    );
  } 

#line 814 "dk3prcfg.ctr"
  return back;
}



/**	Set printer as default.
	@param	pc	Print configuration to set up.
	@param	pr	Current printer.
	@param	vptr	New value.
	@return	1 on success, 0 on recoverable, -1 on unrecoverable error.
*/
static
int
dk3print_lh_pr_default(
  dk3_print_conf_t	*pc,
  dk3_printer_t		*pr,
  dkChar const		*vptr
)
{
  int			 back = -1;
  

#line 835 "dk3prcfg.ctr"
  if(vptr) {
    if(dk3str_is_bool(vptr)) {
      if(dk3str_is_on(vptr)) {
        pc->defPrinter = pr;
	back = 1;
      }
    } else {
      /* ERROR: Not a boolean value! */
      dk3app_log_i3(pc->app, DK3_LL_ERROR, 146, 147, vptr);
    }
  } else {
    pc->defPrinter = pr;
    back = 1;
  } 

#line 849 "dk3prcfg.ctr"
  return back;
}



/**	Set SNMP host.
	@param	pc	Print configuration to set up.
	@param	pr	Current printer.
	@param	vptr	New value.
	@return	1 on success, 0 on recoverable, -1 on unrecoverable error.
*/
static
int
dk3print_lh_pr_snmp_host(
  dk3_print_conf_t	*pc,
  dk3_printer_t		*pr,
  dkChar const		*vptr
)
{
  int			 back = -1;
  

#line 870 "dk3prcfg.ctr"
  if(vptr) {
    if(pr->h_snmp) {
      /* WARNING: Overwriting SNMP host! */
      dk3app_log_3(
        pc->app, DK3_LL_WARNING, pc->msg, 51, 52,
        pr->h_snmp
      );
      dk3_release(pr->h_snmp)
    }
    pr->h_snmp = dk3str_dup_app(vptr, pc->app);
    if(pr->h_snmp) {
      back = 1;
    }
  } else {
    /* ERROR: Value required! */
    dk3app_log_3(
      pc->app, DK3_LL_ERROR, pc->msg, 35, 36,
      dk3prcfg_printer_keywords[8]
    );
  } 

#line 890 "dk3prcfg.ctr"
  return back;
}



/**	Set SNMP community.
	@param	pc	Print configuration to set up.
	@param	pr	Current printer.
	@param	vptr	New value.
	@return	1 on success, 0 on recoverable, -1 on unrecoverable error.
*/
static
int
dk3print_lh_pr_snmp_community(
  dk3_print_conf_t	*pc,
  dk3_printer_t		*pr,
  dkChar const		*vptr
)
{
  int			 back = -1;
  

#line 911 "dk3prcfg.ctr"
  if(vptr) {
    if(pr->c_snmp) {
      /* WARNING: Overwriting SNMP community! */
      dk3app_log_3(
        pc->app, DK3_LL_WARNING, pc->msg, 53, 54,
        pr->c_snmp
      );
      dk3_release(pr->c_snmp)
    }
    pr->c_snmp = dk3str_dup_app(vptr, pc->app);
    if(pr->c_snmp) {
      back = 1;
    }
  } else {
    /* ERROR: Value required! */
    dk3app_log_3(
      pc->app, DK3_LL_ERROR, pc->msg, 35, 36,
      dk3prcfg_printer_keywords[9]
    );
  } 

#line 931 "dk3prcfg.ctr"
  return back;
}



/**	Set SNMP version.
	@param	pc	Print configuration to set up.
	@param	pr	Current printer.
	@param	vptr	New value.
	@return	1 on success, 0 on recoverable, -1 on unrecoverable error.
*/
static
int
dk3print_lh_pr_snmp_version(
  dk3_print_conf_t	*pc,
  dk3_printer_t		*pr,
  dkChar const		*vptr
)
{
  int			 back = -1;
  

#line 952 "dk3prcfg.ctr"
  if(vptr) {
    if(DK3_SNMP_VERSION_UNKNOWN != pr->v_snmp) {
      /* Warning: Overwriting SNMP version! */
      dk3app_log_1(pc->app, DK3_LL_WARNING, pc->msg, 55);
    }
    switch(dk3str_array_index(dk3prcfg_snmp_versions, vptr, 0)) {
      case 0: {
        pr->v_snmp = DK3_SNMP_VERSION_1; back = 1;
      } break;
      case 1: {
        pr->v_snmp = DK3_SNMP_VERSION_2C; back = 1;
      } break;
      case 2: {
        pr->v_snmp = DK3_SNMP_VERSION_2P; back = 1;
      } break;
      case 3: {
        pr->v_snmp = DK3_SNMP_VERSION_3; back = 1;
      } break;
      default: {
        /* ERROR: Unknown SNMP version! */
	dk3app_log_3(pc->app, DK3_LL_ERROR, pc->msg, 56, 57, vptr);
      } break;
    }
  } else {
    /*  ERROR: Value required! */
    dk3app_log_3(
      pc->app, DK3_LL_ERROR, pc->msg, 35, 36,
      dk3prcfg_printer_keywords[10]
    );
  } 

#line 982 "dk3prcfg.ctr"
  return back;
}



/**	Set timeout.
	@param	pc	Print configuration to set up.
	@param	det	Details for current printer.
	@param	tp	Current printer type.
	@param	vptr	Value text.
	@param	sel	Timeout selection (0=connect, 1=send, 2=receive).
	@return	1 on success, 0 on recoverable, -1 on unrecoverable errors.
*/
static
int
dk3print_lh_pr_set_timeout(
  dk3_print_conf_t	*pc,
  dk3_printer_details_t	*det,
  int			 tp,
  dkChar const		*vptr,
  int			 sel
)
{
  dkChar		 buf[128];	/* Buffer to show existing value. */
  double		 d	= -1.0;	/* Temporary conversion result. */
  int			 back	= -1;
  

#line 1009 "dk3prcfg.ctr"
  if(vptr) {
    if(dk3sf_sscanf3(vptr, dk3prcfg_nl[3],&d)) {
      if(d < 0.0) {
        d = -1.0;
      }
      switch(tp) {
        case DK3_PRINTER_TYPE_SOCKET: {
	  switch(sel) {
	    case 2: {
	      if((det->sock).to_r > 0.0) {
	        /* WARNING: Overwriting receive timeout! */
		dk3sf_sprintf3(buf,dkT("%lg"),(det->sock).to_r);
	        dk3app_log_3(pc->app, DK3_LL_WARNING, pc->msg, 58, 59, buf);
	      }
	      (det->sock).to_r = d;
	      back = 1;
	    } break;
	    case 1: {
	      if((det->sock).to_s > 0.0) {
	        /* WARNING: Overwriting send timeout! */
		dk3sf_sprintf3(buf,dkT("%lg"),(det->sock).to_s);
		dk3app_log_3(pc->app, DK3_LL_WARNING, pc->msg, 60, 61, buf);
	      }
	      (det->sock).to_s = d;
	      back = 1;
	    } break;
	    default: {
	      if((det->sock).to_c > 0.0) {
	        /* WARNING: Overwriting connect timeout! */
		dk3sf_sprintf3(buf,dkT("%lg"),(det->sock).to_c);
		dk3app_log_3(pc->app, DK3_LL_WARNING, pc->msg, 62, 63, buf);
	      }
	      (det->sock).to_c = d;
	      back = 1;
	    } break;
	  }
	} break;
	case DK3_PRINTER_TYPE_LPD:
	case DK3_PRINTER_TYPE_LPRNG: {
	  switch(sel) {
	    case 2: {
	      if((det->lprng).to_r > 0.0) {
	        /* WARNING: Overwriting receive timeout! */
		dk3sf_sprintf3(buf,dkT("%lg"),(det->lprng).to_r);
	        dk3app_log_3(pc->app, DK3_LL_WARNING, pc->msg, 58, 59, buf);
	      }
	      (det->lprng).to_r = d;
	      back = 1;
	    } break;
	    case 1: {
	      if((det->lprng).to_s > 0.0) {
	        /* WARNING: Overwriting send timeout! */
		dk3sf_sprintf3(buf,dkT("%lg"),(det->lprng).to_s);
	        dk3app_log_3(pc->app, DK3_LL_WARNING, pc->msg, 60, 61, buf);
	      }
	      (det->lprng).to_s = d;
	      back = 1;
	    } break;
	    default: {
	      if((det->lprng).to_c > 0.0) {
	        /* WARNING: Overwriting connect timeout! */
		dk3sf_sprintf3(buf,dkT("%lg"),(det->lprng).to_c);
	        dk3app_log_3(pc->app, DK3_LL_WARNING, pc->msg, 62, 63, buf);
	      }
	      (det->lprng).to_c = d;
	      back = 1;
	    } break;
	  }
	} break;
      }
    } else {
      /* ERROR: Not a number! */
      dk3app_log_i3(pc->app, DK3_LL_ERROR, 141, 142, vptr);
    }
  } 

#line 1084 "dk3prcfg.ctr"
  return back;
}



/**	Set connect timeout.
	@param	pc	Print configuration to set up.
	@param	pr	Current printer.
	@param	vptr	New value.
	@return	1 on success, 0 on recoverable, -1 on unrecoverable error.
*/
static
int
dk3print_lh_pr_connect_timeout(
  dk3_print_conf_t	*pc,
  dk3_printer_t		*pr,
  dkChar const		*vptr
)
{
  int			 back = -1;
  

#line 1105 "dk3prcfg.ctr"
  if(vptr) {
    switch(pr->t_p) {
      case DK3_PRINTER_TYPE_WINDOWS: {
        switch(pr->t_s) {
	  case DK3_PRINTER_TYPE_SOCKET: {
	    back = dk3print_lh_pr_set_timeout(pc,&(pr->det_s),pr->t_s,vptr,0);
	  } break;
	  case DK3_PRINTER_TYPE_LPD:
	  case DK3_PRINTER_TYPE_LPRNG: {
	    back = dk3print_lh_pr_set_timeout(pc,&(pr->det_s),pr->t_s,vptr,0);
	  } break;
	  default: {
	    /* ERROR: Option not available! */
	    dk3app_log_3(
	      pc->app, DK3_LL_ERROR, pc->msg, 42, 43,
	      dk3prcfg_printer_keywords[11]
	    );
	  } break;
	}
      } break;
      case DK3_PRINTER_TYPE_SOCKET: {
        back = dk3print_lh_pr_set_timeout(pc, &(pr->det_p), pr->t_p, vptr, 0);
      } break;
      case DK3_PRINTER_TYPE_LPD:
      case DK3_PRINTER_TYPE_LPRNG: {
        back = dk3print_lh_pr_set_timeout(pc, &(pr->det_p), pr->t_p, vptr, 0);
      } break;
      default: {
        /* ERROR: Option not available! */
	dk3app_log_3(
	  pc->app, DK3_LL_ERROR, pc->msg, 42, 43,
	  dk3prcfg_printer_keywords[11]
	);
      } break;
    }
  } else {
    /* ERROR: Value required! */
    dk3app_log_3(
      pc->app, DK3_LL_ERROR, pc->msg, 35, 36,
      dk3prcfg_printer_keywords[11]
    );
  } 

#line 1147 "dk3prcfg.ctr"
  return back;
}



/**	Set send timeout.
	@param	pc	Print configuration to set up.
	@param	pr	Current printer.
	@param	vptr	New value.
	@return	1 on success, 0 on recoverable, -1 on unrecoverable error.
*/
static
int
dk3print_lh_pr_send_timeout(
  dk3_print_conf_t	*pc,
  dk3_printer_t		*pr,
  dkChar const		*vptr
)
{
  int			 back = -1;
  

#line 1168 "dk3prcfg.ctr"
  if(vptr) {
    switch(pr->t_p) {
      case DK3_PRINTER_TYPE_WINDOWS: {
        switch(pr->t_s) {
	  case DK3_PRINTER_TYPE_SOCKET: {
	    back = dk3print_lh_pr_set_timeout(pc,&(pr->det_s),pr->t_s,vptr,1);
	  } break;
	  case DK3_PRINTER_TYPE_LPD:
	  case DK3_PRINTER_TYPE_LPRNG: {
	    back = dk3print_lh_pr_set_timeout(pc,&(pr->det_s),pr->t_s,vptr,1);
	  } break;
	  default: {
	    /* ERROR: Option not available! */
	    dk3app_log_3(
	      pc->app, DK3_LL_ERROR, pc->msg, 42, 43,
	      dk3prcfg_printer_keywords[12]
	    );
	  } break;
	}
      } break;
      case DK3_PRINTER_TYPE_SOCKET: {
        back = dk3print_lh_pr_set_timeout(pc, &(pr->det_p), pr->t_p, vptr, 1);
      } break;
      case DK3_PRINTER_TYPE_LPD:
      case DK3_PRINTER_TYPE_LPRNG: {
        back = dk3print_lh_pr_set_timeout(pc, &(pr->det_p), pr->t_p, vptr, 1);
      } break;
      default: {
        /* ERROR: Option not available! */
	dk3app_log_3(
	  pc->app, DK3_LL_ERROR, pc->msg, 42, 43,
	  dk3prcfg_printer_keywords[12]
	);
      } break;
    }
  } else {
    /* ERROR: Value required! */
    dk3app_log_3(
      pc->app, DK3_LL_ERROR, pc->msg, 35, 36,
      dk3prcfg_printer_keywords[12]
    );
  } 

#line 1210 "dk3prcfg.ctr"
  return back;
}



/**	Set receive timeout.
	@param	pc	Print configuration to set up.
	@param	pr	Current printer.
	@param	vptr	New value.
	@return	1 on success, 0 on recoverable, -1 on unrecoverable error.
*/
static
int
dk3print_lh_pr_receive_timeout(
  dk3_print_conf_t	*pc,
  dk3_printer_t		*pr,
  dkChar const		*vptr
)
{
  int			 back = -1;
  

#line 1231 "dk3prcfg.ctr"
  if(vptr) {
    switch(pr->t_p) {
      case DK3_PRINTER_TYPE_WINDOWS: {
        switch(pr->t_s) {
	  case DK3_PRINTER_TYPE_SOCKET: {
	    back = dk3print_lh_pr_set_timeout(pc,&(pr->det_s),pr->t_s,vptr,2);
	  } break;
	  case DK3_PRINTER_TYPE_LPD:
	  case DK3_PRINTER_TYPE_LPRNG: {
	    back = dk3print_lh_pr_set_timeout(pc,&(pr->det_s),pr->t_s,vptr,2);
	  } break;
	  default: {
	    /* ERROR: Option not available! */
	    dk3app_log_3(
	      pc->app, DK3_LL_ERROR, pc->msg, 42, 43,
	      dk3prcfg_printer_keywords[13]
	    );
	  } break;
	}
      } break;
      case DK3_PRINTER_TYPE_SOCKET: {
        back = dk3print_lh_pr_set_timeout(pc, &(pr->det_p), pr->t_p, vptr, 2);
      } break;
      case DK3_PRINTER_TYPE_LPD:
      case DK3_PRINTER_TYPE_LPRNG: {
        back = dk3print_lh_pr_set_timeout(pc, &(pr->det_p), pr->t_p, vptr, 2);
      } break;
      default: {
        /* ERROR: Option not available! */
	dk3app_log_3(
	  pc->app, DK3_LL_ERROR, pc->msg, 42, 43,
	  dk3prcfg_printer_keywords[13]
	);
      } break;
    }
  } else {
    /* ERROR: Value required! */
    dk3app_log_3(
      pc->app, DK3_LL_ERROR, pc->msg, 35, 36,
      dk3prcfg_printer_keywords[13]
    );
  } 

#line 1273 "dk3prcfg.ctr"
  return back;
}



/**	Set orderly release.
	@param	pc	Print configuration to set up.
	@param	pr	Printer to set up.
	@param	det	Details for current printer.
	@param	tp	Current printer type.
	@param	vptr	Value text.
	@return	1 on success, 0 on recoverable, -1 on unrecoverable errors.
*/
static
int
dk3print_lh_pr_set_orderly_release(
  dk3_print_conf_t	*pc,
  dk3_printer_t		*pr,
  dk3_printer_details_t	*det,
  int			 tp,
  dkChar const		*vptr
)
{
  int			 back = -1;
  

#line 1298 "dk3prcfg.ctr"
  if(DK3_PRINTER_TYPE_SOCKET == tp) {
    if(vptr) {
      if(dk3str_is_bool(vptr)) {
        (det->sock).ordrel = ((dk3str_is_on(vptr)) ? 0x01 : 0x00);
	back = 1;
      } else {
        /* ERROR: Not a boolean! */
	dk3app_log_i3(pc->app, DK3_LL_ERROR, 146, 147, vptr);
      }
    } else {
      (det->sock).ordrel = 0x01;
      back = 1;
    }
  } 

#line 1312 "dk3prcfg.ctr"
  return back;
}



/**	Set orderly release.
	@param	pc	Print configuration to set up.
	@param	pr	Current printer.
	@param	vptr	New value.
	@return	1 on success, 0 on recoverable, -1 on unrecoverable error.
*/
static
int
dk3print_lh_pr_orderly_release(
  dk3_print_conf_t	*pc,
  dk3_printer_t		*pr,
  dkChar const		*vptr
)
{
  int			 back = -1;
  

#line 1333 "dk3prcfg.ctr"
  switch(pr->t_p) {
    case DK3_PRINTER_TYPE_WINDOWS: {
      switch(pr->t_s) {
        case DK3_PRINTER_TYPE_SOCKET: {
	  back =
	  dk3print_lh_pr_set_orderly_release(pc,pr,&(pr->det_s),pr->t_s,vptr);
	} break;
	default: {
	  /* ERROR: Option not available */
	  dk3app_log_3(
	    pc->app, DK3_LL_ERROR, pc->msg, 42, 43,
	    dk3prcfg_printer_keywords[14]
	  );
	} break;
      }
    } break;
    case DK3_PRINTER_TYPE_SOCKET: {
      back =
      dk3print_lh_pr_set_orderly_release(pc,pr,&(pr->det_p),pr->t_p,vptr);
    } break;
    default: {
      /* ERROR: Option not available */
      dk3app_log_3(
        pc->app, DK3_LL_ERROR, pc->msg, 42, 43,
        dk3prcfg_printer_keywords[14]
      );
    } break;
  } 

#line 1361 "dk3prcfg.ctr"
  return back;
}



/**	Process configuration line for current printer.
	@param	proc	Configuration processor.
	@param	pc	Print configuration to set up.
	@param	pr	Current printer to modify.
	@param	il	Input line to process.
	@return	1 on succuess, 0 on recoverable errors, -1 on
	unrecoverable errors.
*/
static
int
dk3print_lh_printer_line(
  dk3_print_config_processor_t	*proc,
  dk3_print_conf_t		*pc,
  dk3_printer_t			*pr,
  dkChar			*il
)
{
  dkChar		*kptr;		/* Start of key text. */
  dkChar		*vptr;		/* Start of value text. */
  int			 back = -1;
  

#line 1387 "dk3prcfg.ctr"
  kptr = vptr = NULL;
  kptr = dk3str_start(il, NULL);
  if(kptr) {
    vptr = dk3str_chr(kptr, dkT('='));
    if(vptr) {
      *(vptr++) = dkT('\0');
      vptr = dk3str_start(vptr, NULL);
    }
    dk3str_normalize(kptr, NULL, dkT(' '));
    switch(dk3str_array_index(dk3prcfg_printer_keywords, kptr, 0)) {
      case 0: {		

#line 1398 "dk3prcfg.ctr"
        back = dk3print_lh_pr_alias(pc, pr, vptr);
      } break;
      case 1: {		

#line 1401 "dk3prcfg.ctr"
        back = dk3print_lh_pr_type(pc, pr, vptr);
      } break;
      case 2: {		

#line 1404 "dk3prcfg.ctr"
        back = dk3print_lh_pr_host(pc, pr, vptr);
      } break;
      case 3: {		

#line 1407 "dk3prcfg.ctr"
        back = dk3print_lh_pr_queue(pc, pr, vptr);
      } break;
      case 4: {		

#line 1410 "dk3prcfg.ctr"
        back = dk3print_lh_pr_port(pc, pr, vptr);
      } break;
      case 5: {		

#line 1413 "dk3prcfg.ctr"
        back = dk3print_lh_pr_ps(pc, pr, vptr);
      } break;
      case 6: {		

#line 1416 "dk3prcfg.ctr"
        back = dk3print_lh_pr_psl(pc, pr, vptr);
      } break;
      case 7: {		

#line 1419 "dk3prcfg.ctr"
        back = dk3print_lh_pr_default(pc, pr, vptr);
      } break;
      case 8: {		

#line 1422 "dk3prcfg.ctr"
        back = dk3print_lh_pr_snmp_host(pc, pr, vptr);
      } break;
      case 9: {		

#line 1425 "dk3prcfg.ctr"
        back = dk3print_lh_pr_snmp_community(pc, pr, vptr);
      } break;
      case 10: {	

#line 1428 "dk3prcfg.ctr"
        back = dk3print_lh_pr_snmp_version(pc, pr, vptr);
      } break;
      case 11: {	

#line 1431 "dk3prcfg.ctr"
        back = dk3print_lh_pr_connect_timeout(pc, pr, vptr);
      } break;
      case 12: {	

#line 1434 "dk3prcfg.ctr"
        back = dk3print_lh_pr_send_timeout(pc, pr, vptr);
      } break;
      case 13: {	

#line 1437 "dk3prcfg.ctr"
        back = dk3print_lh_pr_receive_timeout(pc, pr, vptr);
      } break;
      case 14: {
        back = dk3print_lh_pr_orderly_release(pc, pr, vptr);
      } break;
      default: {
        /* ERROR: Unknown keyword! */
	dk3app_log_3(pc->app, DK3_LL_ERROR, pc->msg, 64, 65, vptr);
      } break;
    }
  } else {
    back = 1;
  } 

#line 1450 "dk3prcfg.ctr"
  return back;
}



/**	Set alias.
	@param	pc	Print configuration to set up.
	@param	ho	Current host.
	@param	vptr	Text containing the value.
	@return	1 on success, 0 on recoverable, -1 on unrecoverable errors.
*/
static
int
dk3print_lh_ho_alias(
  dk3_print_conf_t	*pc,
  dk3_print_host_t	*ho,
  dkChar const		*vptr
)
{
  dk3_print_host_alias_t	*al;		/* New alias. */
  void				*ptr;		/* Existing alias. */
  int				 back = -1;
  

#line 1473 "dk3prcfg.ctr"
  if(vptr) {
    ptr = dk3sto_it_find_like(pc->iPrintHosts, (void *)vptr, 1);
    if(ptr) {
      /* ERROR: Print host already exists! */
      dk3app_log_3(pc->app, DK3_LL_ERROR, pc->msg, 66, 67, vptr);
    } else {
      ptr = dk3sto_it_find_like(pc->iHostAliases, (void *)vptr, 1);
      if(ptr) {
        /* ERROR: Host alias already exists! */
	dk3app_log_3(pc->app, DK3_LL_ERROR, pc->msg, 68, 69, vptr);
      } else {
        al = dk3_new_app(dk3_print_host_alias_t,1,pc->app);
	if(al) {
	  al->host = ho;
	  al->name = dk3str_dup_app(vptr, pc->app);
	  if(al->name) {
	    if(dk3sto_add(pc->sHostAliases, (void *)al)) {
	      back = 1;
	    } else {
	      dk3print_host_alias_delete(al);
	    }
	  } else {
	    dk3print_host_alias_delete(al);
	  }
	}
      }
    }
  } else {
    /* ERROR: Value required! */
    dk3app_log_3(
      pc->app, DK3_LL_ERROR, pc->msg, 35, 36,
      dk3prcfg_host_keywords[0]
    );
  } 

#line 1507 "dk3prcfg.ctr"
  return back;
}



/**	Set encoding.
	@param	pc	Print configuration to set up.
	@param	ho	Current host.
	@param	vptr	Text containing the value.
	@return	1 on success, 0 on recoverable, -1 on unrecoverable errors.
*/
static
int
dk3print_lh_ho_encoding(
  dk3_print_conf_t	*pc,
  dk3_print_host_t	*ho,
  dkChar const		*vptr
)
{
  int			 back = -1;
  int			 enc;		/* Encoding used on host. */
  

#line 1529 "dk3prcfg.ctr"
  if(vptr) {
    enc = dk3enc_get_text_encoding_app(vptr, pc->app);
    if(-1 != enc) {
      switch(enc) {
        case DK3_FILE_ENCODING_UTF8: {
	  ho->enc = enc; back = 1;
	} break;
	case DK3_FILE_ENCODING_ASCII: {
	  ho->enc = enc; back = 1;
	} break;
	default: {
	  /* ERROR: Illegal encoding for LPD protocol! */
	  dk3app_log_3(pc->app, DK3_LL_ERROR, pc->msg, 70, 71, vptr);
	} break;
      }
    }
  } else {
    /* ERROR: Value required! */
    dk3app_log_3(
      pc->app, DK3_LL_ERROR, pc->msg, 35, 36,
      dk3prcfg_host_keywords[1]
    );
  } 

#line 1552 "dk3prcfg.ctr"
  return back;
}



/**	Set timeout.
	@param	pc	Print configuration to set up.
	@param	ho	Current host.
	@param	vptr	Text containing the value.
	@param	sel	Timeout type selector (0=connect, 1=send, 2=receive).
	@return	1 on success, 0 on recoverable, -1 on unrecoverable errors.
*/
static
int
dk3print_lh_ho_timeout(
  dk3_print_conf_t	*pc,
  dk3_print_host_t	*ho,
  dkChar const		*vptr,
  int			 sel
)
{
  dkChar		 buf[64];	/* Buffer to show existing value. */
  double		 d;		/* Temporary conversion result. */
  int			 back = -1;
  

#line 1577 "dk3prcfg.ctr"
  if(vptr) {
    if(dk3sf_sscanf3(vptr,dk3prcfg_nl[3],&d)) {
      switch(sel) {
        case 2: {
	  if(-1.0 < ho->to_r) {
	    /* Warning: Overwriting receive timeout! */
	    dk3sf_sprintf3(buf,dkT("%lg"),ho->to_r);
	    dk3app_log_3(pc->app, DK3_LL_WARNING, pc->msg, 58, 59, buf);
	  }
	  ho->to_r = d;
	  back = 1;
	} break;
	case 1: {
	  if(-1.0 < ho->to_s) {
	    /* Warning: Overwriting send timeout! */
	    dk3sf_sprintf3(buf,dkT("%lg"),ho->to_s);
	    dk3app_log_3(pc->app, DK3_LL_WARNING, pc->msg, 60, 61, buf);
	  }
	  ho->to_s = d;
	  back = 1;
	} break;
	case 0: {
	  if(-1.0 < ho->to_c) {
	    /* Warning: Overwriting connect timeout! */
	    dk3sf_sprintf3(buf,dkT("%lg"),ho->to_c);
	    dk3app_log_3(pc->app, DK3_LL_WARNING, pc->msg, 62, 63, buf);
	  }
	  ho->to_c = d;
	  back = 1;
	} break;
      }
    } else {
      /* ERROR: Not numeric! */
      dk3app_log_i3(pc->app, DK3_LL_ERROR, 141, 142, vptr);
    }
  } else {
    /* ERROR: Value required! */
    dk3app_log_3(
      pc->app, DK3_LL_ERROR, pc->msg, 35, 36,
      dk3prcfg_host_keywords[2 + sel]
    );
  } 

#line 1619 "dk3prcfg.ctr"
  return back;
}



/**	Set default host.
	@param	pc	Print configuration to set up.
	@param	ho	Current host.
	@param	vptr	Text containing the value.
	@return	1 on success, 0 on recoverable, -1 on unrecoverable errors.
*/
static
int
dk3print_lh_ho_default(
  dk3_print_conf_t	*pc,
  dk3_print_host_t	*ho,
  dkChar const		*vptr
)
{
  int			 back = -1;
  if(vptr) {
    if(dk3str_is_bool(vptr)) {
      if(dk3str_is_on(vptr)) {
        pc->defHost = ho;
	back = 1;
      }
    } else {
      /* ERROR: Not a boolean! */
      dk3app_log_i3(pc->app, DK3_LL_ERROR, 146, 147, vptr);
    }
  } else {
    pc->defHost = ho;
    back = 1;
  }
  return back;
}



/**	Process configuration line for current host.
	@param	proc	Configuration processor.
	@param	pc	Print configuration to set up.
	@param	ho	Current host.
	@param	il	Input line to process.
	@return	1 on succuess, 0 on recoverable errors, -1 on
	unrecoverable errors.
*/
static
int
dk3print_lh_host_line(
  dk3_print_config_processor_t	*proc,
  dk3_print_conf_t		*pc,
  dk3_print_host_t		*ho,
  dkChar			*il
)
{
  dkChar		*kptr;		/* Start of key text. */
  dkChar		*vptr;		/* Start of value text. */
  int			 back = -1;
  

#line 1679 "dk3prcfg.ctr"
  kptr = vptr = NULL;
  kptr = dk3str_start(il, NULL);
  if(kptr) {
    vptr = dk3str_chr(kptr, dkT('='));
    if(vptr) {
      *(vptr++) = dkT('\0');
      vptr = dk3str_start(vptr, NULL);
    }
    dk3str_normalize(kptr, NULL, dkT(' '));
    switch(dk3str_array_index(dk3prcfg_host_keywords, kptr, 0)) {
      case 0: {		

#line 1690 "dk3prcfg.ctr"
        back = dk3print_lh_ho_alias(pc, ho, vptr);
      } break;
      case 1: {		

#line 1693 "dk3prcfg.ctr"
        back = dk3print_lh_ho_encoding(pc, ho, vptr);
      } break;
      case 2: {		

#line 1696 "dk3prcfg.ctr"
        back = dk3print_lh_ho_timeout(pc, ho, vptr, 0);
      } break;
      case 3: {		

#line 1699 "dk3prcfg.ctr"
        back = dk3print_lh_ho_timeout(pc, ho, vptr, 1);
      } break;
      case 4: {		

#line 1702 "dk3prcfg.ctr"
        back = dk3print_lh_ho_timeout(pc, ho, vptr, 2);
      } break;
      case 5: {
        back = dk3print_lh_ho_default(pc, ho, vptr);
      } break;
      default: {	

#line 1708 "dk3prcfg.ctr"
        /* ERROR: Unknown option! */
	dk3app_log_3(pc->app, DK3_LL_ERROR, pc->msg, 64, 65, vptr);
      } break;
    }
  } else {
    back = 1;
  } 

#line 1715 "dk3prcfg.ctr"
  return back;
}



/**	Handler function to process one configuration line.
	@param	obj	Print configuration processor.
	@param	il	Input line to process.
	@return	1 on success, 0 on recoverable error, -1 on unrecoverable
	error.
*/
static
int
dk3print_config_line_handler(void *obj, dkChar *il)
{
  dk3_print_config_processor_t	*pr;		/* Print conf processor. */
  dk3_print_conf_t		*pc;		/* Configuration to set up. */
  dkChar			*p1;		/* Start of text line. */
  int				 back	= 1;
  

#line 1735 "dk3prcfg.ctr"
  pr = (dk3_print_config_processor_t *)obj;
  pc = pr->pc;
  p1 = dk3str_start(il, NULL);
  if(p1) {
    dk3str_delnl(p1);		

#line 1740 "dk3prcfg.ctr"
    if(dkT('#') != *p1) {	

#line 1741 "dk3prcfg.ctr"
      if(dkT('[') == *p1) {	

#line 1742 "dk3prcfg.ctr"
        pr->pr = NULL;
	pr->ho = NULL;
	back = dk3print_lh_printer_or_host(pr, pc, p1);
      } else {			

#line 1746 "dk3prcfg.ctr"
        if(pr->pr) {		

#line 1747 "dk3prcfg.ctr"
	  back = dk3print_lh_printer_line(pr, pc, pr->pr, p1);
	} else {
	  if(pr->ho) {		

#line 1750 "dk3prcfg.ctr"
	    back = dk3print_lh_host_line(pr, pc, pr->ho, p1);
	  } else {		

#line 1752 "dk3prcfg.ctr"
	    /* WARNING: Line not belonging to printer or host! */
	    dk3app_log_1(pc->app, DK3_LL_WARNING, pc->msg, 72);
	  }
	}
      }
    }
  } else {			

#line 1759 "dk3prcfg.ctr"
  } 

#line 1760 "dk3prcfg.ctr"
  return back;
}



/**	Process one configuration file.
	@param	pc	Configuration to set up.
	@param	fn	File name to apply to configuration.
	@return	1 on success, 0 on error.
*/
static
int
dk3print_process_one_config_file(dk3_print_conf_t *pc, dkChar const *fn)
{
  dkChar			 buf[1024];		/* Input line buffer. */
  dk3_print_config_processor_t	 pr;			/* Config processor. */
  dkChar const			*oldsrcname = NULL;	/* Old source file. */
  unsigned long			 oldsrcline = 0UL;	/* Old source line. */
  int				 se;			/* System encoding. */
  int				 de;			/* Default encoding. */
  int				 back = 0;
  

#line 1782 "dk3prcfg.ctr"
  if(pc->app) {
    oldsrcname = dk3app_get_source_file(pc->app);
    oldsrcline = dk3app_get_source_line(pc->app);
    dk3app_set_source_file(pc->app, fn);
    dk3app_set_source_line(pc->app, 0UL);
    se = dk3app_get_encoding(pc->app);
    de = dk3app_get_input_file_encoding(pc->app);
  } else {
#if DK3_ON_WINDOWS
    se = dk3enc_get_encoding(NULL);
    de = DK3_ENCODING_PLAIN;
#else
    se = de = dk3enc_get_encoding(NULL);
#endif
  }
  dk3print_initialize_print_config_processor(&pr, pc);
  back = dk3stream_process_filename_lines_app(
    (void *)(&pr),
    dk3print_config_line_handler,
    fn,
    buf,
    DK3_SIZEOF(buf,dkChar),
    se,
    de,
    pc->app
  );
  if(pc->app) {
    dk3app_set_source_file(pc->app, oldsrcname);
    dk3app_set_source_line(pc->app, oldsrcline);
  } 

#line 1812 "dk3prcfg.ctr"
  return back;
}



int
dk3print_read_config_files(dk3_print_conf_t *pc)
{
  dk3_search_t		*srch;		/* Configuration file search results. */
  dkChar const		*fn;		/* Current file name to process. */
  int			 back = 1;
  

#line 1824 "dk3prcfg.ctr"
  if(pc) {
    if(pc->app) {
      srch = dk3app_find_config_file(pc->app, dk3prcfg_nl[0], 0);
      if(srch) {
        dk3search_reset(srch);
	while(NULL != (fn = dk3search_next(srch))) { 

#line 1830 "dk3prcfg.ctr"
	  if(!dk3print_process_one_config_file(pc, fn)) {
	    back = 0;
	  }
	}
        dk3search_close(srch);
      }
    }
  } 

#line 1838 "dk3prcfg.ctr"
  return back;
}


