1 #ident "$Id: conf_mg.c,v 4.19 2009/03/19 15:13:53 gert Exp $ Copyright (c) Gert Doering" 2 3 /* conf_mg.c 4 * 5 * configuration defaults / configuration reading code for mgetty 6 */ 7 8 #include <stdio.h> 9 #include <string.h> 10 #include <unistd.h> 11 12 #include "mgetty.h" 13 #include "policy.h" 14 #include "syslibs.h" 15 #include "tio.h" 16 17 #include "config.h" 18 #include "conf_mg.h" 19 20 #include "version.h" 21 char * mgetty_version = VERSION_LONG; /* version.h */ 22 23 #ifndef MODEM_CHECK_TIME 24 # define MODEM_CHECK_TIME -1 /* no check */ 25 #endif 26 27 #ifndef FAX_RECV_SWITCHBD 28 #define FAX_RECV_SWITCHBD 0 /* no switching */ 29 #endif 30 31 #ifndef FAX_FILE_MODE 32 #define FAX_FILE_MODE -1 /* controlled by umask */ 33 #endif 34 35 /* initialize the modem - MODEM_INIT_STRING defined in policy.h 36 */ 37 static char * def_init_chat_seq[] = { "", 38 "\\dATQ0V1H0", "OK", 39 MODEM_INIT_STRING, "OK", 40 NULL }; 41 42 /* "force init" the modem (DLE ETX for voice modems, +++ATH0 for all others) 43 */ 44 static char * def_force_init_chat_seq[] = { "", 45 "\\d\020\03\\d\\d\\d+++\\d\\d\\d\r\\dATQ0V1H0", 46 "OK", NULL }; 47 48 /* default way to answer the phone... 49 */ 50 static char * def_answer_chat_seq[] = 51 { "", "ATA", "CONNECT", "\\c", "\n", NULL }; 52 53 /* this is the default configuration... 54 */ 55 56 struct conf_data_mgetty c = { 57 { "speed", {DEFAULT_PORTSPEED}, CT_INT, C_PRESET }, 58 { "switchbd", {FAX_RECV_SWITCHBD}, CT_INT, C_PRESET }, 59 { "direct", {FALSE}, CT_BOOL, C_PRESET }, 60 { "blocking", {FALSE}, CT_BOOL, C_PRESET }, 61 62 { "port-owner", {(p_int) DEVICE_OWNER}, CT_STRING, C_PRESET }, 63 #ifdef DEVICE_GROUP 64 { "port-group", {(p_int) DEVICE_GROUP}, CT_STRING, C_PRESET }, 65 #else 66 { "port-group", {0}, CT_STRING, C_EMPTY }, 67 #endif 68 { "port-mode", {FILE_MODE}, CT_INT, C_PRESET }, 69 70 { "toggle-dtr", {TRUE}, CT_BOOL, C_PRESET }, 71 { "toggle-dtr-waittime", {500}, CT_INT, C_PRESET }, 72 { "need-dsr", {FALSE}, CT_BOOL, C_PRESET }, 73 { "data-only", {FALSE}, CT_BOOL, C_PRESET }, 74 { "fax-only", {FALSE}, CT_BOOL, C_PRESET }, 75 { "modem-type", {(p_int) DEFAULT_MODEMTYPE}, CT_STRING, C_PRESET }, 76 { "modem-quirks", {0}, CT_INT, C_EMPTY }, 77 { "init-chat", {0}, CT_CHAT, C_EMPTY }, 78 { "force-init-chat", {0}, CT_CHAT, C_EMPTY }, 79 { "post-init-chat", {0}, CT_CHAT, C_EMPTY }, 80 { "data-flow", {DATA_FLOW}, CT_FLOWL, C_PRESET }, 81 { "fax-send-flow", {FAXSEND_FLOW}, CT_FLOWL, C_PRESET }, 82 { "fax-rec-flow", {FAXREC_FLOW}, CT_FLOWL, C_PRESET }, 83 84 { "modem-check-time", {MODEM_CHECK_TIME}, CT_INT, C_PRESET }, 85 { "rings", {1}, CT_INT, C_PRESET }, 86 { "msn-list", {(p_int) NULL}, CT_CHAT, C_EMPTY }, 87 { "get-cnd-chat", {0}, CT_CHAT, C_EMPTY }, 88 { "cnd-program", {(p_int) NULL}, CT_STRING, C_EMPTY }, 89 { "answer-chat", {0}, CT_CHAT, C_EMPTY }, 90 { "answer-chat-timeout", {80}, CT_INT, C_PRESET }, 91 { "autobauding", {FALSE}, CT_BOOL, C_PRESET }, 92 93 { "ringback", {FALSE}, CT_BOOL, C_PRESET }, 94 { "ringback-time", {30}, CT_INT, C_PRESET }, 95 96 { "ignore-carrier", {FALSE}, CT_BOOL, C_PRESET }, 97 { "issue-file", {(p_int)"/etc/issue"}, CT_STRING, C_PRESET }, 98 { "prompt-waittime", {500}, CT_INT, C_PRESET }, 99 { "login-prompt", {(p_int) LOGIN_PROMPT}, CT_STRING, C_PRESET }, 100 #ifdef MAX_LOGIN_TIME 101 { "login-time", {MAX_LOGIN_TIME}, CT_INT, C_PRESET }, 102 #else 103 { "login-time", {0}, CT_INT, C_EMPTY }, 104 #endif 105 { "fido-send-emsi", {TRUE}, CT_BOOL, C_PRESET }, 106 { "login-env-ttyprompt-hack", {FALSE}, CT_BOOL, C_PRESET }, 107 108 #ifdef LOGIN_CFG_FILE 109 { "login-conf-file", {(p_int) LOGIN_CFG_FILE}, CT_STRING, C_PRESET }, 110 #else 111 { "login-conf-file", {0}, CT_STRING, C_EMPTY }, 112 #endif 113 114 { "fax-id", {(p_int)FAX_STATION_ID}, CT_STRING, C_PRESET }, 115 { "fax-min-speed", {0}, CT_INT, C_PRESET }, 116 { "fax-max-speed", {14400}, CT_INT, C_PRESET }, 117 { "fax-server-file", {0}, CT_STRING, C_EMPTY }, 118 { "diskspace", {MINFREESPACE}, CT_INT, C_PRESET }, 119 #ifdef MAIL_TO 120 { "notify", {(p_int)MAIL_TO}, CT_STRING, C_PRESET }, 121 #else 122 { "notify", {0}, CT_STRING, C_EMPTY }, 123 #endif 124 { "fax-owner", {(p_int)FAX_IN_OWNER}, CT_STRING, C_PRESET }, 125 #ifdef FAX_IN_GROUP 126 { "fax-group", {(p_int)FAX_IN_GROUP}, CT_STRING, C_PRESET }, 127 #else 128 { "fax-group", {0}, CT_STRING, C_EMPTY }, 129 #endif 130 { "fax-mode", {FAX_FILE_MODE}, CT_INT, C_PRESET }, 131 #ifdef __STDC__ 132 { "fax-spool-in", {(p_int) FAX_SPOOL_IN ":/tmp"}, CT_STRING, C_PRESET }, 133 #else 134 { "fax-spool-in", {(p_int) FAX_SPOOL_IN}, CT_STRING, C_PRESET }, 135 #endif 136 137 { "debug", {LOG_LEVEL}, CT_INT, C_PRESET }, 138 139 { "statistics-chat", {0}, CT_CHAT, C_EMPTY }, 140 { "statistics-file", {0}, CT_STRING, C_EMPTY }, 141 { "gettydefs", {(p_int)GETTYDEFS_DEFAULT_TAG}, CT_STRING, C_PRESET }, 142 { "term", {0}, CT_STRING, C_EMPTY }, 143 144 { NULL, {0}, CT_STRING, C_EMPTY }}; 145 146 /* 147 * exit_usage() - exit with usage display 148 */ 149 150 void exit_usage _P1((code), int code ) 151 { 152 #ifdef USE_GETTYDEFS 153 lprintf( L_FATAL, "Usage: mgetty [-x debug] [-s speed] [-r] line [gettydefentry]" ); 154 #else 155 lprintf( L_FATAL, "Usage: mgetty [-x debug] [-s speed] [-r] line" ); 156 #endif 157 exit(code); 158 } 159 160 int mgetty_parse_args _P2( (argc,argv), int argc, char ** argv ) 161 { 162 int opt; 163 #ifdef USE_GETTYDEFS 164 extern boolean verbose; 165 #endif 166 167 /* sanity check: 168 * make sure that structs-in-struct can be handled exactly as if 169 * packed in array (get_config relies on it!) 170 */ 171 conf_data c_a[2]; 172 if ( ( (char *)&c_a[1] - (char *)&c_a[0] ) != 173 ( (char *)&c.switchbd - (char *)&c.speed ) ) 174 { 175 fprintf( stderr, "ERROR: config table size mixup. contact author\n" ); 176 exit(99); 177 } 178 179 /* initialize a few things that can't be done statically */ 180 c.init_chat.d.p = (void *) def_init_chat_seq; 181 c.init_chat.flags = C_PRESET; 182 183 c.force_init_chat.d.p = (void *) def_force_init_chat_seq; 184 c.force_init_chat.flags = C_PRESET; 185 186 c.answer_chat.d.p = (void *) def_answer_chat_seq; 187 c.answer_chat.flags = C_PRESET; 188 189 190 /* get command line arguments */ 191 192 /* some magic done by the command's name */ 193 if ( strcmp( get_basename( argv[0] ), "getty" ) == 0 ) 194 { 195 conf_set_bool( &c.blocking, TRUE ); 196 conf_set_bool( &c.direct_line, TRUE ); 197 } 198 199 while ((opt = getopt(argc, argv, "c:x:s:rp:n:R:i:DC:FS:k:m:I:baV")) != EOF) 200 { 201 switch (opt) 202 { 203 case 'c': /* check */ 204 #ifdef USE_GETTYDEFS 205 verbose = TRUE; 206 dumpgettydefs(optarg); 207 exit(0); 208 #else 209 lprintf( L_FATAL, "gettydefs not supported\n"); 210 exit_usage(2); 211 #endif 212 case 'k': /* kbytes free on disk */ 213 conf_set_int( &c.diskspace, atol(optarg) ); 214 break; 215 case 'x': /* log level */ 216 conf_set_int( &c.debug, atoi(optarg) ); 217 log_set_llevel( c_int(debug) ); 218 break; 219 case 's': /* port speed */ 220 conf_set_int( &c.speed, atoi(optarg) ); 221 break; 222 case 'r': /* direct line (nullmodem) */ 223 conf_set_int( &c.direct_line, TRUE ); 224 break; 225 case 'p': /* login prompt */ 226 conf_set_string( &c.login_prompt, optarg ); 227 break; 228 case 'n': /* ring counter */ 229 conf_set_int( &c.rings_wanted, atoi(optarg) ); 230 break; 231 case 'R': /* ringback timer */ 232 conf_set_bool( &c.ringback, TRUE ); 233 conf_set_int( &c.ringback_time, atoi(optarg) ); 234 break; 235 case 'i': /* use different issue file */ 236 conf_set_string( &c.issue_file, optarg ); 237 break; 238 case 'D': /* switch off fax */ 239 conf_set_bool( &c.data_only, TRUE ); 240 break; 241 case 'F': /* switch off data-mode (security!) */ 242 conf_set_bool( &c.fax_only, TRUE ); 243 break; 244 case 'C': /* set modem mode (fax/data) */ 245 conf_set_string( &c.modem_type, optarg ); 246 break; 247 case 'S': /* fax poll file to send */ 248 conf_set_string( &c.fax_server_file, optarg ); 249 break; 250 case 'I': /* local station ID */ 251 conf_set_string( &c.station_id, optarg); 252 break; 253 case 'b': /* open port in blocking mode */ 254 conf_set_bool( &c.blocking, TRUE ); 255 break; 256 case 'a': /* autobauding */ 257 conf_set_bool( &c.autobauding, TRUE ); 258 break; 259 case 'm': /* modem init sequence */ 260 c.init_chat.flags = C_OVERRIDE; 261 c.init_chat.d.p = conf_get_chat( optarg ); 262 break; 263 case 'V': /* show version number */ 264 printf("\nmgetty+sendfax by Gert Doering\n%s\n\n", 265 mgetty_version); 266 printf("log file written to '"); 267 printf(LOG_PATH, "<ttyX>"); 268 #ifdef MGETTY_CONFIG 269 printf("'\nconfig file read from '%s", 270 makepath( MGETTY_CONFIG, CONFDIR )); 271 #endif 272 printf("'\n\n"); 273 exit(0); 274 case '?': 275 exit_usage(2); 276 break; 277 } 278 } 279 280 return NOERROR; 281 } 282 283 284 /* get mgetty configuration from file (if configured) 285 */ 286 void mgetty_get_config _P1( (port), char * port ) 287 { 288 #ifdef MGETTY_CONFIG 289 lprintf( L_NOISE, "reading configuration data for port '%s'", port ); 290 get_config( makepath( MGETTY_CONFIG, CONFDIR ), 291 (conf_data *)&c, "port", port ); 292 #else 293 lprintf( L_NOISE, "not reading config file, not configured" ); 294 #endif 295 296 /* tell log subsystem about new log level */ 297 log_set_llevel( c_int(debug) ); 298 299 /* tell getdisk.c about desired disk space (in kbytes) */ 300 minfreespace = c_int(diskspace); 301 302 /* sanity checks */ 303 if ( tio_check_speed( c_int(speed) ) < 0 ) 304 { 305 lprintf( L_FATAL, "invalid port speed: %d", c_int(speed)); 306 exit_usage(2); 307 } 308 if ( c_isset(switchbd) && c_int(switchbd) != 0 && !c_bool(data_only) && 309 tio_check_speed( c_int(switchbd) ) < 0 ) 310 { 311 lprintf( L_FATAL, "invalid fax reception switch speed: %d", 312 c_int(switchbd) ); 313 exit_usage(2); 314 } 315 316 if ( c_int(rings_wanted) == 0 ) conf_set_int( &c.rings_wanted, 1 ); 317 318 if ( c_int(ringback_time) < 30 ) conf_set_int( &c.ringback_time, 30); 319 320 if ( c_int(modem_check_time) >= 0 && 321 c_int(modem_check_time) < 900 ) 322 { 323 lprintf( L_NOISE, "increasing modem_check_time to 900 sec." ); 324 conf_set_int( &c.modem_check_time, 900 ); 325 } 326 327 if ( c_isset(modem_quirks) ) 328 { 329 lprintf( L_NOISE, "set modem_quirks: 0x%04x", c_int(modem_quirks)); 330 modem_quirks = c_int(modem_quirks); 331 } 332 } 333