/* Copyright (C) 2012-2020, Dirk Krause SPDX-License-Identifier: BSD-3-Clause */ /* WARNING: This file was generated by the dkct program (see http://dktools.sourceforge.net/ for details). 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: itaconf.ctr */ /** @file itaconf.c The itaconf module. */ #line 10 "itaconf.ctr" #include "dk3all.h" #include "itadmin.h" #line 17 "itaconf.ctr" /** Key names in configuration file. */ static dkChar const * const itadmin_config_keys[] = { /* 0 */ dkT("database-host"), /* 1 */ dkT("database-name"), /* 2 */ dkT("database-credentials-file"), /* 3 */ dkT("dhcpd.conf-vlan"), /* 4 */ dkT("organization"), /* 5 */ dkT("organizational-unit"), /* 6 */ dkT("administrator-name"), /* 7 */ dkT("create-dhcpd.conf"), /* 8 */ dkT("database-type"), /* 9 */ dkT("ldap-base"), /* 10 */ dkT("use-koma-script"), /* 11 */ dkT("msft-release-lease-on-shutdown"), /* 12 */ dkT("marker-point"), /* 13 */ dkT("marker-vlan"), /* 14 */ dkT("marker-subnet"), /* 15 */ dkT("marker-group"), /* 16 */ dkT("marker-pool"), /* 17 */ dkT("marker-host"), NULL #line 82 "itaconf.ctr" }; /** Items for "msft release lease on shutdown". */ static const char * const msft_release_keys[] = { "none", "pool", "all", NULL }; /** Names of SQL database types. */ static dkChar const * const itadmin_config_database_types[] = { /* 0 */ dkT("MySQL"), NULL #line 102 "itaconf.ctr" }; /** Keywords to watch out for when processing a credential file. Typically this is a .my.cnf file. */ static dkChar const * const itadmin_config_credential_keys[] = { /* 0 */ dkT("client"), /* 1 */ dkT("user"), /* 2 */ dkT("password"), NULL #line 124 "itaconf.ctr" }; /** Set one string entry in job structure. @param job Job structure to modify. @param resptr Pointer to result pointer. @param srcptr Source string. @return 1 on success, 0 on error. */ static int itadmin_config_set_string( itadmin_job *job, dkChar const **resptr, dkChar const *srcptr ) { dkChar const *np; /* New string duplicate. */ int back = 0; #line 145 "itaconf.ctr" np = dk3str_dup_app(srcptr,job->app); if(np) { dk3_release(*resptr); *resptr = np; back = 1; } else { /* ERROR: Memory allocation failed! */ } #line 153 "itaconf.ctr" return back; } /** Configure a boolean value setting. @param job Job structure. @param bp Pointer to result variable. @param defv Default value, used for empty or non-boolean strings. @param txt Configuration text. @return 1 on success, 0 on error. */ static int itadmin_config_set_bool(itadmin_job *job, int *bp, int defv, dkChar const *txt) { dkChar lb[ITADMIN_CONFIG_LINE_SIZE]; /* Copy of value. */ dkChar *p1; /* Start of text in copy. */ int back = 1; #line 173 "itaconf.ctr" if(txt) { p1 = dk3str_start(txt, NULL); if(p1) { if(dk3str_len(p1) < DK3_SIZEOF(lb,dkChar)) { dk3str_cpy_not_overlapped(lb, p1); dk3str_normalize(lb,NULL,dkT(' ')); if(dk3str_is_bool(lb)) { *bp = ((dk3str_is_on(lb)) ? 1 : 0); } else { #line 182 "itaconf.ctr" back = 0; *bp = defv; /* ERROR: Not a boolean! */ dk3app_log_3(job->app, DK3_LL_ERROR, job->msg, 106, 107, lb); } } else { #line 188 "itaconf.ctr" back = 0; *bp = defv; /* ERROR: Text too long! */ dk3app_log_3(job->app, DK3_LL_ERROR, job->msg, 108, 109, p1); } } else { #line 194 "itaconf.ctr" *bp = defv; } } else { #line 197 "itaconf.ctr" *bp = defv; } #line 199 "itaconf.ctr" return back; } /** Set database type. @param job Job structure. @param txt Text for database type (at this time only "MySQL" can be used). @return 1 on success, 0 on error. */ static int itadmin_config_set_dbtype(itadmin_job *job, dkChar const *txt) { int back = 0; int i; /* Index of type in array of known types. */ if(txt) { i = dk3str_array_index(itadmin_config_database_types, txt, 0); if(i >= 0) { job->dbt = i; back = 1; } else { /* ERROR: No such database type! */ dk3app_log_3(job->app, DK3_LL_ERROR, job->msg, 110, 111, txt); } } else { /* ERROR: Empty text. */ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 112); } return back; } /** Handler function for one configuration file line. @param obj Reader object. @param il Input line to process (constant text). @return 1 for OK, 0 for recoverable error, -1 for abort. */ static int itadmin_config_const_line_handler(void *obj, dkChar const *il) { dkChar line[ITADMIN_CONFIG_LINE_SIZE]; /* Private copy of line.*/ itadmin_job *job; dkChar *p1; /* Start of line. */ dkChar *p2; /* Start of value in line. */ int back = 0; #line 250 "itaconf.ctr" if((obj) && (il)) { job = (itadmin_job *)obj; if(dk3str_len(il) < DK3_SIZEOF(line,dkChar)) { dk3str_cpy_not_overlapped(line, il); dk3str_delnl(line); p1 = dk3str_start(line, NULL); if(p1) { if(*p1 == dkT('#')) { back = 1; /* Comment line. */ } else { p2 = dk3str_chr(p1, dkT('=')); if(p2) { *(p2++) = dkT('\0'); p2 = dk3str_start(p2, NULL); if(p2) { dk3str_normalize(p1, NULL, dkT('-')); switch(dk3str_array_index(itadmin_config_keys, p1, 0)) { case 0: { /* database host */ back = itadmin_config_set_string(job, &(job->dbhn), p2); } break; case 1: { /* database name */ back = itadmin_config_set_string(job, &(job->dbn), p2); } break; case 2: { /* credentials file */ back = itadmin_config_set_string(job, &(job->dbcf), p2); } break; case 3: { /* VLAN name */ back = itadmin_config_set_string(job, &(job->vlan), p2); if(back) { job->f_dh = 1; } } break; case 4: { /* organization */ back = itadmin_config_set_string(job, &(job->org), p2); } break; case 5: { /* organizational unit */ back = itadmin_config_set_string(job, &(job->ou), p2); } break; case 6: { /* administrator name */ back = itadmin_config_set_string(job, &(job->admn), p2); } break; case 7: { back = itadmin_config_set_bool(job, &(job->f_dh), 1, p2); } break; case 8: { back = itadmin_config_set_dbtype(job, p2); } break; case 9: { dk3str_normalize(p2, NULL, ' '); back = itadmin_config_set_string(job, &(job->ldapb), p2); } break; case 10: { back = itadmin_config_set_bool(job, &(job->ukoma), 0, p2); } break; case 11: { switch(dk3str_array_index(msft_release_keys, p2, 0)) { case 0: { job->rel = 0; back = 1; } break; case 1: { job->rel = 1; back = 1; } break; case 2: { job->rel = 2; back = 1; } break; default: { /* ##### ERROR: Illegal keyword */ } break; } } break; case 12: { back = itadmin_config_set_bool(job, &(job->m_p), 1, p2); } break; case 13: { back = itadmin_config_set_bool(job, &(job->m_vl), 1, p2); } break; case 14: { back = itadmin_config_set_bool(job, &(job->m_sn), 1, p2); } break; case 15: { back = itadmin_config_set_bool(job, &(job->m_gr), 1, p2); } break; case 16: { back = itadmin_config_set_bool(job, &(job->m_po), 1, p2); } break; case 17: { back = itadmin_config_set_bool(job, &(job->m_ho), 0, p2); } break; default: { /* ERROR: Unknown option ... */ dk3app_log_3(job->app, DK3_LL_ERROR, job->msg, 113, 114, p1); } break; } } else { /* ERROR: No value! */ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 115); } } else { /* ERROR: Missing '=' */ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 115); } } } else { back = 1; /* Empty line. */ } } else { /* ERROR: Input line too long! */ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 116); } } #line 360 "itaconf.ctr" return back; } /** Handler function for one configuration file line. @param obj Reader object. @param il Input line to process. @return 1 for OK, 0 for recoverable error, -1 for abort. */ static int itadmin_cred_file_const_line_handler(void *obj, dkChar const *il) { dkChar line[ITADMIN_CONFIG_LINE_SIZE]; /* Copy of line. */ dkChar *p1; /* Start of key. */ dkChar *p2; /* Start of value. */ itadmin_cred_reader *reader; /* Help structure to read creds. */ int back = 0; #line 380 "itaconf.ctr" if((obj) && (il)) { #line 381 "itaconf.ctr" reader = (itadmin_cred_reader *)obj; if(dk3str_len(il) < DK3_SIZEOF(line,dkChar)) { #line 383 "itaconf.ctr" dk3str_cpy_not_overlapped(line, il); dk3str_delnl(line); p1 = dk3str_start(line, NULL); if(p1) { #line 387 "itaconf.ctr" if(*p1 == dkT('#')) { #line 388 "itaconf.ctr" back = 1; /* Ignore comment. */ } else { #line 390 "itaconf.ctr" if(*p1 == dkT('[')) { #line 391 "itaconf.ctr" reader->f_clnt = 0; p1++; p2 = dk3str_chr(p1, dkT(']')); if(p2) { #line 395 "itaconf.ctr" back = 1; *p2 = dkT('\0'); if(dk3str_cmp(p1, itadmin_config_credential_keys[0]) == 0) { reader->f_clnt = 1; } } else { #line 401 "itaconf.ctr" /* ERROR: Syntax! */ dk3app_log_1( (reader->job)->app, DK3_LL_ERROR, (reader->job)->msg, 117 ); } } else { #line 407 "itaconf.ctr" back = 1; p2 = dk3str_chr(p1, dkT('=')); if(p2) { #line 410 "itaconf.ctr" *(p2++) = dkT('\0'); p2 = dk3str_start(p2, NULL); if(p2) { #line 413 "itaconf.ctr" dk3str_normalize(p1,NULL,dkT(' ')); switch(dk3str_array_index(itadmin_config_credential_keys,p1,0)) { case 1: { /* user */ #line 417 "itaconf.ctr" back = itadmin_config_set_string( reader->job, &((reader->job)->dbus), p2 ); } break; case 2: { /* password */ #line 422 "itaconf.ctr" back = itadmin_config_set_string( reader->job, &((reader->job)->dbpw), p2 ); } break; } } else { #line 428 "itaconf.ctr" /* Empty key. */ } } else { #line 431 "itaconf.ctr" /* Not a key=value line. */ } } } } else { #line 436 "itaconf.ctr" back = 1; /* Ignore empty line. */ } } else { #line 439 "itaconf.ctr" /* ERROR: Line too long! */ dk3app_log_1( (reader->job)->app, DK3_LL_ERROR, (reader->job)->msg, 116 ); } } else { #line 445 "itaconf.ctr" } #line 446 "itaconf.ctr" return back; } /** Handler function for one configuration file line. @param obj Reader object. @param il Input line to process. @return 1 for OK, 0 for recoverable error, -1 for abort. */ static int itadmin_cred_file_line_handler(void *obj, dkChar *il) { int back; back = itadmin_cred_file_const_line_handler(obj, il); return back; } /** Handler function for one configuration file line. @param obj Reader object. @param il Input line to process. @return 1 for OK, 0 for recoverable error, -1 for abort. */ static int itadmin_config_line_handler(void *obj, dkChar *il) { int back; back = itadmin_config_const_line_handler(obj, il); return back; } /** Process one configuration file. @param job Job structure. @param fn File name to process. @return 1 on success, 0 on error. */ static int itadmin_config_process_one_file(itadmin_job *job, dkChar const *fn) { dkChar line[ITADMIN_CONFIG_LINE_SIZE]; /* Copy of line. */ int back = 0; #line 495 "itaconf.ctr" back = dk3stream_process_filename_lines_app( (void *)job, itadmin_config_line_handler, fn, line, DK3_SIZEOF(line,dkChar), dk3app_get_encoding(job->app), dk3app_get_input_file_encoding(job->app), job->app ); if(back < 1) { back = 0; } #line 508 "itaconf.ctr" return back; } /** Read credentials file to obtain database user name and password. @param job Job structure. @return 1 on success, 0 on error. */ static int itadmin_config_read_credentials(itadmin_job *job) { dkChar fnb[DK3_MAX_PATH]; /* File name buffer. */ dkChar line[ITADMIN_CONFIG_LINE_SIZE]; /* Input line buffer. */ itadmin_cred_reader reader; /* Helper structure to read creds. */ int back = 0; #line 526 "itaconf.ctr" if(dk3str_len(job->dbcf) < DK3_SIZEOF(fnb,dkChar)) { dk3str_cpy_not_overlapped(fnb, job->dbcf); dk3str_correct_filename(fnb); if(dk3sf_must_expand(fnb)) { /* ERROR: File name must not contain wildcards! */ dk3app_log_3(job->app, DK3_LL_ERROR, job->msg, 118, 119, fnb); } else { if(!dk3str_is_abs_path(fnb)) { /* WARNING: File name should be specified as absolute path! */ dk3app_log_3(job->app, DK3_LL_WARNING, job->msg, 120, 121, fnb); } reader.job = job; reader.f_clnt = 1; #line 539 "itaconf.ctr" back = dk3stream_process_filename_sanitized_lines_app( (void *)(&reader), itadmin_cred_file_line_handler, fnb, line, DK3_SIZEOF(line,dkChar), dk3app_get_encoding(job->app), dk3app_get_input_file_encoding(job->app), job->app ); } } else { /* ERROR: File name too long! */ dk3app_log_i3(job->app, DK3_LL_ERROR, 65, 66, job->dbcf); } if(job->ec) { #line 555 "itaconf.ctr" back = 0; } #line 557 "itaconf.ctr" return back; } int itadmin_config_read(itadmin_job *job) { dkChar fnb[DK3_MAX_PATH]; /* Copy of file name. */ dk3_search_t *res; /* Search result, config. */ dk3_dir_t *fne; /* File name expander. */ dk3_stat_t const *es; /* Expandend file status. */ dkChar const *fn; /* File name. */ dkChar const *en; /* Expanded file name. */ dkChar const *fnorig; /* Original file name. */ int back = 0; int have_file = 0; /* Flag: File found. */ int have_error = 0; /* Flag: Error occured. */ int argc; /* Number of file names. */ int i; /* Current file name index. */ #line 578 "itaconf.ctr" /* Process default configuration files. */ res = dk3app_find_config_file(job->app, (job->noloc)[4], 0); if(res) { dk3search_reset(res); while((fn = dk3search_next(res)) != NULL) { have_file = 1; if(!itadmin_config_process_one_file(job, fn)) { have_error = 1; } } dk3search_close(res); } /* Process configuration file(s) specified on command line. */ argc = dk3opt_get_num_args(job->opt); for(i = 0; i < argc; i++) { fnorig = dk3opt_get_arg(job->opt, i); if(fnorig) { if(dk3str_len(fnorig) < DK3_SIZEOF(fnb,dkChar)) { dk3str_cpy_not_overlapped(fnb, fnorig); dk3str_correct_filename(fnb); if(dk3sf_must_expand(fnb)) { fne = dk3dir_fne_open_app(fnb, job->app); if(fne) { while(dk3dir_get_next_file(fne)) { en = dk3dir_get_fullname(fne); es = dk3dir_get_stat(fne); if((en) && (es)) { switch((es->ft) & (~(DK3_FT_SYMLINK))) { case DK3_FT_REGULAR: { have_file = 1; if(!itadmin_config_process_one_file(job, fnb)) { have_error = 1; } } break; default: { have_error = 1; /* ERROR: Wrong file type! */ dk3app_log_i3(job->app, DK3_LL_ERROR, 255, 256, en); } break; } } else { /* BUG: No complete information available! */ } } dk3dir_close(fne); } else { /* ERROR: Failed to expand file name! */ } } else { have_file = 1; if(!itadmin_config_process_one_file(job, fnb)) { have_error = 1; } } } else { /* ERROR: File name fnorig too long! */ dk3app_log_i3(job->app, DK3_LL_ERROR, 65, 66, fnorig); } } else { /* BUG: No pointer returned! */ } } /* Final tests and error messages. */ if(have_file) { #line 648 "itaconf.ctr" if(!(have_error)) { #line 649 "itaconf.ctr" back = 1; if(!(job->dbhn)) { #line 651 "itaconf.ctr" /* ERROR: Missing database host name! */ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 122); back = 0; } if(!(job->dbn)) { #line 656 "itaconf.ctr" /* ERROR: Missing database name! */ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 123); back = 0; } if(!(job->vlan)) { #line 661 "itaconf.ctr" /* Warning: Missing VLAN name! */ dk3app_log_1(job->app, DK3_LL_WARNING, job->msg, 124); } if(!(job->org)) { #line 665 "itaconf.ctr" /* ERROR: Missing organization name! */ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 125); back = 0; } if(!(job->ou)) { #line 670 "itaconf.ctr" /* ERROR: Missing organizational unit name! */ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 126); back = 0; } if(!(job->admn)) { #line 675 "itaconf.ctr" /* ERROR: Missing administrator name! */ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 127); back = 0; } if(!(job->dbcf)) { #line 680 "itaconf.ctr" /* ERROR: Missing database credentials file name! */ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 128); back = 0; } else { #line 684 "itaconf.ctr" if(back) { #line 685 "itaconf.ctr" back = itadmin_config_read_credentials(job); if(back) { if(!(job->dbus)) { #line 688 "itaconf.ctr" /* ERROR: Missing database user name! */ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 129); back = 0; } if(!(job->dbpw)) { #line 693 "itaconf.ctr" /* ERROR: Missing database user password! */ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 130); back = 0; } } } } if(back) { if(!(job->ukoma)) { if(dk3str_casecmp(dkT("de"), dk3app_get_language(job->app)) == 0) { dk3app_log_1(job->app, DK3_LL_INFO, job->msg, 302); } } } if(!(back)) { dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 132); } } else { #line 711 "itaconf.ctr" } } else { #line 713 "itaconf.ctr" /* ERROR: No configuration file found for processing! */ dk3app_log_1(job->app, DK3_LL_ERROR, job->msg, 131); } #line 716 "itaconf.ctr" return back; }