2 Unix SMB/Netbios implementation.
4 Parameter loading functions
5 Copyright (C) Karl Auer 1993,1994
7 Largely re-written by Andrew Tridgell, September 1994
9 This program is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation; either version 2 of the License, or
12 (at your option) any later version.
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
19 You should have received a copy of the GNU General Public License
20 along with this program; if not, write to the Free Software
21 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
27 * This module provides suitable callback functions for the params
28 * module. It builds the internal table of service details which is
29 * then used by the rest of the server.
33 * 1) add it to the global or service structure definition
34 * 2) add it to the parm_table
35 * 3) add it to the list of available functions (eg: using FN_GLOBAL_STRING())
36 * 4) If it's a global then initialise it in init_globals. If a local
37 * (ie. service) parameter then initialise it in the sDefault structure
41 * The configuration file is processed sequentially for speed. It is NOT
42 * accessed randomly as happens in 'real' Windows. For this reason, there
43 * is a fair bit of sequence-dependent code here - ie., code which assumes
44 * that certain things happen before others. In particular, the code which
45 * happens at the boundary between sections is delicately poised, so be
54 extern int DEBUGLEVEL;
55 extern pstring user_socket_options;
56 extern pstring myname;
59 #define GLOBAL_NAME "global"
64 #define PRINTCAP_NAME "/etc/qconfig"
66 #define PRINTCAP_NAME "/etc/printcap"
71 #define PRINTERS_NAME "printers"
75 #define HOMES_NAME "homes"
78 /* some helpful bits */
79 #define pSERVICE(i) ServicePtrs[i]
80 #define iSERVICE(i) (*pSERVICE(i))
81 #define LP_SNUM_OK(iService) (((iService) >= 0) && ((iService) < iNumServices) && iSERVICE(iService).valid)
82 #define VALID(i) iSERVICE(i).valid
84 /* these are the types of parameter we have */
87 P_BOOL,P_BOOLREV,P_CHAR,P_INTEGER,P_OCTAL,
88 P_STRING,P_USTRING,P_GSTRING,P_UGSTRING
93 P_LOCAL,P_GLOBAL,P_NONE
97 extern BOOL use_getwd_cache;
99 extern int extra_time_offset;
101 extern int coding_system;
105 * This structure describes global (ie., server-wide) parameters.
109 char *szPrintcapname;
112 char *szDefaultService;
116 char *szServerString;
117 char *szAutoServices;
118 char *szPasswdProgram;
122 char *szSMBPasswdFile;
123 char *szPasswordServer;
124 char *szSocketOptions;
127 char *szDomainController;
129 char *szCharacterSet;
134 char *szRemoteAnnounce;
135 char *szSocketAddress;
154 BOOL bPreferredMaster;
157 BOOL bEncryptPasswords;
164 BOOL bReadPrediction;
170 static global Globals;
175 * This structure describes a single service.
183 char *szGuestaccount;
184 char *szInvalidUsers;
192 char *szRootPostExec;
193 char *szPrintcommand;
196 char *szLppausecommand;
197 char *szLpresumecommand;
199 char *szPrinterDriver;
220 BOOL bShortCasePreserve;
244 BOOL bDeleteReadonly;
245 char dummy[3]; /* for alignment */
249 /* This is a default service used to prime a services structure */
250 static service sDefault =
253 NULL, /* szService */
255 NULL, /* szUsername */
256 NULL, /* szGuestAccount */
257 NULL, /* szInvalidUsers */
258 NULL, /* szValidUsers */
259 NULL, /* szAdminUsers */
261 NULL, /* szInclude */
262 NULL, /* szPreExec */
263 NULL, /* szPostExec */
264 NULL, /* szRootPreExec */
265 NULL, /* szRootPostExec */
266 NULL, /* szPrintcommand */
267 NULL, /* szLpqcommand */
268 NULL, /* szLprmcommand */
269 NULL, /* szLppausecommand */
270 NULL, /* szLpresumecommand */
271 NULL, /* szPrintername */
272 NULL, /* szPrinterDriver */
273 NULL, /* szDontdescend */
274 NULL, /* szHostsallow */
275 NULL, /* szHostsdeny */
276 NULL, /* szMagicScript */
277 NULL, /* szMagicOutput */
278 NULL, /* szMangledMap */
280 NULL, /* force user */
281 NULL, /* force group */
283 NULL, /* writelist */
285 0, /* iMinPrintSpace */
286 0755, /* iCreate_mode */
287 0, /* iMaxConnections */
288 CASE_LOWER, /* iDefaultCase */
289 False, /* bAlternatePerm */
290 False, /* revalidate */
291 False, /* case sensitive */
292 False, /* case preserve */
293 False, /* short case preserve */
294 False, /* case mangle */
296 True, /* bHideDotFiles */
297 True, /* bBrowseable */
298 True, /* bAvailable */
299 True, /* bRead_only */
300 True, /* bNo_set_dir */
301 False, /* bGuest_only */
302 False, /* bGuest_ok */
303 False, /* bPrint_ok */
304 False, /* bPostscript */
305 False, /* bMap_system */
306 False, /* bMap_hidden */
307 True, /* bMap_archive */
309 False, /* bStrictLocking */
310 True, /* bShareModes */
311 False, /* bOnlyUser */
312 True, /* bMangledNames */
313 True, /* bWidelinks */
314 False, /* bSyncAlways */
315 '~', /* magic char */
317 False, /* bDeleteReadonly */
323 /* local variables */
324 static service **ServicePtrs = NULL;
325 static int iNumServices = 0;
326 static int iServiceIndex = 0;
327 static BOOL bInGlobalSection = True;
328 static BOOL bGlobalOnly = False;
331 #define NUMPARAMETERS (sizeof(parm_table) / sizeof(struct parm_struct))
333 /* prototypes for the special type handlers */
334 static BOOL handle_valid_chars(char *pszParmValue, char **ptr);
335 static BOOL handle_include(char *pszParmValue, char **ptr);
336 static BOOL handle_copy(char *pszParmValue, char **ptr);
337 static BOOL handle_protocol(char *pszParmValue,int *val);
338 static BOOL handle_security(char *pszParmValue,int *val);
339 static BOOL handle_case(char *pszParmValue,int *val);
340 static BOOL handle_printing(char *pszParmValue,int *val);
341 static BOOL handle_character_set(char *pszParmValue,int *val);
343 static BOOL handle_coding_system(char *pszParmValue,int *val);
355 {"debuglevel", P_INTEGER, P_GLOBAL, &DEBUGLEVEL, NULL},
356 {"log level", P_INTEGER, P_GLOBAL, &DEBUGLEVEL, NULL},
357 {"syslog", P_INTEGER, P_GLOBAL, &Globals.syslog, NULL},
358 {"syslog only", P_BOOL, P_GLOBAL, &Globals.bSyslogOnly, NULL},
359 {"protocol", P_INTEGER, P_GLOBAL, &Globals.maxprotocol,handle_protocol},
360 {"security", P_INTEGER, P_GLOBAL, &Globals.security,handle_security},
361 {"printing", P_INTEGER, P_GLOBAL, &Globals.printing,handle_printing},
362 {"max disk size", P_INTEGER, P_GLOBAL, &Globals.maxdisksize, NULL},
363 {"lpq cache time", P_INTEGER, P_GLOBAL, &Globals.lpqcachetime, NULL},
364 {"encrypt passwords",P_BOOL, P_GLOBAL, &Globals.bEncryptPasswords, NULL},
365 {"getwd cache", P_BOOL, P_GLOBAL, &use_getwd_cache, NULL},
366 {"read prediction", P_BOOL, P_GLOBAL, &Globals.bReadPrediction, NULL},
367 {"read bmpx", P_BOOL, P_GLOBAL, &Globals.bReadbmpx, NULL},
368 {"read raw", P_BOOL, P_GLOBAL, &Globals.bReadRaw, NULL},
369 {"write raw", P_BOOL, P_GLOBAL, &Globals.bWriteRaw, NULL},
370 {"use rhosts", P_BOOL, P_GLOBAL, &Globals.bUseRhosts, NULL},
371 {"load printers", P_BOOL, P_GLOBAL, &Globals.bLoadPrinters, NULL},
372 {"null passwords", P_BOOL, P_GLOBAL, &Globals.bNullPasswords, NULL},
373 {"strip dot", P_BOOL, P_GLOBAL, &Globals.bStripDot, NULL},
374 {"interfaces", P_STRING, P_GLOBAL, &Globals.szInterfaces, NULL},
375 {"password server", P_STRING, P_GLOBAL, &Globals.szPasswordServer, NULL},
376 {"socket options", P_GSTRING, P_GLOBAL, user_socket_options, NULL},
377 {"netbios name", P_UGSTRING,P_GLOBAL, myname, NULL},
378 {"smbrun", P_STRING, P_GLOBAL, &Globals.szSmbrun, NULL},
379 {"log file", P_STRING, P_GLOBAL, &Globals.szLogFile, NULL},
380 {"config file", P_STRING, P_GLOBAL, &Globals.szConfigFile, NULL},
381 {"smb passwd file", P_STRING, P_GLOBAL, &Globals.szSMBPasswdFile, NULL},
382 {"hosts equiv", P_STRING, P_GLOBAL, &Globals.szHostsEquiv, NULL},
383 {"preload", P_STRING, P_GLOBAL, &Globals.szAutoServices, NULL},
384 {"auto services", P_STRING, P_GLOBAL, &Globals.szAutoServices, NULL},
385 {"server string", P_STRING, P_GLOBAL, &Globals.szServerString, NULL},
386 {"printcap name", P_STRING, P_GLOBAL, &Globals.szPrintcapname, NULL},
387 {"printcap", P_STRING, P_GLOBAL, &Globals.szPrintcapname, NULL},
388 {"lock dir", P_STRING, P_GLOBAL, &Globals.szLockDir, NULL},
389 {"lock directory", P_STRING, P_GLOBAL, &Globals.szLockDir, NULL},
390 {"root directory", P_STRING, P_GLOBAL, &Globals.szRootdir, NULL},
391 {"root dir", P_STRING, P_GLOBAL, &Globals.szRootdir, NULL},
392 {"root", P_STRING, P_GLOBAL, &Globals.szRootdir, NULL},
393 {"default service", P_STRING, P_GLOBAL, &Globals.szDefaultService, NULL},
394 {"default", P_STRING, P_GLOBAL, &Globals.szDefaultService, NULL},
395 {"message command", P_STRING, P_GLOBAL, &Globals.szMsgCommand, NULL},
396 {"dfree command", P_STRING, P_GLOBAL, &Globals.szDfree, NULL},
397 {"passwd program", P_STRING, P_GLOBAL, &Globals.szPasswdProgram, NULL},
398 {"passwd chat", P_STRING, P_GLOBAL, &Globals.szPasswdChat, NULL},
399 {"valid chars", P_STRING, P_GLOBAL, &Globals.szValidChars, handle_valid_chars},
400 {"workgroup", P_USTRING, P_GLOBAL, &Globals.szWorkGroup, NULL},
401 {"domain controller",P_STRING, P_GLOBAL, &Globals.szDomainController,NULL},
402 {"username map", P_STRING, P_GLOBAL, &Globals.szUsernameMap, NULL},
403 {"character set", P_STRING, P_GLOBAL, &Globals.szCharacterSet, handle_character_set},
404 {"logon script", P_STRING, P_GLOBAL, &Globals.szLogonScript, NULL},
405 {"remote announce", P_STRING, P_GLOBAL, &Globals.szRemoteAnnounce, NULL},
406 {"socket address", P_STRING, P_GLOBAL, &Globals.szSocketAddress, NULL},
407 {"max log size", P_INTEGER, P_GLOBAL, &Globals.max_log_size, NULL},
408 {"mangled stack", P_INTEGER, P_GLOBAL, &Globals.mangled_stack, NULL},
409 {"max mux", P_INTEGER, P_GLOBAL, &Globals.max_mux, NULL},
410 {"max xmit", P_INTEGER, P_GLOBAL, &Globals.max_xmit, NULL},
411 {"max packet", P_INTEGER, P_GLOBAL, &Globals.max_packet, NULL},
412 {"packet size", P_INTEGER, P_GLOBAL, &Globals.max_packet, NULL},
413 {"password level", P_INTEGER, P_GLOBAL, &Globals.pwordlevel, NULL},
414 {"keepalive", P_INTEGER, P_GLOBAL, &keepalive, NULL},
415 {"deadtime", P_INTEGER, P_GLOBAL, &Globals.deadtime, NULL},
416 {"time offset", P_INTEGER, P_GLOBAL, &extra_time_offset, NULL},
417 {"read size", P_INTEGER, P_GLOBAL, &Globals.ReadSize, NULL},
419 {"coding system", P_INTEGER, P_GLOBAL, &coding_system, handle_coding_system},
421 {"os level", P_INTEGER, P_GLOBAL, &Globals.os_level, NULL},
422 {"max ttl", P_INTEGER, P_GLOBAL, &Globals.max_ttl, NULL},
423 {"wins support", P_BOOL, P_GLOBAL, &Globals.bWINSsupport, NULL},
424 {"wins proxy", P_BOOL, P_GLOBAL, &Globals.bWINSproxy, NULL},
425 {"wins server", P_STRING, P_GLOBAL, &Globals.szWINSserver, NULL},
426 {"preferred master", P_BOOL, P_GLOBAL, &Globals.bPreferredMaster, NULL},
427 {"prefered master", P_BOOL, P_GLOBAL, &Globals.bPreferredMaster, NULL},
428 {"domain master", P_BOOL, P_GLOBAL, &Globals.bDomainMaster, NULL},
429 {"domain logons", P_BOOL, P_GLOBAL, &Globals.bDomainLogons, NULL},
430 {"browse list", P_BOOL, P_GLOBAL, &Globals.bBrowseList, NULL},
432 {"-valid", P_BOOL, P_LOCAL, &sDefault.valid, NULL},
433 {"comment", P_STRING, P_LOCAL, &sDefault.comment, NULL},
434 {"copy", P_STRING, P_LOCAL, &sDefault.szCopy, handle_copy},
435 {"include", P_STRING, P_LOCAL, &sDefault.szInclude, handle_include},
436 {"exec", P_STRING, P_LOCAL, &sDefault.szPreExec, NULL},
437 {"preexec", P_STRING, P_LOCAL, &sDefault.szPreExec, NULL},
438 {"postexec", P_STRING, P_LOCAL, &sDefault.szPostExec, NULL},
439 {"root preexec", P_STRING, P_LOCAL, &sDefault.szRootPreExec, NULL},
440 {"root postexec", P_STRING, P_LOCAL, &sDefault.szRootPostExec, NULL},
441 {"alternate permissions",P_BOOL,P_LOCAL, &sDefault.bAlternatePerm, NULL},
442 {"revalidate", P_BOOL, P_LOCAL, &sDefault.bRevalidate, NULL},
443 {"default case", P_INTEGER, P_LOCAL, &sDefault.iDefaultCase, handle_case},
444 {"case sensitive", P_BOOL, P_LOCAL, &sDefault.bCaseSensitive, NULL},
445 {"casesignames", P_BOOL, P_LOCAL, &sDefault.bCaseSensitive, NULL},
446 {"preserve case", P_BOOL, P_LOCAL, &sDefault.bCasePreserve, NULL},
447 {"short preserve case",P_BOOL, P_LOCAL, &sDefault.bShortCasePreserve,NULL},
448 {"mangle case", P_BOOL, P_LOCAL, &sDefault.bCaseMangle, NULL},
449 {"mangling char", P_CHAR, P_LOCAL, &sDefault.magic_char, NULL},
450 {"browseable", P_BOOL, P_LOCAL, &sDefault.bBrowseable, NULL},
451 {"browsable", P_BOOL, P_LOCAL, &sDefault.bBrowseable, NULL},
452 {"available", P_BOOL, P_LOCAL, &sDefault.bAvailable, NULL},
453 {"path", P_STRING, P_LOCAL, &sDefault.szPath, NULL},
454 {"directory", P_STRING, P_LOCAL, &sDefault.szPath, NULL},
455 {"username", P_STRING, P_LOCAL, &sDefault.szUsername, NULL},
456 {"user", P_STRING, P_LOCAL, &sDefault.szUsername, NULL},
457 {"users", P_STRING, P_LOCAL, &sDefault.szUsername, NULL},
458 {"guest account", P_STRING, P_LOCAL, &sDefault.szGuestaccount, NULL},
459 {"invalid users", P_STRING, P_LOCAL, &sDefault.szInvalidUsers, NULL},
460 {"valid users", P_STRING, P_LOCAL, &sDefault.szValidUsers, NULL},
461 {"admin users", P_STRING, P_LOCAL, &sDefault.szAdminUsers, NULL},
462 {"read list", P_STRING, P_LOCAL, &sDefault.readlist, NULL},
463 {"write list", P_STRING, P_LOCAL, &sDefault.writelist, NULL},
464 {"volume", P_STRING, P_LOCAL, &sDefault.volume, NULL},
465 {"force user", P_STRING, P_LOCAL, &sDefault.force_user, NULL},
466 {"force group", P_STRING, P_LOCAL, &sDefault.force_group, NULL},
467 {"group", P_STRING, P_LOCAL, &sDefault.force_group, NULL},
468 {"read only", P_BOOL, P_LOCAL, &sDefault.bRead_only, NULL},
469 {"write ok", P_BOOLREV, P_LOCAL, &sDefault.bRead_only, NULL},
470 {"writeable", P_BOOLREV, P_LOCAL, &sDefault.bRead_only, NULL},
471 {"writable", P_BOOLREV, P_LOCAL, &sDefault.bRead_only, NULL},
472 {"max connections", P_INTEGER, P_LOCAL, &sDefault.iMaxConnections, NULL},
473 {"min print space", P_INTEGER, P_LOCAL, &sDefault.iMinPrintSpace, NULL},
474 {"create mask", P_OCTAL, P_LOCAL, &sDefault.iCreate_mode, NULL},
475 {"create mode", P_OCTAL, P_LOCAL, &sDefault.iCreate_mode, NULL},
476 {"set directory", P_BOOLREV, P_LOCAL, &sDefault.bNo_set_dir, NULL},
477 {"status", P_BOOL, P_LOCAL, &sDefault.status, NULL},
478 {"hide dot files", P_BOOL, P_LOCAL, &sDefault.bHideDotFiles, NULL},
479 {"guest only", P_BOOL, P_LOCAL, &sDefault.bGuest_only, NULL},
480 {"only guest", P_BOOL, P_LOCAL, &sDefault.bGuest_only, NULL},
481 {"guest ok", P_BOOL, P_LOCAL, &sDefault.bGuest_ok, NULL},
482 {"public", P_BOOL, P_LOCAL, &sDefault.bGuest_ok, NULL},
483 {"print ok", P_BOOL, P_LOCAL, &sDefault.bPrint_ok, NULL},
484 {"printable", P_BOOL, P_LOCAL, &sDefault.bPrint_ok, NULL},
485 {"postscript", P_BOOL, P_LOCAL, &sDefault.bPostscript, NULL},
486 {"map system", P_BOOL, P_LOCAL, &sDefault.bMap_system, NULL},
487 {"map hidden", P_BOOL, P_LOCAL, &sDefault.bMap_hidden, NULL},
488 {"map archive", P_BOOL, P_LOCAL, &sDefault.bMap_archive, NULL},
489 {"locking", P_BOOL, P_LOCAL, &sDefault.bLocking, NULL},
490 {"strict locking", P_BOOL, P_LOCAL, &sDefault.bStrictLocking, NULL},
491 {"share modes", P_BOOL, P_LOCAL, &sDefault.bShareModes, NULL},
492 {"only user", P_BOOL, P_LOCAL, &sDefault.bOnlyUser, NULL},
493 {"wide links", P_BOOL, P_LOCAL, &sDefault.bWidelinks, NULL},
494 {"sync always", P_BOOL, P_LOCAL, &sDefault.bSyncAlways, NULL},
495 {"mangled names", P_BOOL, P_LOCAL, &sDefault.bMangledNames, NULL},
496 {"print command", P_STRING, P_LOCAL, &sDefault.szPrintcommand, NULL},
497 {"lpq command", P_STRING, P_LOCAL, &sDefault.szLpqcommand, NULL},
498 {"lprm command", P_STRING, P_LOCAL, &sDefault.szLprmcommand, NULL},
499 {"lppause command", P_STRING, P_LOCAL, &sDefault.szLppausecommand, NULL},
500 {"lpresume command", P_STRING, P_LOCAL, &sDefault.szLpresumecommand,NULL},
501 {"printer", P_STRING, P_LOCAL, &sDefault.szPrintername, NULL},
502 {"printer name", P_STRING, P_LOCAL, &sDefault.szPrintername, NULL},
503 {"printer driver", P_STRING, P_LOCAL, &sDefault.szPrinterDriver, NULL},
504 {"hosts allow", P_STRING, P_LOCAL, &sDefault.szHostsallow, NULL},
505 {"allow hosts", P_STRING, P_LOCAL, &sDefault.szHostsallow, NULL},
506 {"hosts deny", P_STRING, P_LOCAL, &sDefault.szHostsdeny, NULL},
507 {"deny hosts", P_STRING, P_LOCAL, &sDefault.szHostsdeny, NULL},
508 {"dont descend", P_STRING, P_LOCAL, &sDefault.szDontdescend, NULL},
509 {"magic script", P_STRING, P_LOCAL, &sDefault.szMagicScript, NULL},
510 {"magic output", P_STRING, P_LOCAL, &sDefault.szMagicOutput, NULL},
511 {"mangled map", P_STRING, P_LOCAL, &sDefault.szMangledMap, NULL},
512 {"delete readonly", P_BOOL, P_LOCAL, &sDefault.bDeleteReadonly, NULL},
514 {NULL, P_BOOL, P_NONE, NULL, NULL}
519 /***************************************************************************
520 Initialise the global parameter structure.
521 ***************************************************************************/
522 static void init_globals(void)
524 static BOOL done_init = False;
530 bzero((void *)&Globals,sizeof(Globals));
532 for (i = 0; parm_table[i].label; i++)
533 if ((parm_table[i].type == P_STRING ||
534 parm_table[i].type == P_USTRING) &&
536 string_init(parm_table[i].ptr,"");
538 string_set(&sDefault.szGuestaccount, GUEST_ACCOUNT);
544 DEBUG(3,("Initialising global parameters\n"));
546 #ifdef SMB_PASSWD_FILE
547 string_set(&Globals.szSMBPasswdFile, SMB_PASSWD_FILE);
549 string_set(&Globals.szPasswdChat,"*old*password* %o\\n *new*password* %n\\n *new*password* %n\\n *changed*");
550 string_set(&Globals.szWorkGroup, WORKGROUP);
552 string_set(&Globals.szPasswdProgram, SMB_PASSWD);
554 string_set(&Globals.szPasswdProgram, "/bin/passwd");
556 string_set(&Globals.szPrintcapname, PRINTCAP_NAME);
557 string_set(&Globals.szLockDir, LOCKDIR);
558 string_set(&Globals.szRootdir, "/");
559 string_set(&Globals.szSmbrun, SMBRUN);
560 string_set(&Globals.szSocketAddress, "0.0.0.0");
561 sprintf(s,"Samba %s",VERSION);
562 string_set(&Globals.szServerString,s);
563 Globals.bLoadPrinters = True;
564 Globals.bUseRhosts = False;
565 Globals.max_packet = 65535;
566 Globals.mangled_stack = 50;
567 Globals.max_xmit = Globals.max_packet;
569 Globals.lpqcachetime = 10;
570 Globals.pwordlevel = 0;
571 Globals.deadtime = 0;
572 Globals.max_log_size = 5000;
573 Globals.maxprotocol = PROTOCOL_NT1;
574 Globals.security = SEC_SHARE;
575 Globals.bEncryptPasswords = False;
576 Globals.printing = DEFAULT_PRINTING;
577 Globals.bReadRaw = True;
578 Globals.bWriteRaw = True;
579 Globals.bReadPrediction = False;
580 Globals.bReadbmpx = True;
581 Globals.bNullPasswords = False;
582 Globals.bStripDot = False;
584 Globals.bSyslogOnly = False;
585 Globals.os_level = 0;
586 Globals.max_ttl = 60*60*4; /* 2 hours default */
587 Globals.bPreferredMaster = True;
588 Globals.bDomainMaster = False;
589 Globals.bDomainLogons = False;
590 Globals.bBrowseList = True;
591 Globals.bWINSsupport = True;
592 Globals.bWINSproxy = False;
593 Globals.ReadSize = 16*1024;
596 coding_system = interpret_coding_system (KANJI, SJIS_CODE);
601 /***************************************************************************
602 check if a string is initialised and if not then initialise it
603 ***************************************************************************/
604 static void string_initial(char **s,char *v)
611 /***************************************************************************
612 Initialise the sDefault parameter structure.
613 ***************************************************************************/
614 static void init_locals(void)
616 /* choose defaults depending on the type of printing */
617 switch (Globals.printing)
623 string_initial(&sDefault.szLpqcommand,"lpq -P%p");
624 string_initial(&sDefault.szLprmcommand,"lprm -P%p %j");
625 string_initial(&sDefault.szPrintcommand,"lpr -r -P%p %s");
630 string_initial(&sDefault.szLpqcommand,"lpstat -o%p");
631 string_initial(&sDefault.szLprmcommand,"cancel %p-%j");
632 string_initial(&sDefault.szPrintcommand,"lp -c -d%p %s; rm %s");
634 string_initial(&sDefault.szLppausecommand,"lp -i %p-%j -H hold");
635 string_initial(&sDefault.szLpresumecommand,"lp -i %p-%j -H resume");
640 string_initial(&sDefault.szLpqcommand,"lpq -P%p");
641 string_initial(&sDefault.szLprmcommand,"lprm -P%p %j");
642 string_initial(&sDefault.szPrintcommand,"lp -r -P%p %s");
650 /******************************************************************* a
651 convenience routine to grab string parameters into a rotating buffer,
652 and run standard_sub_basic on them. The buffers can be written to by
653 callers without affecting the source string.
654 ********************************************************************/
655 char *lp_string(char *s)
657 static char *bufs[10];
658 static int buflen[10];
659 static int next = -1;
662 int len = s?strlen(s):0;
673 len = MAX(len+100,sizeof(pstring)); /* the +100 is for some
676 if (buflen[next] != len) {
678 if (bufs[next]) free(bufs[next]);
679 bufs[next] = (char *)malloc(len);
681 DEBUG(0,("out of memory in lp_string()"));
686 ret = &bufs[next][0];
694 standard_sub_basic(ret);
700 In this section all the functions that are used to access the
701 parameters from the rest of the program are defined
704 #define FN_GLOBAL_STRING(fn_name,ptr) \
705 char *fn_name(void) {return(lp_string(*(char **)(ptr) ? *(char **)(ptr) : ""));}
706 #define FN_GLOBAL_BOOL(fn_name,ptr) \
707 BOOL fn_name(void) {return(*(BOOL *)(ptr));}
708 #define FN_GLOBAL_CHAR(fn_name,ptr) \
709 char fn_name(void) {return(*(char *)(ptr));}
710 #define FN_GLOBAL_INTEGER(fn_name,ptr) \
711 int fn_name(void) {return(*(int *)(ptr));}
713 #define FN_LOCAL_STRING(fn_name,val) \
714 char *fn_name(int i) {return(lp_string((LP_SNUM_OK(i)&&pSERVICE(i)->val)?pSERVICE(i)->val : sDefault.val));}
715 #define FN_LOCAL_BOOL(fn_name,val) \
716 BOOL fn_name(int i) {return(LP_SNUM_OK(i)? pSERVICE(i)->val : sDefault.val);}
717 #define FN_LOCAL_CHAR(fn_name,val) \
718 char fn_name(int i) {return(LP_SNUM_OK(i)? pSERVICE(i)->val : sDefault.val);}
719 #define FN_LOCAL_INTEGER(fn_name,val) \
720 int fn_name(int i) {return(LP_SNUM_OK(i)? pSERVICE(i)->val : sDefault.val);}
722 FN_GLOBAL_STRING(lp_logfile,&Globals.szLogFile)
723 FN_GLOBAL_STRING(lp_smbrun,&Globals.szSmbrun)
724 FN_GLOBAL_STRING(lp_configfile,&Globals.szConfigFile)
725 FN_GLOBAL_STRING(lp_smb_passwd_file,&Globals.szSMBPasswdFile)
726 FN_GLOBAL_STRING(lp_serverstring,&Globals.szServerString)
727 FN_GLOBAL_STRING(lp_printcapname,&Globals.szPrintcapname)
728 FN_GLOBAL_STRING(lp_lockdir,&Globals.szLockDir)
729 FN_GLOBAL_STRING(lp_rootdir,&Globals.szRootdir)
730 FN_GLOBAL_STRING(lp_defaultservice,&Globals.szDefaultService)
731 FN_GLOBAL_STRING(lp_msg_command,&Globals.szMsgCommand)
732 FN_GLOBAL_STRING(lp_dfree_command,&Globals.szDfree)
733 FN_GLOBAL_STRING(lp_hosts_equiv,&Globals.szHostsEquiv)
734 FN_GLOBAL_STRING(lp_auto_services,&Globals.szAutoServices)
735 FN_GLOBAL_STRING(lp_passwd_program,&Globals.szPasswdProgram)
736 FN_GLOBAL_STRING(lp_passwd_chat,&Globals.szPasswdChat)
737 FN_GLOBAL_STRING(lp_passwordserver,&Globals.szPasswordServer)
738 FN_GLOBAL_STRING(lp_workgroup,&Globals.szWorkGroup)
739 FN_GLOBAL_STRING(lp_domain_controller,&Globals.szDomainController)
740 FN_GLOBAL_STRING(lp_username_map,&Globals.szUsernameMap)
741 FN_GLOBAL_STRING(lp_character_set,&Globals.szCharacterSet)
742 FN_GLOBAL_STRING(lp_logon_script,&Globals.szLogonScript)
743 FN_GLOBAL_STRING(lp_remote_announce,&Globals.szRemoteAnnounce)
744 FN_GLOBAL_STRING(lp_wins_server,&Globals.szWINSserver)
745 FN_GLOBAL_STRING(lp_interfaces,&Globals.szInterfaces)
746 FN_GLOBAL_STRING(lp_socket_address,&Globals.szSocketAddress)
748 FN_GLOBAL_BOOL(lp_wins_support,&Globals.bWINSsupport)
749 FN_GLOBAL_BOOL(lp_wins_proxy,&Globals.bWINSproxy)
750 FN_GLOBAL_BOOL(lp_domain_master,&Globals.bDomainMaster)
751 FN_GLOBAL_BOOL(lp_domain_logons,&Globals.bDomainLogons)
752 FN_GLOBAL_BOOL(lp_preferred_master,&Globals.bPreferredMaster)
753 FN_GLOBAL_BOOL(lp_load_printers,&Globals.bLoadPrinters)
754 FN_GLOBAL_BOOL(lp_use_rhosts,&Globals.bUseRhosts)
755 FN_GLOBAL_BOOL(lp_getwdcache,&use_getwd_cache)
756 FN_GLOBAL_BOOL(lp_readprediction,&Globals.bReadPrediction)
757 FN_GLOBAL_BOOL(lp_readbmpx,&Globals.bReadbmpx)
758 FN_GLOBAL_BOOL(lp_readraw,&Globals.bReadRaw)
759 FN_GLOBAL_BOOL(lp_writeraw,&Globals.bWriteRaw)
760 FN_GLOBAL_BOOL(lp_null_passwords,&Globals.bNullPasswords)
761 FN_GLOBAL_BOOL(lp_strip_dot,&Globals.bStripDot)
762 FN_GLOBAL_BOOL(lp_encrypted_passwords,&Globals.bEncryptPasswords)
763 FN_GLOBAL_BOOL(lp_syslog_only,&Globals.bSyslogOnly)
764 FN_GLOBAL_BOOL(lp_browse_list,&Globals.bBrowseList)
766 FN_GLOBAL_INTEGER(lp_os_level,&Globals.os_level)
767 FN_GLOBAL_INTEGER(lp_max_ttl,&Globals.max_ttl)
768 FN_GLOBAL_INTEGER(lp_max_log_size,&Globals.max_log_size)
769 FN_GLOBAL_INTEGER(lp_mangledstack,&Globals.mangled_stack)
770 FN_GLOBAL_INTEGER(lp_maxxmit,&Globals.max_xmit)
771 FN_GLOBAL_INTEGER(lp_maxmux,&Globals.max_mux)
772 FN_GLOBAL_INTEGER(lp_maxpacket,&Globals.max_packet)
773 FN_GLOBAL_INTEGER(lp_keepalive,&keepalive)
774 FN_GLOBAL_INTEGER(lp_passwordlevel,&Globals.pwordlevel)
775 FN_GLOBAL_INTEGER(lp_readsize,&Globals.ReadSize)
776 FN_GLOBAL_INTEGER(lp_deadtime,&Globals.deadtime)
777 FN_GLOBAL_INTEGER(lp_maxprotocol,&Globals.maxprotocol)
778 FN_GLOBAL_INTEGER(lp_security,&Globals.security)
779 FN_GLOBAL_INTEGER(lp_printing,&Globals.printing)
780 FN_GLOBAL_INTEGER(lp_maxdisksize,&Globals.maxdisksize)
781 FN_GLOBAL_INTEGER(lp_lpqcachetime,&Globals.lpqcachetime)
782 FN_GLOBAL_INTEGER(lp_syslog,&Globals.syslog)
784 FN_LOCAL_STRING(lp_preexec,szPreExec)
785 FN_LOCAL_STRING(lp_postexec,szPostExec)
786 FN_LOCAL_STRING(lp_rootpreexec,szRootPreExec)
787 FN_LOCAL_STRING(lp_rootpostexec,szRootPostExec)
788 FN_LOCAL_STRING(lp_servicename,szService)
789 FN_LOCAL_STRING(lp_pathname,szPath)
790 FN_LOCAL_STRING(lp_dontdescend,szDontdescend)
791 FN_LOCAL_STRING(lp_username,szUsername)
792 FN_LOCAL_STRING(lp_guestaccount,szGuestaccount)
793 FN_LOCAL_STRING(lp_invalid_users,szInvalidUsers)
794 FN_LOCAL_STRING(lp_valid_users,szValidUsers)
795 FN_LOCAL_STRING(lp_admin_users,szAdminUsers)
796 FN_LOCAL_STRING(lp_printcommand,szPrintcommand)
797 FN_LOCAL_STRING(lp_lpqcommand,szLpqcommand)
798 FN_LOCAL_STRING(lp_lprmcommand,szLprmcommand)
799 FN_LOCAL_STRING(lp_lppausecommand,szLppausecommand)
800 FN_LOCAL_STRING(lp_lpresumecommand,szLpresumecommand)
801 FN_LOCAL_STRING(lp_printername,szPrintername)
802 FN_LOCAL_STRING(lp_printerdriver,szPrinterDriver)
803 FN_LOCAL_STRING(lp_hostsallow,szHostsallow)
804 FN_LOCAL_STRING(lp_hostsdeny,szHostsdeny)
805 FN_LOCAL_STRING(lp_magicscript,szMagicScript)
806 FN_LOCAL_STRING(lp_magicoutput,szMagicOutput)
807 FN_LOCAL_STRING(lp_comment,comment)
808 FN_LOCAL_STRING(lp_force_user,force_user)
809 FN_LOCAL_STRING(lp_force_group,force_group)
810 FN_LOCAL_STRING(lp_readlist,readlist)
811 FN_LOCAL_STRING(lp_writelist,writelist)
812 FN_LOCAL_STRING(lp_volume,volume)
813 FN_LOCAL_STRING(lp_mangled_map,szMangledMap)
815 FN_LOCAL_BOOL(lp_alternate_permissions,bAlternatePerm)
816 FN_LOCAL_BOOL(lp_revalidate,bRevalidate)
817 FN_LOCAL_BOOL(lp_casesensitive,bCaseSensitive)
818 FN_LOCAL_BOOL(lp_preservecase,bCasePreserve)
819 FN_LOCAL_BOOL(lp_shortpreservecase,bShortCasePreserve)
820 FN_LOCAL_BOOL(lp_casemangle,bCaseMangle)
821 FN_LOCAL_BOOL(lp_status,status)
822 FN_LOCAL_BOOL(lp_hide_dot_files,bHideDotFiles)
823 FN_LOCAL_BOOL(lp_browseable,bBrowseable)
824 FN_LOCAL_BOOL(lp_readonly,bRead_only)
825 FN_LOCAL_BOOL(lp_no_set_dir,bNo_set_dir)
826 FN_LOCAL_BOOL(lp_guest_ok,bGuest_ok)
827 FN_LOCAL_BOOL(lp_guest_only,bGuest_only)
828 FN_LOCAL_BOOL(lp_print_ok,bPrint_ok)
829 FN_LOCAL_BOOL(lp_postscript,bPostscript)
830 FN_LOCAL_BOOL(lp_map_hidden,bMap_hidden)
831 FN_LOCAL_BOOL(lp_map_archive,bMap_archive)
832 FN_LOCAL_BOOL(lp_locking,bLocking)
833 FN_LOCAL_BOOL(lp_strict_locking,bStrictLocking)
834 FN_LOCAL_BOOL(lp_share_modes,bShareModes)
835 FN_LOCAL_BOOL(lp_onlyuser,bOnlyUser)
836 FN_LOCAL_BOOL(lp_manglednames,bMangledNames)
837 FN_LOCAL_BOOL(lp_widelinks,bWidelinks)
838 FN_LOCAL_BOOL(lp_syncalways,bSyncAlways)
839 FN_LOCAL_BOOL(lp_map_system,bMap_system)
840 FN_LOCAL_BOOL(lp_delete_readonly,bDeleteReadonly)
842 FN_LOCAL_INTEGER(lp_create_mode,iCreate_mode)
843 FN_LOCAL_INTEGER(lp_max_connections,iMaxConnections)
844 FN_LOCAL_INTEGER(lp_defaultcase,iDefaultCase)
845 FN_LOCAL_INTEGER(lp_minprintspace,iMinPrintSpace)
847 FN_LOCAL_CHAR(lp_magicchar,magic_char)
851 /* local prototypes */
852 static int strwicmp( char *psz1, char *psz2 );
853 static int map_parameter( char *pszParmName);
854 static BOOL set_boolean( BOOL *pb, char *pszParmValue );
855 static int getservicebyname(char *pszServiceName, service *pserviceDest);
856 static void copy_service( service *pserviceDest,
857 service *pserviceSource,
858 BOOL *pcopymapDest );
859 static BOOL service_ok(int iService);
860 static BOOL do_parameter(char *pszParmName, char *pszParmValue);
861 static BOOL do_section(char *pszSectionName);
862 static void dump_globals(void);
863 static void dump_a_service(service *pService);
864 static void init_copymap(service *pservice);
867 /***************************************************************************
868 initialise a service to the defaults
869 ***************************************************************************/
870 static void init_service(service *pservice)
872 bzero((char *)pservice,sizeof(service));
873 copy_service(pservice,&sDefault,NULL);
877 /***************************************************************************
878 free the dynamically allocated parts of a service struct
879 ***************************************************************************/
880 static void free_service(service *pservice)
886 for (i=0;parm_table[i].label;i++)
887 if ((parm_table[i].type == P_STRING ||
888 parm_table[i].type == P_STRING) &&
889 parm_table[i].class == P_LOCAL)
890 string_free((char **)(((char *)pservice) + PTR_DIFF(parm_table[i].ptr,&sDefault)));
893 /***************************************************************************
894 add a new service to the services array initialising it with the given
896 ***************************************************************************/
897 static int add_a_service(service *pservice, char *name)
901 int num_to_alloc = iNumServices+1;
903 tservice = *pservice;
905 /* it might already exist */
908 i = getservicebyname(name,NULL);
913 /* find an invalid one */
914 for (i=0;i<iNumServices;i++)
915 if (!pSERVICE(i)->valid)
918 /* if not, then create one */
919 if (i == iNumServices)
921 ServicePtrs = (service **)Realloc(ServicePtrs,sizeof(service *)*num_to_alloc);
923 pSERVICE(iNumServices) = (service *)malloc(sizeof(service));
925 if (!ServicePtrs || !pSERVICE(iNumServices))
931 free_service(pSERVICE(i));
933 pSERVICE(i)->valid = True;
935 init_service(pSERVICE(i));
936 copy_service(pSERVICE(i),&tservice,NULL);
938 string_set(&iSERVICE(i).szService,name);
943 /***************************************************************************
944 add a new home service, with the specified home directory, defaults coming
946 ***************************************************************************/
947 BOOL lp_add_home(char *pszHomename, int iDefaultService, char *pszHomedir)
949 int i = add_a_service(pSERVICE(iDefaultService),pszHomename);
954 if (!(*(iSERVICE(i).szPath)) || strequal(iSERVICE(i).szPath,lp_pathname(-1)))
955 string_set(&iSERVICE(i).szPath,pszHomedir);
956 if (!(*(iSERVICE(i).comment)))
959 sprintf(comment,"Home directory of %s",pszHomename);
960 string_set(&iSERVICE(i).comment,comment);
962 iSERVICE(i).bAvailable = sDefault.bAvailable;
963 iSERVICE(i).bBrowseable = sDefault.bBrowseable;
965 DEBUG(3,("adding home directory %s at %s\n", pszHomename, pszHomedir));
970 /***************************************************************************
971 add a new service, based on an old one
972 ***************************************************************************/
973 int lp_add_service(char *pszService, int iDefaultService)
975 return(add_a_service(pSERVICE(iDefaultService),pszService));
979 /***************************************************************************
981 ***************************************************************************/
982 static BOOL lp_add_ipc(void)
985 int i = add_a_service(&sDefault,"IPC$");
990 sprintf(comment,"IPC Service (%s)",lp_serverstring());
992 string_set(&iSERVICE(i).szPath,"/tmp");
993 string_set(&iSERVICE(i).szUsername,"");
994 string_set(&iSERVICE(i).comment,comment);
995 iSERVICE(i).status = False;
996 iSERVICE(i).iMaxConnections = 0;
997 iSERVICE(i).bAvailable = True;
998 iSERVICE(i).bRead_only = True;
999 iSERVICE(i).bGuest_only = False;
1000 iSERVICE(i).bGuest_ok = True;
1001 iSERVICE(i).bPrint_ok = False;
1002 iSERVICE(i).bBrowseable = sDefault.bBrowseable;
1004 DEBUG(3,("adding IPC service\n"));
1010 /***************************************************************************
1011 add a new printer service, with defaults coming from service iFrom
1012 ***************************************************************************/
1013 BOOL lp_add_printer(char *pszPrintername, int iDefaultService)
1015 char *comment = "From Printcap";
1016 int i = add_a_service(pSERVICE(iDefaultService),pszPrintername);
1021 /* note that we do NOT default the availability flag to True - */
1022 /* we take it from the default service passed. This allows all */
1023 /* dynamic printers to be disabled by disabling the [printers] */
1024 /* entry (if/when the 'available' keyword is implemented!). */
1026 /* the printer name is set to the service name. */
1027 string_set(&iSERVICE(i).szPrintername,pszPrintername);
1028 string_set(&iSERVICE(i).comment,comment);
1029 iSERVICE(i).bBrowseable = sDefault.bBrowseable;
1031 DEBUG(3,("adding printer service %s\n",pszPrintername));
1037 /***************************************************************************
1038 Do a case-insensitive, whitespace-ignoring string compare.
1039 ***************************************************************************/
1040 static int strwicmp(char *psz1, char *psz2)
1042 /* if BOTH strings are NULL, return TRUE, if ONE is NULL return */
1043 /* appropriate value. */
1053 /* sync the strings on first non-whitespace */
1056 while (isspace(*psz1))
1058 while (isspace(*psz2))
1060 if (toupper(*psz1) != toupper(*psz2) || *psz1 == '\0' || *psz2 == '\0')
1065 return (*psz1 - *psz2);
1068 /***************************************************************************
1069 Map a parameter's string representation to something we can use.
1070 Returns False if the parameter string is not recognised, else TRUE.
1071 ***************************************************************************/
1072 static int map_parameter(char *pszParmName)
1076 if (*pszParmName == '-')
1079 for (iIndex = 0; parm_table[iIndex].label; iIndex++)
1080 if (strwicmp(parm_table[iIndex].label, pszParmName) == 0)
1083 DEBUG(0,( "Unknown parameter encountered: \"%s\"\n", pszParmName));
1088 /***************************************************************************
1089 Set a boolean variable from the text value stored in the passed string.
1090 Returns True in success, False if the passed string does not correctly
1091 represent a boolean.
1092 ***************************************************************************/
1093 static BOOL set_boolean(BOOL *pb, char *pszParmValue)
1098 if (strwicmp(pszParmValue, "yes") == 0 ||
1099 strwicmp(pszParmValue, "true") == 0 ||
1100 strwicmp(pszParmValue, "1") == 0)
1103 if (strwicmp(pszParmValue, "no") == 0 ||
1104 strwicmp(pszParmValue, "False") == 0 ||
1105 strwicmp(pszParmValue, "0") == 0)
1109 DEBUG(0,( "Badly formed boolean in configuration file: \"%s\".\n",
1116 /***************************************************************************
1117 Find a service by name. Otherwise works like get_service.
1118 ***************************************************************************/
1119 static int getservicebyname(char *pszServiceName, service *pserviceDest)
1123 for (iService = iNumServices - 1; iService >= 0; iService--)
1124 if (VALID(iService) &&
1125 strwicmp(iSERVICE(iService).szService, pszServiceName) == 0)
1127 if (pserviceDest != NULL)
1128 copy_service(pserviceDest, pSERVICE(iService), NULL);
1137 /***************************************************************************
1138 Copy a service structure to another
1140 If pcopymapDest is NULL then copy all fields
1141 ***************************************************************************/
1142 static void copy_service(service *pserviceDest,
1143 service *pserviceSource,
1147 BOOL bcopyall = (pcopymapDest == NULL);
1149 for (i=0;parm_table[i].label;i++)
1150 if (parm_table[i].ptr && parm_table[i].class == P_LOCAL &&
1151 (bcopyall || pcopymapDest[i]))
1153 void *def_ptr = parm_table[i].ptr;
1155 ((char *)pserviceSource) + PTR_DIFF(def_ptr,&sDefault);
1157 ((char *)pserviceDest) + PTR_DIFF(def_ptr,&sDefault);
1159 switch (parm_table[i].type)
1163 *(BOOL *)dest_ptr = *(BOOL *)src_ptr;
1168 *(int *)dest_ptr = *(int *)src_ptr;
1172 *(char *)dest_ptr = *(char *)src_ptr;
1176 string_set(dest_ptr,*(char **)src_ptr);
1180 string_set(dest_ptr,*(char **)src_ptr);
1181 strupper(*(char **)dest_ptr);
1190 init_copymap(pserviceDest);
1191 if (pserviceSource->copymap)
1192 memcpy((void *)pserviceDest->copymap,
1193 (void *)pserviceSource->copymap,sizeof(BOOL)*NUMPARAMETERS);
1197 /***************************************************************************
1198 Check a service for consistency. Return False if the service is in any way
1199 incomplete or faulty, else True.
1200 ***************************************************************************/
1201 static BOOL service_ok(int iService)
1206 if (iSERVICE(iService).szService[0] == '\0')
1208 DEBUG(0,( "The following message indicates an internal error:\n"));
1209 DEBUG(0,( "No service name in service entry.\n"));
1213 /* The [printers] entry MUST be printable. I'm all for flexibility, but */
1214 /* I can't see why you'd want a non-printable printer service... */
1215 if (strwicmp(iSERVICE(iService).szService,PRINTERS_NAME) == 0)
1216 if (!iSERVICE(iService).bPrint_ok)
1218 DEBUG(0,( "WARNING: [%s] service MUST be printable!\n",
1219 iSERVICE(iService).szService));
1220 iSERVICE(iService).bPrint_ok = True;
1223 if (iSERVICE(iService).szPath[0] == '\0' &&
1224 strwicmp(iSERVICE(iService).szService,HOMES_NAME) != 0)
1226 DEBUG(0,("No path in service %s - using /tmp\n",iSERVICE(iService).szService));
1227 string_set(&iSERVICE(iService).szPath,"/tmp");
1230 /* If a service is flagged unavailable, log the fact at level 0. */
1231 if (!iSERVICE(iService).bAvailable)
1232 DEBUG(1,( "NOTE: Service %s is flagged unavailable.\n",
1233 iSERVICE(iService).szService));
1238 static struct file_lists {
1239 struct file_lists *next;
1242 } *file_lists = NULL;
1244 /*******************************************************************
1245 keep a linked list of all config files so we know when one has changed
1246 it's date and needs to be reloaded
1247 ********************************************************************/
1248 static void add_to_file_list(char *fname)
1250 struct file_lists *f=file_lists;
1253 if (f->name && !strcmp(f->name,fname)) break;
1258 f = (struct file_lists *)malloc(sizeof(file_lists[0]));
1260 f->next = file_lists;
1261 f->name = strdup(fname);
1272 standard_sub_basic(n2);
1273 f->modtime = file_modtime(n2);
1278 /*******************************************************************
1279 check if a config file has changed date
1280 ********************************************************************/
1281 BOOL lp_file_list_changed(void)
1283 struct file_lists *f = file_lists;
1287 standard_sub_basic(n2);
1288 if (f->modtime != file_modtime(n2)) return(True);
1295 /***************************************************************************
1296 handle the interpretation of the coding system parameter
1297 *************************************************************************/
1298 static BOOL handle_coding_system(char *pszParmValue,int *val)
1300 *val = interpret_coding_system(pszParmValue,*val);
1305 /***************************************************************************
1306 handle the interpretation of the character set system parameter
1307 ***************************************************************************/
1308 static BOOL handle_character_set(char *pszParmValue,int *val)
1310 string_set(&Globals.szCharacterSet,pszParmValue);
1311 *val = interpret_character_set(pszParmValue,*val);
1316 /***************************************************************************
1317 handle the interpretation of the protocol parameter
1318 ***************************************************************************/
1319 static BOOL handle_protocol(char *pszParmValue,int *val)
1321 *val = interpret_protocol(pszParmValue,*val);
1325 /***************************************************************************
1326 handle the interpretation of the security parameter
1327 ***************************************************************************/
1328 static BOOL handle_security(char *pszParmValue,int *val)
1330 *val = interpret_security(pszParmValue,*val);
1334 /***************************************************************************
1335 handle the interpretation of the default case
1336 ***************************************************************************/
1337 static BOOL handle_case(char *pszParmValue,int *val)
1339 if (strequal(pszParmValue,"LOWER"))
1341 else if (strequal(pszParmValue,"UPPER"))
1346 /***************************************************************************
1347 handle the interpretation of the printing system
1348 ***************************************************************************/
1349 static BOOL handle_printing(char *pszParmValue,int *val)
1351 if (strequal(pszParmValue,"sysv"))
1353 else if (strequal(pszParmValue,"aix"))
1355 else if (strequal(pszParmValue,"hpux"))
1357 else if (strequal(pszParmValue,"bsd"))
1359 else if (strequal(pszParmValue,"qnx"))
1361 else if (strequal(pszParmValue,"plp"))
1363 else if (strequal(pszParmValue,"lprng"))
1368 /***************************************************************************
1369 handle the valid chars lines
1370 ***************************************************************************/
1371 static BOOL handle_valid_chars(char *pszParmValue,char **ptr)
1373 string_set(ptr,pszParmValue);
1375 add_char_string(pszParmValue);
1380 /***************************************************************************
1381 handle the include operation
1382 ***************************************************************************/
1383 static BOOL handle_include(char *pszParmValue,char **ptr)
1386 strcpy(fname,pszParmValue);
1388 add_to_file_list(fname);
1390 standard_sub_basic(fname);
1392 string_set(ptr,fname);
1394 if (file_exist(fname,NULL))
1395 return(pm_process(fname, do_section, do_parameter));
1397 DEBUG(2,("Can't find include file %s\n",fname));
1403 /***************************************************************************
1404 handle the interpretation of the copy parameter
1405 ***************************************************************************/
1406 static BOOL handle_copy(char *pszParmValue,char **ptr)
1410 service serviceTemp;
1412 string_set(ptr,pszParmValue);
1414 init_service(&serviceTemp);
1418 DEBUG(3,("Copying service from service %s\n",pszParmValue));
1420 if ((iTemp = getservicebyname(pszParmValue, &serviceTemp)) >= 0)
1422 if (iTemp == iServiceIndex)
1424 DEBUG(0,("Can't copy service %s - unable to copy self!\n",
1429 copy_service(pSERVICE(iServiceIndex),
1431 iSERVICE(iServiceIndex).copymap);
1437 DEBUG(0,( "Unable to copy service - source not found: %s\n",
1442 free_service(&serviceTemp);
1447 /***************************************************************************
1448 initialise a copymap
1449 ***************************************************************************/
1450 static void init_copymap(service *pservice)
1453 if (pservice->copymap) free(pservice->copymap);
1454 pservice->copymap = (BOOL *)malloc(sizeof(BOOL)*NUMPARAMETERS);
1455 if (!pservice->copymap)
1456 DEBUG(0,("Couldn't allocate copymap!! (size %d)\n",NUMPARAMETERS));
1458 for (i=0;i<NUMPARAMETERS;i++)
1459 pservice->copymap[i] = True;
1463 /***************************************************************************
1464 Process a parameter.
1465 ***************************************************************************/
1466 static BOOL do_parameter(char *pszParmName, char *pszParmValue)
1469 void *parm_ptr=NULL; /* where we are going to store the result */
1472 if (!bInGlobalSection && bGlobalOnly) return(True);
1474 DEBUG(3,("doing parameter %s = %s\n",pszParmName,pszParmValue));
1476 parmnum = map_parameter(pszParmName);
1480 DEBUG(0,( "Ignoring unknown parameter \"%s\"\n", pszParmName));
1484 def_ptr = parm_table[parmnum].ptr;
1486 /* we might point at a service, the default service or a global */
1487 if (bInGlobalSection)
1491 if (parm_table[parmnum].class == P_GLOBAL)
1493 DEBUG(0,( "Global parameter %s found in service section!\n",pszParmName));
1496 parm_ptr = ((char *)pSERVICE(iServiceIndex)) + PTR_DIFF(def_ptr,&sDefault);
1499 if (!bInGlobalSection)
1502 if (!iSERVICE(iServiceIndex).copymap)
1503 init_copymap(pSERVICE(iServiceIndex));
1505 /* this handles the aliases - set the copymap for other entries with
1506 the same data pointer */
1507 for (i=0;parm_table[i].label;i++)
1508 if (parm_table[i].ptr == parm_table[parmnum].ptr)
1509 iSERVICE(iServiceIndex).copymap[i] = False;
1512 /* if it is a special case then go ahead */
1513 if (parm_table[parmnum].special)
1515 parm_table[parmnum].special(pszParmValue,parm_ptr);
1519 /* now switch on the type of variable it is */
1520 switch (parm_table[parmnum].type)
1523 set_boolean(parm_ptr,pszParmValue);
1527 set_boolean(parm_ptr,pszParmValue);
1528 *(BOOL *)parm_ptr = ! *(BOOL *)parm_ptr;
1532 *(int *)parm_ptr = atoi(pszParmValue);
1536 *(char *)parm_ptr = *pszParmValue;
1540 sscanf(pszParmValue,"%o",(int *)parm_ptr);
1544 string_set(parm_ptr,pszParmValue);
1548 string_set(parm_ptr,pszParmValue);
1549 strupper(*(char **)parm_ptr);
1553 strcpy((char *)parm_ptr,pszParmValue);
1557 strcpy((char *)parm_ptr,pszParmValue);
1558 strupper((char *)parm_ptr);
1565 /***************************************************************************
1566 print a parameter of the specified type
1567 ***************************************************************************/
1568 static void print_parameter(parm_type type,void *ptr)
1573 printf("%s",BOOLSTR(*(BOOL *)ptr));
1577 printf("%s",BOOLSTR(! *(BOOL *)ptr));
1581 printf("%d",*(int *)ptr);
1585 printf("%c",*(char *)ptr);
1589 printf("0%o",*(int *)ptr);
1595 printf("%s",(char *)ptr);
1601 printf("%s",*(char **)ptr);
1607 /***************************************************************************
1608 check if two parameters are equal
1609 ***************************************************************************/
1610 static BOOL equal_parameter(parm_type type,void *ptr1,void *ptr2)
1616 return(*((BOOL *)ptr1) == *((BOOL *)ptr2));
1620 return(*((int *)ptr1) == *((int *)ptr2));
1623 return(*((char *)ptr1) == *((char *)ptr2));
1628 char *p1 = (char *)ptr1, *p2 = (char *)ptr2;
1629 if (p1 && !*p1) p1 = NULL;
1630 if (p2 && !*p2) p2 = NULL;
1631 return(p1==p2 || strequal(p1,p2));
1636 char *p1 = *(char **)ptr1, *p2 = *(char **)ptr2;
1637 if (p1 && !*p1) p1 = NULL;
1638 if (p2 && !*p2) p2 = NULL;
1639 return(p1==p2 || strequal(p1,p2));
1645 /***************************************************************************
1646 Process a new section (service). At this stage all sections are services.
1647 Later we'll have special sections that permit server parameters to be set.
1648 Returns True on success, False on failure.
1649 ***************************************************************************/
1650 static BOOL do_section(char *pszSectionName)
1653 BOOL isglobal = ((strwicmp(pszSectionName, GLOBAL_NAME) == 0) ||
1654 (strwicmp(pszSectionName, GLOBAL_NAME2) == 0));
1657 /* if we were in a global section then do the local inits */
1658 if (bInGlobalSection && !isglobal)
1661 /* if we've just struck a global section, note the fact. */
1662 bInGlobalSection = isglobal;
1664 /* check for multiple global sections */
1665 if (bInGlobalSection)
1667 DEBUG(3,( "Processing section \"[%s]\"\n", pszSectionName));
1671 if (!bInGlobalSection && bGlobalOnly) return(True);
1673 /* if we have a current service, tidy it up before moving on */
1676 if (iServiceIndex >= 0)
1677 bRetval = service_ok(iServiceIndex);
1679 /* if all is still well, move to the next record in the services array */
1682 /* We put this here to avoid an odd message order if messages are */
1683 /* issued by the post-processing of a previous section. */
1684 DEBUG(2,( "Processing section \"[%s]\"\n", pszSectionName));
1686 if ((iServiceIndex=add_a_service(&sDefault,pszSectionName)) < 0)
1688 DEBUG(0,("Failed to add a new service\n"));
1696 /***************************************************************************
1697 Display the contents of the global structure.
1698 ***************************************************************************/
1699 static void dump_globals(void)
1702 printf("Global parameters:\n");
1704 for (i=0;parm_table[i].label;i++)
1705 if (parm_table[i].class == P_GLOBAL &&
1706 parm_table[i].ptr &&
1707 (i == 0 || (parm_table[i].ptr != parm_table[i-1].ptr)))
1709 printf("\t%s: ",parm_table[i].label);
1710 print_parameter(parm_table[i].type,parm_table[i].ptr);
1715 /***************************************************************************
1716 Display the contents of a single services record.
1717 ***************************************************************************/
1718 static void dump_a_service(service *pService)
1721 if (pService == &sDefault)
1722 printf("\nDefault service parameters:\n");
1724 printf("\nService parameters [%s]:\n",pService->szService);
1726 for (i=0;parm_table[i].label;i++)
1727 if (parm_table[i].class == P_LOCAL &&
1728 parm_table[i].ptr &&
1729 (*parm_table[i].label != '-') &&
1730 (i == 0 || (parm_table[i].ptr != parm_table[i-1].ptr)))
1732 int pdiff = PTR_DIFF(parm_table[i].ptr,&sDefault);
1734 if (pService == &sDefault || !equal_parameter(parm_table[i].type,
1735 ((char *)pService) + pdiff,
1736 ((char *)&sDefault) + pdiff))
1738 printf("\t%s: ",parm_table[i].label);
1739 print_parameter(parm_table[i].type,
1740 ((char *)pService) + pdiff);
1747 /***************************************************************************
1748 Display the contents of a single copy structure.
1749 ***************************************************************************/
1750 static void dump_copy_map(BOOL *pcopymap)
1753 if (!pcopymap) return;
1755 printf("\n\tNon-Copied parameters:\n");
1757 for (i=0;parm_table[i].label;i++)
1758 if (parm_table[i].class == P_LOCAL &&
1759 parm_table[i].ptr && !pcopymap[i] &&
1760 (i == 0 || (parm_table[i].ptr != parm_table[i-1].ptr)))
1762 printf("\t\t%s\n",parm_table[i].label);
1767 /***************************************************************************
1768 Return TRUE if the passed service number is within range.
1769 ***************************************************************************/
1770 BOOL lp_snum_ok(int iService)
1772 return (LP_SNUM_OK(iService) && iSERVICE(iService).bAvailable);
1776 /***************************************************************************
1777 auto-load some homes and printer services
1778 ***************************************************************************/
1779 static void lp_add_auto_services(char *str)
1783 int homes = lp_servicenumber(HOMES_NAME);
1784 int printers = lp_servicenumber(PRINTERS_NAME);
1792 for (p=strtok(s,LIST_SEP);p;p=strtok(NULL,LIST_SEP))
1794 char *home = get_home_dir(p);
1796 if (lp_servicenumber(p) >= 0) continue;
1798 if (home && homes >= 0)
1800 lp_add_home(p,homes,home);
1804 if (printers >= 0 && pcap_printername_ok(p,NULL))
1805 lp_add_printer(p,printers);
1810 /***************************************************************************
1811 auto-load one printer
1812 ***************************************************************************/
1813 static void lp_add_one_printer(char *name,char *comment)
1815 int printers = lp_servicenumber(PRINTERS_NAME);
1818 if (lp_servicenumber(name) < 0)
1820 lp_add_printer(name,printers);
1821 if ((i=lp_servicenumber(name)) >= 0)
1822 string_set(&iSERVICE(i).comment,comment);
1827 /***************************************************************************
1828 auto-load printer services
1829 ***************************************************************************/
1830 static void lp_add_all_printers(void)
1832 int printers = lp_servicenumber(PRINTERS_NAME);
1834 if (printers < 0) return;
1836 pcap_printer_fn(lp_add_one_printer);
1839 /***************************************************************************
1840 have we loaded a services file yet?
1841 ***************************************************************************/
1842 BOOL lp_loaded(void)
1847 /***************************************************************************
1848 unload unused services
1849 ***************************************************************************/
1850 void lp_killunused(BOOL (*snumused)(int ))
1853 for (i=0;i<iNumServices;i++)
1854 if (VALID(i) && !snumused(i))
1856 iSERVICE(i).valid = False;
1857 free_service(pSERVICE(i));
1861 /***************************************************************************
1862 Load the services array from the services file. Return True on success,
1864 ***************************************************************************/
1865 BOOL lp_load(char *pszFname,BOOL global_only)
1870 add_to_file_list(pszFname);
1874 bInGlobalSection = True;
1875 bGlobalOnly = global_only;
1879 strcpy(n2,pszFname);
1880 standard_sub_basic(n2);
1882 /* We get sections first, so have to start 'behind' to make up */
1884 bRetval = pm_process(n2, do_section, do_parameter);
1886 /* finish up the last section */
1887 DEBUG(3,("pm_process() returned %s\n", BOOLSTR(bRetval)));
1889 if (iServiceIndex >= 0)
1890 bRetval = service_ok(iServiceIndex);
1892 lp_add_auto_services(lp_auto_services());
1893 if (lp_load_printers())
1894 lp_add_all_printers();
1904 /***************************************************************************
1905 return the max number of services
1906 ***************************************************************************/
1907 int lp_numservices(void)
1909 return(iNumServices);
1912 /***************************************************************************
1913 Display the contents of the services array in human-readable form.
1914 ***************************************************************************/
1921 dump_a_service(&sDefault);
1923 for (iService = 0; iService < iNumServices; iService++)
1925 if (VALID(iService))
1927 if (iSERVICE(iService).szService[0] == '\0')
1929 dump_a_service(pSERVICE(iService));
1934 /***************************************************************************
1935 Return the number of the service with the given name, or -1 if it doesn't
1936 exist. Note that this is a DIFFERENT ANIMAL from the internal function
1937 getservicebyname()! This works ONLY if all services have been loaded, and
1938 does not copy the found service.
1939 ***************************************************************************/
1940 int lp_servicenumber(char *pszServiceName)
1944 for (iService = iNumServices - 1; iService >= 0; iService--)
1945 if (VALID(iService) &&
1946 strwicmp(iSERVICE(iService).szService, pszServiceName) == 0)
1950 DEBUG(7,("lp_servicenumber: couldn't find %s\n",pszServiceName));
1955 /*******************************************************************
1956 a useful volume label function
1957 ******************************************************************/
1958 char *volume_label(int snum)
1960 char *ret = lp_volume(snum);
1961 if (!*ret) return(lp_servicename(snum));