2 Unix SMB/Netbios implementation.
4 Parameter loading functions
5 Copyright (C) Karl Auer 1993,1997
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
52 /* Set default coding system for KANJI if none specified in Makefile. */
59 extern int DEBUGLEVEL;
60 extern pstring user_socket_options;
61 extern pstring myname;
64 #define GLOBAL_NAME "global"
68 #define PRINTERS_NAME "printers"
72 #define HOMES_NAME "homes"
75 /* some helpful bits */
76 #define pSERVICE(i) ServicePtrs[i]
77 #define iSERVICE(i) (*pSERVICE(i))
78 #define LP_SNUM_OK(iService) (((iService) >= 0) && ((iService) < iNumServices) && iSERVICE(iService).valid)
79 #define VALID(i) iSERVICE(i).valid
81 /* these are the types of parameter we have */
84 P_BOOL,P_BOOLREV,P_CHAR,P_INTEGER,P_OCTAL,
85 P_STRING,P_USTRING,P_GSTRING,P_UGSTRING,P_ENUM
90 P_LOCAL,P_GLOBAL,P_NONE
94 extern BOOL use_getwd_cache;
96 extern int extra_time_offset;
99 * This structure describes global (ie., server-wide) parameters.
103 char *szPrintcapname;
106 char *szDefaultService;
110 char *szServerString;
111 char *szAutoServices;
112 char *szPasswdProgram;
116 char *szSMBPasswdFile;
117 char *szPasswordServer;
118 char *szSocketOptions;
121 char *szDomainAdminUsers;
122 char *szDomainGuestUsers;
123 char *szDomainHostsallow;
124 char *szDomainHostsdeny;
126 char *szCharacterSet;
133 char *szCodingSystem;
135 char *szRemoteAnnounce;
136 char *szRemoteBrowseSync;
137 char *szSocketAddress;
138 char *szNISHomeMapName;
139 char *szAnnounceVersion; /* This is initialised in init_globals */
140 char *szNetbiosAliases;
142 char *szDomainOtherSIDs;
143 char *szDomainGroups;
166 int client_code_page;
167 int announce_as; /* This is initialised in init_globals */
172 BOOL bPreferredMaster;
173 BOOL bDomainController;
176 BOOL bEncryptPasswords;
183 BOOL bReadPrediction;
190 BOOL bBindInterfacesOnly;
193 static global Globals;
198 * This structure describes a single service.
206 char *szGuestaccount;
207 char *szInvalidUsers;
215 char *szRootPostExec;
216 char *szPrintcommand;
219 char *szLppausecommand;
220 char *szLpresumecommand;
222 char *szPrinterDriver;
223 char *szPrinterDriverLocation;
232 char *szVetoOplockFiles;
241 int iCreate_force_mode;
251 BOOL bShortCasePreserve;
277 BOOL bDeleteReadonly;
279 BOOL bDeleteVetoFiles;
281 char dummy[3]; /* for alignment */
285 /* This is a default service used to prime a services structure */
286 static service sDefault =
289 NULL, /* szService */
291 NULL, /* szUsername */
292 NULL, /* szGuestAccount - this is set in init_globals() */
293 NULL, /* szInvalidUsers */
294 NULL, /* szValidUsers */
295 NULL, /* szAdminUsers */
297 NULL, /* szInclude */
298 NULL, /* szPreExec */
299 NULL, /* szPostExec */
300 NULL, /* szRootPreExec */
301 NULL, /* szRootPostExec */
302 NULL, /* szPrintcommand */
303 NULL, /* szLpqcommand */
304 NULL, /* szLprmcommand */
305 NULL, /* szLppausecommand */
306 NULL, /* szLpresumecommand */
307 NULL, /* szPrintername */
308 NULL, /* szPrinterDriver - this is set in init_globals() */
309 NULL, /* szPrinterDriverLocation */
310 NULL, /* szDontdescend */
311 NULL, /* szHostsallow */
312 NULL, /* szHostsdeny */
313 NULL, /* szMagicScript */
314 NULL, /* szMagicOutput */
315 NULL, /* szMangledMap */
316 NULL, /* szVetoFiles */
317 NULL, /* szHideFiles */
318 NULL, /* szVetoOplockFiles */
320 NULL, /* force user */
321 NULL, /* force group */
323 NULL, /* writelist */
325 0, /* iMinPrintSpace */
326 0744, /* iCreate_mask */
327 0000, /* iCreate_force_mode */
328 0755, /* iDir_mask */
329 0000, /* iDir_force_mode */
330 0, /* iMaxConnections */
331 CASE_LOWER, /* iDefaultCase */
332 DEFAULT_PRINTING, /* iPrinting */
333 False, /* bAlternatePerm */
334 False, /* revalidate */
335 False, /* case sensitive */
336 False, /* case preserve */
337 False, /* short case preserve */
338 False, /* case mangle */
340 True, /* bHideDotFiles */
341 True, /* bBrowseable */
342 True, /* bAvailable */
343 True, /* bRead_only */
344 True, /* bNo_set_dir */
345 False, /* bGuest_only */
346 False, /* bGuest_ok */
347 False, /* bPrint_ok */
348 False, /* bPostscript */
349 False, /* bMap_system */
350 False, /* bMap_hidden */
351 True, /* bMap_archive */
353 False, /* bStrictLocking */
354 True, /* bShareModes */
356 False, /* bOnlyUser */
357 True, /* bMangledNames */
358 True, /* bWidelinks */
359 True, /* bSymlinks */
360 False, /* bSyncAlways */
361 '~', /* magic char */
363 False, /* bDeleteReadonly */
364 False, /* bFakeOplocks */
365 False, /* bDeleteVetoFiles */
366 False, /* bDosFiletimes */
372 /* local variables */
373 static service **ServicePtrs = NULL;
374 static int iNumServices = 0;
375 static int iServiceIndex = 0;
376 static BOOL bInGlobalSection = True;
377 static BOOL bGlobalOnly = False;
378 static int default_server_announce;
380 #define NUMPARAMETERS (sizeof(parm_table) / sizeof(struct parm_struct))
382 /* prototypes for the special type handlers */
383 static BOOL handle_valid_chars(char *pszParmValue, char **ptr);
384 static BOOL handle_include(char *pszParmValue, char **ptr);
385 static BOOL handle_copy(char *pszParmValue, char **ptr);
386 static BOOL handle_character_set(char *pszParmValue,char **ptr);
387 static BOOL handle_coding_system(char *pszParmValue,char **ptr);
389 static void set_default_server_announce_type(void);
396 static struct enum_list enum_protocol[] = {{PROTOCOL_NT1, "NT1"}, {PROTOCOL_LANMAN2, "LANMAN2"},
397 {PROTOCOL_LANMAN1, "LANMAN1"}, {PROTOCOL_CORE,"CORE"},
398 {PROTOCOL_COREPLUS, "COREPLUS"},
399 {PROTOCOL_COREPLUS, "CORE+"}, {-1, NULL}};
401 static struct enum_list enum_security[] = {{SEC_SHARE, "SHARE"}, {SEC_USER, "USER"},
402 {SEC_SERVER, "SERVER"}, {-1, NULL}};
404 static struct enum_list enum_printing[] = {{PRINT_SYSV, "sysv"}, {PRINT_AIX, "aix"},
405 {PRINT_HPUX, "hpux"}, {PRINT_BSD, "bsd"},
406 {PRINT_QNX, "qnx"}, {PRINT_PLP, "plp"},
407 {PRINT_LPRNG, "lprng"}, {-1, NULL}};
409 static struct enum_list enum_announce_as[] = {{ANNOUNCE_AS_NT, "NT"}, {ANNOUNCE_AS_WIN95, "win95"},
410 {ANNOUNCE_AS_WFW, "WfW"}, {-1, NULL}};
412 static struct enum_list enum_case[] = {{CASE_LOWER, "lower"}, {CASE_UPPER, "upper"}, {-1, NULL}};
414 static struct enum_list enum_lm_announce[] = {{0, "False"}, {1, "True"}, {2, "Auto"}};
416 static struct parm_struct
423 struct enum_list *enum_list;
426 {"debuglevel", P_INTEGER, P_GLOBAL, &DEBUGLEVEL, NULL, NULL},
427 {"log level", P_INTEGER, P_GLOBAL, &DEBUGLEVEL, NULL, NULL},
428 {"syslog", P_INTEGER, P_GLOBAL, &Globals.syslog, NULL, NULL},
429 {"syslog only", P_BOOL, P_GLOBAL, &Globals.bSyslogOnly, NULL, NULL},
430 {"protocol", P_ENUM, P_GLOBAL, &Globals.maxprotocol, NULL, enum_protocol},
431 {"security", P_ENUM, P_GLOBAL, &Globals.security, NULL, enum_security},
432 {"max disk size", P_INTEGER, P_GLOBAL, &Globals.maxdisksize, NULL, NULL},
433 {"lpq cache time", P_INTEGER, P_GLOBAL, &Globals.lpqcachetime, NULL, NULL},
434 {"announce as", P_ENUM, P_GLOBAL, &Globals.announce_as, NULL, enum_announce_as},
435 {"encrypt passwords",P_BOOL, P_GLOBAL, &Globals.bEncryptPasswords, NULL, NULL},
436 {"getwd cache", P_BOOL, P_GLOBAL, &use_getwd_cache, NULL, NULL},
437 {"read prediction", P_BOOL, P_GLOBAL, &Globals.bReadPrediction, NULL, NULL},
438 {"read bmpx", P_BOOL, P_GLOBAL, &Globals.bReadbmpx, NULL, NULL},
439 {"read raw", P_BOOL, P_GLOBAL, &Globals.bReadRaw, NULL, NULL},
440 {"write raw", P_BOOL, P_GLOBAL, &Globals.bWriteRaw, NULL, NULL},
441 {"use rhosts", P_BOOL, P_GLOBAL, &Globals.bUseRhosts, NULL, NULL},
442 {"load printers", P_BOOL, P_GLOBAL, &Globals.bLoadPrinters, NULL, NULL},
443 {"null passwords", P_BOOL, P_GLOBAL, &Globals.bNullPasswords, NULL, NULL},
444 {"strip dot", P_BOOL, P_GLOBAL, &Globals.bStripDot, NULL, NULL},
445 {"interfaces", P_STRING, P_GLOBAL, &Globals.szInterfaces, NULL, NULL},
446 {"bind interfaces only", P_BOOL,P_GLOBAL, &Globals.bBindInterfacesOnly,NULL, NULL},
447 {"password server", P_STRING, P_GLOBAL, &Globals.szPasswordServer, NULL, NULL},
448 {"socket options", P_GSTRING, P_GLOBAL, user_socket_options, NULL, NULL},
449 {"netbios name", P_UGSTRING,P_GLOBAL, myname, NULL, NULL},
450 {"netbios aliases", P_STRING, P_GLOBAL, &Globals.szNetbiosAliases, NULL, NULL},
451 {"smbrun", P_STRING, P_GLOBAL, &Globals.szSmbrun, NULL, NULL},
452 {"log file", P_STRING, P_GLOBAL, &Globals.szLogFile, NULL, NULL},
453 {"config file", P_STRING, P_GLOBAL, &Globals.szConfigFile, NULL, NULL},
454 {"smb passwd file", P_STRING, P_GLOBAL, &Globals.szSMBPasswdFile, NULL, NULL},
455 {"hosts equiv", P_STRING, P_GLOBAL, &Globals.szHostsEquiv, NULL, NULL},
456 {"preload", P_STRING, P_GLOBAL, &Globals.szAutoServices, NULL, NULL},
457 {"auto services", P_STRING, P_GLOBAL, &Globals.szAutoServices, NULL, NULL},
458 {"server string", P_STRING, P_GLOBAL, &Globals.szServerString, NULL, NULL},
459 {"printcap name", P_STRING, P_GLOBAL, &Globals.szPrintcapname, NULL, NULL},
460 {"printcap", P_STRING, P_GLOBAL, &Globals.szPrintcapname, NULL, NULL},
461 {"lock dir", P_STRING, P_GLOBAL, &Globals.szLockDir, NULL, NULL},
462 {"lock directory", P_STRING, P_GLOBAL, &Globals.szLockDir, NULL, NULL},
463 {"root directory", P_STRING, P_GLOBAL, &Globals.szRootdir, NULL, NULL},
464 {"root dir", P_STRING, P_GLOBAL, &Globals.szRootdir, NULL, NULL},
465 {"root", P_STRING, P_GLOBAL, &Globals.szRootdir, NULL, NULL},
466 {"default service", P_STRING, P_GLOBAL, &Globals.szDefaultService, NULL, NULL},
467 {"default", P_STRING, P_GLOBAL, &Globals.szDefaultService, NULL, NULL},
468 {"message command", P_STRING, P_GLOBAL, &Globals.szMsgCommand, NULL, NULL},
469 {"dfree command", P_STRING, P_GLOBAL, &Globals.szDfree, NULL, NULL},
470 {"passwd program", P_STRING, P_GLOBAL, &Globals.szPasswdProgram, NULL, NULL},
471 {"passwd chat", P_STRING, P_GLOBAL, &Globals.szPasswdChat, NULL, NULL},
472 {"valid chars", P_STRING, P_GLOBAL, &Globals.szValidChars, handle_valid_chars, NULL},
473 {"workgroup", P_USTRING, P_GLOBAL, &Globals.szWorkGroup, NULL, NULL},
474 {"domain sid", P_USTRING, P_GLOBAL, &Globals.szDomainSID, NULL, NULL},
475 {"domain other sids",P_STRING, P_GLOBAL, &Globals.szDomainOtherSIDs, NULL, NULL},
476 {"domain groups", P_STRING, P_GLOBAL, &Globals.szDomainGroups, NULL, NULL},
477 {"domain controller",P_BOOL , P_GLOBAL, &Globals.bDomainController,NULL, NULL},
478 {"domain admin users",P_STRING, P_GLOBAL, &Globals.szDomainAdminUsers, NULL, NULL},
479 {"domain guest users",P_STRING, P_GLOBAL, &Globals.szDomainGuestUsers, NULL, NULL},
480 {"domain hosts allow",P_STRING, P_GLOBAL, &Globals.szDomainHostsallow, NULL, NULL},
481 {"domain allow hosts",P_STRING, P_GLOBAL, &Globals.szDomainHostsallow, NULL, NULL},
482 {"domain hosts deny", P_STRING, P_GLOBAL, &Globals.szDomainHostsdeny, NULL, NULL},
483 {"domain deny hosts", P_STRING, P_GLOBAL, &Globals.szDomainHostsdeny, NULL, NULL},
484 {"username map", P_STRING, P_GLOBAL, &Globals.szUsernameMap, NULL, NULL},
485 {"character set", P_STRING, P_GLOBAL, &Globals.szCharacterSet, handle_character_set, NULL},
486 {"logon script", P_STRING, P_GLOBAL, &Globals.szLogonScript, NULL, NULL},
487 {"logon path", P_STRING, P_GLOBAL, &Globals.szLogonPath, NULL, NULL},
488 {"logon drive", P_STRING, P_GLOBAL, &Globals.szLogonDrive, NULL, NULL},
489 {"logon home", P_STRING, P_GLOBAL, &Globals.szLogonHome, NULL, NULL},
490 {"remote announce", P_STRING, P_GLOBAL, &Globals.szRemoteAnnounce, NULL, NULL},
491 {"remote browse sync",P_STRING, P_GLOBAL, &Globals.szRemoteBrowseSync,NULL, NULL},
492 {"socket address", P_STRING, P_GLOBAL, &Globals.szSocketAddress, NULL, NULL},
493 {"homedir map", P_STRING, P_GLOBAL, &Globals.szNISHomeMapName, NULL, NULL},
494 {"announce version", P_STRING, P_GLOBAL, &Globals.szAnnounceVersion, NULL, NULL},
495 {"max log size", P_INTEGER, P_GLOBAL, &Globals.max_log_size, NULL, NULL},
496 {"mangled stack", P_INTEGER, P_GLOBAL, &Globals.mangled_stack, NULL, NULL},
497 {"max mux", P_INTEGER, P_GLOBAL, &Globals.max_mux, NULL, NULL},
498 {"max xmit", P_INTEGER, P_GLOBAL, &Globals.max_xmit, NULL, NULL},
499 {"max packet", P_INTEGER, P_GLOBAL, &Globals.max_packet, NULL, NULL},
500 {"packet size", P_INTEGER, P_GLOBAL, &Globals.max_packet, NULL, NULL},
501 {"password level", P_INTEGER, P_GLOBAL, &Globals.pwordlevel, NULL, NULL},
502 {"username level", P_INTEGER, P_GLOBAL, &Globals.unamelevel, NULL, NULL},
503 {"keepalive", P_INTEGER, P_GLOBAL, &keepalive, NULL, NULL},
504 {"deadtime", P_INTEGER, P_GLOBAL, &Globals.deadtime, NULL, NULL},
505 {"time offset", P_INTEGER, P_GLOBAL, &extra_time_offset, NULL, NULL},
506 {"read size", P_INTEGER, P_GLOBAL, &Globals.ReadSize, NULL, NULL},
507 {"shared mem size", P_INTEGER, P_GLOBAL, &Globals.shmem_size, NULL, NULL},
508 {"coding system", P_STRING, P_GLOBAL, &Globals.szCodingSystem, handle_coding_system, NULL},
509 {"client code page", P_INTEGER, P_GLOBAL, &Globals.client_code_page, NULL, NULL},
510 {"os level", P_INTEGER, P_GLOBAL, &Globals.os_level, NULL, NULL},
511 {"max ttl", P_INTEGER, P_GLOBAL, &Globals.max_ttl, NULL, NULL},
512 {"max wins ttl", P_INTEGER, P_GLOBAL, &Globals.max_wins_ttl, NULL, NULL},
513 {"min wins ttl", P_INTEGER, P_GLOBAL, &Globals.min_wins_ttl, NULL, NULL},
514 {"lm announce", P_ENUM, P_GLOBAL, &Globals.lm_announce, NULL, enum_lm_announce},
515 {"lm interval", P_INTEGER, P_GLOBAL, &Globals.lm_interval, NULL, NULL},
516 {"dns proxy", P_BOOL, P_GLOBAL, &Globals.bDNSproxy, NULL, NULL},
517 {"wins support", P_BOOL, P_GLOBAL, &Globals.bWINSsupport, NULL, NULL},
518 {"wins proxy", P_BOOL, P_GLOBAL, &Globals.bWINSproxy, NULL, NULL},
519 {"wins server", P_STRING, P_GLOBAL, &Globals.szWINSserver, NULL, NULL},
520 {"preferred master", P_BOOL, P_GLOBAL, &Globals.bPreferredMaster, NULL, NULL},
521 {"prefered master", P_BOOL, P_GLOBAL, &Globals.bPreferredMaster, NULL, NULL},
522 {"local master", P_BOOL, P_GLOBAL, &Globals.bLocalMaster, NULL, NULL},
523 {"domain master", P_BOOL, P_GLOBAL, &Globals.bDomainMaster, NULL, NULL},
524 {"domain logons", P_BOOL, P_GLOBAL, &Globals.bDomainLogons, NULL, NULL},
525 {"browse list", P_BOOL, P_GLOBAL, &Globals.bBrowseList, NULL, NULL},
526 {"unix realname", P_BOOL, P_GLOBAL, &Globals.bUnixRealname, NULL, NULL},
527 {"NIS homedir", P_BOOL, P_GLOBAL, &Globals.bNISHomeMap, NULL, NULL},
528 {"time server", P_BOOL, P_GLOBAL, &Globals.bTimeServer, NULL, NULL},
529 {"printer driver file", P_STRING, P_GLOBAL, &Globals.szDriverFile, NULL, NULL},
530 {"-valid", P_BOOL, P_LOCAL, &sDefault.valid, NULL, NULL},
531 {"comment", P_STRING, P_LOCAL, &sDefault.comment, NULL, NULL},
532 {"copy", P_STRING, P_LOCAL, &sDefault.szCopy, handle_copy, NULL},
533 {"include", P_STRING, P_LOCAL, &sDefault.szInclude, handle_include, NULL},
534 {"exec", P_STRING, P_LOCAL, &sDefault.szPreExec, NULL, NULL},
535 {"preexec", P_STRING, P_LOCAL, &sDefault.szPreExec, NULL, NULL},
536 {"postexec", P_STRING, P_LOCAL, &sDefault.szPostExec, NULL, NULL},
537 {"root preexec", P_STRING, P_LOCAL, &sDefault.szRootPreExec, NULL, NULL},
538 {"root postexec", P_STRING, P_LOCAL, &sDefault.szRootPostExec, NULL, NULL},
539 {"alternate permissions",P_BOOL,P_LOCAL, &sDefault.bAlternatePerm, NULL, NULL},
540 {"revalidate", P_BOOL, P_LOCAL, &sDefault.bRevalidate, NULL, NULL},
541 {"default case", P_ENUM, P_LOCAL, &sDefault.iDefaultCase, NULL, enum_case},
542 {"case sensitive", P_BOOL, P_LOCAL, &sDefault.bCaseSensitive, NULL, NULL},
543 {"casesignames", P_BOOL, P_LOCAL, &sDefault.bCaseSensitive, NULL, NULL},
544 {"preserve case", P_BOOL, P_LOCAL, &sDefault.bCasePreserve, NULL, NULL},
545 {"short preserve case",P_BOOL, P_LOCAL, &sDefault.bShortCasePreserve,NULL, NULL},
546 {"mangle case", P_BOOL, P_LOCAL, &sDefault.bCaseMangle, NULL, NULL},
547 {"mangling char", P_CHAR, P_LOCAL, &sDefault.magic_char, NULL, NULL},
548 {"browseable", P_BOOL, P_LOCAL, &sDefault.bBrowseable, NULL, NULL},
549 {"browsable", P_BOOL, P_LOCAL, &sDefault.bBrowseable, NULL, NULL},
550 {"available", P_BOOL, P_LOCAL, &sDefault.bAvailable, NULL, NULL},
551 {"path", P_STRING, P_LOCAL, &sDefault.szPath, NULL, NULL},
552 {"directory", P_STRING, P_LOCAL, &sDefault.szPath, NULL, NULL},
553 {"username", P_STRING, P_LOCAL, &sDefault.szUsername, NULL, NULL},
554 {"user", P_STRING, P_LOCAL, &sDefault.szUsername, NULL, NULL},
555 {"users", P_STRING, P_LOCAL, &sDefault.szUsername, NULL, NULL},
556 {"guest account", P_STRING, P_LOCAL, &sDefault.szGuestaccount, NULL, NULL},
557 {"invalid users", P_STRING, P_LOCAL, &sDefault.szInvalidUsers, NULL, NULL},
558 {"valid users", P_STRING, P_LOCAL, &sDefault.szValidUsers, NULL, NULL},
559 {"admin users", P_STRING, P_LOCAL, &sDefault.szAdminUsers, NULL, NULL},
560 {"read list", P_STRING, P_LOCAL, &sDefault.readlist, NULL, NULL},
561 {"write list", P_STRING, P_LOCAL, &sDefault.writelist, NULL, NULL},
562 {"volume", P_STRING, P_LOCAL, &sDefault.volume, NULL, NULL},
563 {"force user", P_STRING, P_LOCAL, &sDefault.force_user, NULL, NULL},
564 {"force group", P_STRING, P_LOCAL, &sDefault.force_group, NULL, NULL},
565 {"group", P_STRING, P_LOCAL, &sDefault.force_group, NULL, NULL},
566 {"read only", P_BOOL, P_LOCAL, &sDefault.bRead_only, NULL, NULL},
567 {"write ok", P_BOOLREV, P_LOCAL, &sDefault.bRead_only, NULL, NULL},
568 {"writeable", P_BOOLREV, P_LOCAL, &sDefault.bRead_only, NULL, NULL},
569 {"writable", P_BOOLREV, P_LOCAL, &sDefault.bRead_only, NULL, NULL},
570 {"max connections", P_INTEGER, P_LOCAL, &sDefault.iMaxConnections, NULL, NULL},
571 {"min print space", P_INTEGER, P_LOCAL, &sDefault.iMinPrintSpace, NULL, NULL},
572 {"create mask", P_OCTAL, P_LOCAL, &sDefault.iCreate_mask, NULL, NULL},
573 {"create mode", P_OCTAL, P_LOCAL, &sDefault.iCreate_mask, NULL, NULL},
574 {"force create mode",P_OCTAL, P_LOCAL, &sDefault.iCreate_force_mode, NULL, NULL},
575 {"directory mask", P_OCTAL, P_LOCAL, &sDefault.iDir_mask, NULL, NULL},
576 {"directory mode", P_OCTAL, P_LOCAL, &sDefault.iDir_mask, NULL, NULL},
577 {"force directory mode", P_OCTAL, P_LOCAL, &sDefault.iDir_force_mode, NULL, NULL},
578 {"set directory", P_BOOLREV, P_LOCAL, &sDefault.bNo_set_dir, NULL, NULL},
579 {"status", P_BOOL, P_LOCAL, &sDefault.status, NULL, NULL},
580 {"hide dot files", P_BOOL, P_LOCAL, &sDefault.bHideDotFiles, NULL, NULL},
581 {"delete veto files",P_BOOL, P_LOCAL, &sDefault.bDeleteVetoFiles, NULL, NULL},
582 {"veto files", P_STRING, P_LOCAL, &sDefault.szVetoFiles, NULL, NULL},
583 {"hide files", P_STRING, P_LOCAL, &sDefault.szHideFiles, NULL, NULL},
584 {"veto oplock files",P_STRING, P_LOCAL, &sDefault.szVetoOplockFiles,NULL, NULL},
585 {"guest only", P_BOOL, P_LOCAL, &sDefault.bGuest_only, NULL, NULL},
586 {"only guest", P_BOOL, P_LOCAL, &sDefault.bGuest_only, NULL, NULL},
587 {"guest ok", P_BOOL, P_LOCAL, &sDefault.bGuest_ok, NULL, NULL},
588 {"public", P_BOOL, P_LOCAL, &sDefault.bGuest_ok, NULL, NULL},
589 {"print ok", P_BOOL, P_LOCAL, &sDefault.bPrint_ok, NULL, NULL},
590 {"printable", P_BOOL, P_LOCAL, &sDefault.bPrint_ok, NULL, NULL},
591 {"postscript", P_BOOL, P_LOCAL, &sDefault.bPostscript, NULL, NULL},
592 {"map system", P_BOOL, P_LOCAL, &sDefault.bMap_system, NULL, NULL},
593 {"map hidden", P_BOOL, P_LOCAL, &sDefault.bMap_hidden, NULL, NULL},
594 {"map archive", P_BOOL, P_LOCAL, &sDefault.bMap_archive, NULL, NULL},
595 {"locking", P_BOOL, P_LOCAL, &sDefault.bLocking, NULL, NULL},
596 {"strict locking", P_BOOL, P_LOCAL, &sDefault.bStrictLocking, NULL, NULL},
597 {"share modes", P_BOOL, P_LOCAL, &sDefault.bShareModes, NULL, NULL},
598 {"oplocks", P_BOOL, P_LOCAL, &sDefault.bOpLocks, NULL, NULL},
599 {"only user", P_BOOL, P_LOCAL, &sDefault.bOnlyUser, NULL, NULL},
600 {"wide links", P_BOOL, P_LOCAL, &sDefault.bWidelinks, NULL, NULL},
601 {"follow symlinks", P_BOOL, P_LOCAL, &sDefault.bSymlinks, NULL, NULL},
602 {"sync always", P_BOOL, P_LOCAL, &sDefault.bSyncAlways, NULL, NULL},
603 {"mangled names", P_BOOL, P_LOCAL, &sDefault.bMangledNames, NULL, NULL},
604 {"fake oplocks", P_BOOL, P_LOCAL, &sDefault.bFakeOplocks, NULL, NULL},
605 {"printing", P_ENUM, P_LOCAL, &sDefault.iPrinting, NULL, enum_printing},
606 {"print command", P_STRING, P_LOCAL, &sDefault.szPrintcommand, NULL, NULL},
607 {"lpq command", P_STRING, P_LOCAL, &sDefault.szLpqcommand, NULL, NULL},
608 {"lprm command", P_STRING, P_LOCAL, &sDefault.szLprmcommand, NULL, NULL},
609 {"lppause command", P_STRING, P_LOCAL, &sDefault.szLppausecommand, NULL, NULL},
610 {"lpresume command", P_STRING, P_LOCAL, &sDefault.szLpresumecommand,NULL, NULL},
611 {"printer", P_STRING, P_LOCAL, &sDefault.szPrintername, NULL, NULL},
612 {"printer name", P_STRING, P_LOCAL, &sDefault.szPrintername, NULL, NULL},
613 {"printer driver", P_STRING, P_LOCAL, &sDefault.szPrinterDriver, NULL, NULL},
614 {"printer driver location", P_STRING, P_LOCAL, &sDefault.szPrinterDriverLocation, NULL, NULL},
615 {"hosts allow", P_STRING, P_LOCAL, &sDefault.szHostsallow, NULL, NULL},
616 {"allow hosts", P_STRING, P_LOCAL, &sDefault.szHostsallow, NULL, NULL},
617 {"hosts deny", P_STRING, P_LOCAL, &sDefault.szHostsdeny, NULL, NULL},
618 {"deny hosts", P_STRING, P_LOCAL, &sDefault.szHostsdeny, NULL, NULL},
619 {"dont descend", P_STRING, P_LOCAL, &sDefault.szDontdescend, NULL, NULL},
620 {"magic script", P_STRING, P_LOCAL, &sDefault.szMagicScript, NULL, NULL},
621 {"magic output", P_STRING, P_LOCAL, &sDefault.szMagicOutput, NULL, NULL},
622 {"mangled map", P_STRING, P_LOCAL, &sDefault.szMangledMap, NULL, NULL},
623 {"delete readonly", P_BOOL, P_LOCAL, &sDefault.bDeleteReadonly, NULL, NULL},
624 {"dos filetimes", P_BOOL, P_LOCAL, &sDefault.bDosFiletimes, NULL, NULL},
626 {NULL, P_BOOL, P_NONE, NULL, NULL, NULL}
631 /***************************************************************************
632 Initialise the global parameter structure.
633 ***************************************************************************/
634 static void init_globals(void)
636 static BOOL done_init = False;
642 bzero((void *)&Globals,sizeof(Globals));
644 for (i = 0; parm_table[i].label; i++)
645 if ((parm_table[i].type == P_STRING ||
646 parm_table[i].type == P_USTRING) &&
648 string_init(parm_table[i].ptr,"");
650 string_set(&sDefault.szGuestaccount, GUEST_ACCOUNT);
651 string_set(&sDefault.szPrinterDriver, "NULL");
657 DEBUG(3,("Initialising global parameters\n"));
659 #ifdef SMB_PASSWD_FILE
660 string_set(&Globals.szSMBPasswdFile, SMB_PASSWD_FILE);
662 string_set(&Globals.szPasswdChat,"*old*password* %o\\n *new*password* %n\\n *new*password* %n\\n *changed*");
663 string_set(&Globals.szWorkGroup, WORKGROUP);
664 string_set(&Globals.szPasswdProgram, SMB_PASSWD);
665 string_set(&Globals.szPrintcapname, PRINTCAP_NAME);
666 string_set(&Globals.szDriverFile, DRIVERFILE);
667 string_set(&Globals.szLockDir, LOCKDIR);
668 string_set(&Globals.szRootdir, "/");
669 string_set(&Globals.szSmbrun, SMBRUN);
670 string_set(&Globals.szSocketAddress, "0.0.0.0");
671 sprintf(s,"Samba %s",VERSION);
672 string_set(&Globals.szServerString,s);
673 sprintf(s,"%d.%d", DEFAULT_MAJOR_VERSION, DEFAULT_MINOR_VERSION);
674 string_set(&Globals.szAnnounceVersion,s);
676 string_set(&Globals.szLogonDrive, "");
677 /* %N is the NIS auto.home server if -DAUTOHOME is used, else same as %L */
678 string_set(&Globals.szLogonHome, "\\\\%N\\%U");
679 string_set(&Globals.szLogonPath, "\\\\%N\\%U\\profile");
681 Globals.bLoadPrinters = True;
682 Globals.bUseRhosts = False;
683 Globals.max_packet = 65535;
684 Globals.mangled_stack = 50;
685 Globals.max_xmit = 65535;
686 Globals.max_mux = 50; /* This is *needed* for profile support. */
687 Globals.lpqcachetime = 10;
688 Globals.pwordlevel = 0;
689 Globals.unamelevel = 0;
690 Globals.deadtime = 0;
691 Globals.max_log_size = 5000;
692 Globals.maxprotocol = PROTOCOL_NT1;
693 Globals.security = SEC_SHARE;
694 Globals.bEncryptPasswords = False;
695 Globals.bReadRaw = True;
696 Globals.bWriteRaw = True;
697 Globals.bReadPrediction = False;
698 Globals.bReadbmpx = True;
699 Globals.bNullPasswords = False;
700 Globals.bStripDot = False;
702 Globals.bSyslogOnly = False;
703 Globals.os_level = 0;
704 Globals.max_ttl = 60*60*4; /* 4 hours default */
705 Globals.max_wins_ttl = 60*60*24*3; /* 3 days default */
706 Globals.min_wins_ttl = 60*60*6; /* 6 hours default */
707 Globals.ReadSize = 16*1024;
708 Globals.lm_announce = 2; /* = Auto: send only if LM clients found */
709 Globals.lm_interval = 60;
710 Globals.shmem_size = SHMEM_SIZE;
711 Globals.announce_as = ANNOUNCE_AS_NT;
712 Globals.bUnixRealname = False;
713 #if (defined(NETGROUP) && defined(AUTOMOUNT))
714 Globals.bNISHomeMap = False;
715 string_set(&Globals.szNISHomeMapName, "auto.home");
717 interpret_coding_system(KANJI);
718 Globals.client_code_page = DEFAULT_CLIENT_CODE_PAGE;
719 Globals.bTimeServer = False;
720 Globals.bBindInterfacesOnly = False;
722 /* these parameters are set to defaults that are more appropriate
723 for the increasing samba install base:
725 as a member of the workgroup, that will possibly become a
726 _local_ master browser (lm = True). this is opposed to a forced
727 local master browser startup (pm = True).
729 doesn't provide WINS server service by default (wsupp = False),
730 and doesn't provide domain master browser services by default, either.
734 Globals.bPreferredMaster = False;
735 Globals.bLocalMaster = True;
736 Globals.bDomainMaster = False;
737 Globals.bDomainLogons = False;
738 Globals.bBrowseList = True;
739 Globals.bWINSsupport = False;
740 Globals.bWINSproxy = False;
742 Globals.bDNSproxy = True;
745 /***************************************************************************
746 check if a string is initialised and if not then initialise it
747 ***************************************************************************/
748 static void string_initial(char **s,char *v)
755 /***************************************************************************
756 Initialise the sDefault parameter structure.
757 ***************************************************************************/
758 static void init_locals(void)
760 /* choose defaults depending on the type of printing */
761 switch (sDefault.iPrinting)
767 string_initial(&sDefault.szLpqcommand,"lpq -P%p");
768 string_initial(&sDefault.szLprmcommand,"lprm -P%p %j");
769 string_initial(&sDefault.szPrintcommand,"lpr -r -P%p %s");
774 string_initial(&sDefault.szLpqcommand,"lpstat -o%p");
775 string_initial(&sDefault.szLprmcommand,"cancel %p-%j");
776 string_initial(&sDefault.szPrintcommand,"lp -c -d%p %s; rm %s");
778 string_initial(&sDefault.szLppausecommand,"lp -i %p-%j -H hold");
779 string_initial(&sDefault.szLpresumecommand,"lp -i %p-%j -H resume");
784 string_initial(&sDefault.szLpqcommand,"lpq -P%p");
785 string_initial(&sDefault.szLprmcommand,"lprm -P%p %j");
786 string_initial(&sDefault.szPrintcommand,"lp -r -P%p %s");
794 /******************************************************************* a
795 convenience routine to grab string parameters into a rotating buffer,
796 and run standard_sub_basic on them. The buffers can be written to by
797 callers without affecting the source string.
798 ********************************************************************/
799 char *lp_string(char *s)
801 static char *bufs[10];
802 static int buflen[10];
803 static int next = -1;
806 int len = s?strlen(s):0;
817 len = MAX(len+100,sizeof(pstring)); /* the +100 is for some
820 if (buflen[next] != len) {
822 if (bufs[next]) free(bufs[next]);
823 bufs[next] = (char *)malloc(len);
825 DEBUG(0,("out of memory in lp_string()"));
830 ret = &bufs[next][0];
838 trim_string(ret, "\"", "\"");
840 standard_sub_basic(ret);
846 In this section all the functions that are used to access the
847 parameters from the rest of the program are defined
850 #define FN_GLOBAL_STRING(fn_name,ptr) \
851 char *fn_name(void) {return(lp_string(*(char **)(ptr) ? *(char **)(ptr) : ""));}
852 #define FN_GLOBAL_BOOL(fn_name,ptr) \
853 BOOL fn_name(void) {return(*(BOOL *)(ptr));}
854 #define FN_GLOBAL_CHAR(fn_name,ptr) \
855 char fn_name(void) {return(*(char *)(ptr));}
856 #define FN_GLOBAL_INTEGER(fn_name,ptr) \
857 int fn_name(void) {return(*(int *)(ptr));}
859 #define FN_LOCAL_STRING(fn_name,val) \
860 char *fn_name(int i) {return(lp_string((LP_SNUM_OK(i)&&pSERVICE(i)->val)?pSERVICE(i)->val : sDefault.val));}
861 #define FN_LOCAL_BOOL(fn_name,val) \
862 BOOL fn_name(int i) {return(LP_SNUM_OK(i)? pSERVICE(i)->val : sDefault.val);}
863 #define FN_LOCAL_CHAR(fn_name,val) \
864 char fn_name(int i) {return(LP_SNUM_OK(i)? pSERVICE(i)->val : sDefault.val);}
865 #define FN_LOCAL_INTEGER(fn_name,val) \
866 int fn_name(int i) {return(LP_SNUM_OK(i)? pSERVICE(i)->val : sDefault.val);}
868 FN_GLOBAL_STRING(lp_logfile,&Globals.szLogFile)
869 FN_GLOBAL_STRING(lp_smbrun,&Globals.szSmbrun)
870 FN_GLOBAL_STRING(lp_configfile,&Globals.szConfigFile)
871 FN_GLOBAL_STRING(lp_smb_passwd_file,&Globals.szSMBPasswdFile)
872 FN_GLOBAL_STRING(lp_serverstring,&Globals.szServerString)
873 FN_GLOBAL_STRING(lp_printcapname,&Globals.szPrintcapname)
874 FN_GLOBAL_STRING(lp_lockdir,&Globals.szLockDir)
875 FN_GLOBAL_STRING(lp_rootdir,&Globals.szRootdir)
876 FN_GLOBAL_STRING(lp_defaultservice,&Globals.szDefaultService)
877 FN_GLOBAL_STRING(lp_msg_command,&Globals.szMsgCommand)
878 FN_GLOBAL_STRING(lp_dfree_command,&Globals.szDfree)
879 FN_GLOBAL_STRING(lp_hosts_equiv,&Globals.szHostsEquiv)
880 FN_GLOBAL_STRING(lp_auto_services,&Globals.szAutoServices)
881 FN_GLOBAL_STRING(lp_passwd_program,&Globals.szPasswdProgram)
882 FN_GLOBAL_STRING(lp_passwd_chat,&Globals.szPasswdChat)
883 FN_GLOBAL_STRING(lp_passwordserver,&Globals.szPasswordServer)
884 FN_GLOBAL_STRING(lp_workgroup,&Globals.szWorkGroup)
885 FN_GLOBAL_STRING(lp_username_map,&Globals.szUsernameMap)
886 FN_GLOBAL_STRING(lp_character_set,&Globals.szCharacterSet)
887 FN_GLOBAL_STRING(lp_logon_script,&Globals.szLogonScript)
888 FN_GLOBAL_STRING(lp_logon_path,&Globals.szLogonPath)
889 FN_GLOBAL_STRING(lp_logon_drive,&Globals.szLogonDrive)
890 FN_GLOBAL_STRING(lp_logon_home,&Globals.szLogonHome)
891 FN_GLOBAL_STRING(lp_remote_announce,&Globals.szRemoteAnnounce)
892 FN_GLOBAL_STRING(lp_remote_browse_sync,&Globals.szRemoteBrowseSync)
893 FN_GLOBAL_STRING(lp_wins_server,&Globals.szWINSserver)
894 FN_GLOBAL_STRING(lp_interfaces,&Globals.szInterfaces)
895 FN_GLOBAL_STRING(lp_socket_address,&Globals.szSocketAddress)
896 FN_GLOBAL_STRING(lp_nis_home_map_name,&Globals.szNISHomeMapName)
897 FN_GLOBAL_STRING(lp_announce_version,&Globals.szAnnounceVersion)
898 FN_GLOBAL_STRING(lp_netbios_aliases,&Globals.szNetbiosAliases)
899 FN_GLOBAL_STRING(lp_driverfile,&Globals.szDriverFile)
901 FN_GLOBAL_STRING(lp_domain_sid,&Globals.szDomainSID)
902 FN_GLOBAL_STRING(lp_domain_other_sids,&Globals.szDomainOtherSIDs)
903 FN_GLOBAL_STRING(lp_domain_groups,&Globals.szDomainGroups)
904 FN_GLOBAL_STRING(lp_domain_admin_users,&Globals.szDomainAdminUsers)
905 FN_GLOBAL_STRING(lp_domain_guest_users,&Globals.szDomainGuestUsers)
906 FN_GLOBAL_STRING(lp_domain_hostsallow,&Globals.szDomainHostsallow)
907 FN_GLOBAL_STRING(lp_domain_hostsdeny,&Globals.szDomainHostsdeny)
910 FN_GLOBAL_BOOL(lp_dns_proxy,&Globals.bDNSproxy)
911 FN_GLOBAL_BOOL(lp_wins_support,&Globals.bWINSsupport)
912 FN_GLOBAL_BOOL(lp_we_are_a_wins_server,&Globals.bWINSsupport)
913 FN_GLOBAL_BOOL(lp_wins_proxy,&Globals.bWINSproxy)
914 FN_GLOBAL_BOOL(lp_local_master,&Globals.bLocalMaster)
915 FN_GLOBAL_BOOL(lp_domain_controller,&Globals.bDomainController)
916 FN_GLOBAL_BOOL(lp_domain_master,&Globals.bDomainMaster)
917 FN_GLOBAL_BOOL(lp_domain_logons,&Globals.bDomainLogons)
918 FN_GLOBAL_BOOL(lp_preferred_master,&Globals.bPreferredMaster)
919 FN_GLOBAL_BOOL(lp_load_printers,&Globals.bLoadPrinters)
920 FN_GLOBAL_BOOL(lp_use_rhosts,&Globals.bUseRhosts)
921 FN_GLOBAL_BOOL(lp_getwdcache,&use_getwd_cache)
922 FN_GLOBAL_BOOL(lp_readprediction,&Globals.bReadPrediction)
923 FN_GLOBAL_BOOL(lp_readbmpx,&Globals.bReadbmpx)
924 FN_GLOBAL_BOOL(lp_readraw,&Globals.bReadRaw)
925 FN_GLOBAL_BOOL(lp_writeraw,&Globals.bWriteRaw)
926 FN_GLOBAL_BOOL(lp_null_passwords,&Globals.bNullPasswords)
927 FN_GLOBAL_BOOL(lp_strip_dot,&Globals.bStripDot)
928 FN_GLOBAL_BOOL(lp_encrypted_passwords,&Globals.bEncryptPasswords)
929 FN_GLOBAL_BOOL(lp_syslog_only,&Globals.bSyslogOnly)
930 FN_GLOBAL_BOOL(lp_browse_list,&Globals.bBrowseList)
931 FN_GLOBAL_BOOL(lp_unix_realname,&Globals.bUnixRealname)
932 FN_GLOBAL_BOOL(lp_nis_home_map,&Globals.bNISHomeMap)
933 FN_GLOBAL_BOOL(lp_time_server,&Globals.bTimeServer)
934 FN_GLOBAL_BOOL(lp_bind_interfaces_only,&Globals.bBindInterfacesOnly)
936 FN_GLOBAL_INTEGER(lp_os_level,&Globals.os_level)
937 FN_GLOBAL_INTEGER(lp_max_ttl,&Globals.max_ttl)
938 FN_GLOBAL_INTEGER(lp_max_wins_ttl,&Globals.max_wins_ttl)
939 FN_GLOBAL_INTEGER(lp_min_wins_ttl,&Globals.max_wins_ttl)
940 FN_GLOBAL_INTEGER(lp_max_log_size,&Globals.max_log_size)
941 FN_GLOBAL_INTEGER(lp_mangledstack,&Globals.mangled_stack)
942 FN_GLOBAL_INTEGER(lp_maxxmit,&Globals.max_xmit)
943 FN_GLOBAL_INTEGER(lp_maxmux,&Globals.max_mux)
944 FN_GLOBAL_INTEGER(lp_maxpacket,&Globals.max_packet)
945 FN_GLOBAL_INTEGER(lp_keepalive,&keepalive)
946 FN_GLOBAL_INTEGER(lp_passwordlevel,&Globals.pwordlevel)
947 FN_GLOBAL_INTEGER(lp_usernamelevel,&Globals.unamelevel)
948 FN_GLOBAL_INTEGER(lp_readsize,&Globals.ReadSize)
949 FN_GLOBAL_INTEGER(lp_shmem_size,&Globals.shmem_size)
950 FN_GLOBAL_INTEGER(lp_deadtime,&Globals.deadtime)
951 FN_GLOBAL_INTEGER(lp_maxprotocol,&Globals.maxprotocol)
952 FN_GLOBAL_INTEGER(lp_security,&Globals.security)
953 FN_GLOBAL_INTEGER(lp_maxdisksize,&Globals.maxdisksize)
954 FN_GLOBAL_INTEGER(lp_lpqcachetime,&Globals.lpqcachetime)
955 FN_GLOBAL_INTEGER(lp_syslog,&Globals.syslog)
956 FN_GLOBAL_INTEGER(lp_client_code_page,&Globals.client_code_page)
957 FN_GLOBAL_INTEGER(lp_announce_as,&Globals.announce_as)
958 FN_GLOBAL_INTEGER(lp_lm_announce,&Globals.lm_announce)
959 FN_GLOBAL_INTEGER(lp_lm_interval,&Globals.lm_interval)
961 FN_LOCAL_STRING(lp_preexec,szPreExec)
962 FN_LOCAL_STRING(lp_postexec,szPostExec)
963 FN_LOCAL_STRING(lp_rootpreexec,szRootPreExec)
964 FN_LOCAL_STRING(lp_rootpostexec,szRootPostExec)
965 FN_LOCAL_STRING(lp_servicename,szService)
966 FN_LOCAL_STRING(lp_pathname,szPath)
967 FN_LOCAL_STRING(lp_dontdescend,szDontdescend)
968 FN_LOCAL_STRING(lp_username,szUsername)
969 FN_LOCAL_STRING(lp_guestaccount,szGuestaccount)
970 FN_LOCAL_STRING(lp_invalid_users,szInvalidUsers)
971 FN_LOCAL_STRING(lp_valid_users,szValidUsers)
972 FN_LOCAL_STRING(lp_admin_users,szAdminUsers)
973 FN_LOCAL_STRING(lp_printcommand,szPrintcommand)
974 FN_LOCAL_STRING(lp_lpqcommand,szLpqcommand)
975 FN_LOCAL_STRING(lp_lprmcommand,szLprmcommand)
976 FN_LOCAL_STRING(lp_lppausecommand,szLppausecommand)
977 FN_LOCAL_STRING(lp_lpresumecommand,szLpresumecommand)
978 FN_LOCAL_STRING(lp_printername,szPrintername)
979 FN_LOCAL_STRING(lp_printerdriver,szPrinterDriver)
980 FN_LOCAL_STRING(lp_hostsallow,szHostsallow)
981 FN_LOCAL_STRING(lp_hostsdeny,szHostsdeny)
982 FN_LOCAL_STRING(lp_magicscript,szMagicScript)
983 FN_LOCAL_STRING(lp_magicoutput,szMagicOutput)
984 FN_LOCAL_STRING(lp_comment,comment)
985 FN_LOCAL_STRING(lp_force_user,force_user)
986 FN_LOCAL_STRING(lp_force_group,force_group)
987 FN_LOCAL_STRING(lp_readlist,readlist)
988 FN_LOCAL_STRING(lp_writelist,writelist)
989 FN_LOCAL_STRING(lp_volume,volume)
990 FN_LOCAL_STRING(lp_mangled_map,szMangledMap)
991 FN_LOCAL_STRING(lp_veto_files,szVetoFiles)
992 FN_LOCAL_STRING(lp_hide_files,szHideFiles)
993 FN_LOCAL_STRING(lp_veto_oplocks,szVetoFiles)
994 FN_LOCAL_STRING(lp_driverlocation,szPrinterDriverLocation)
996 FN_LOCAL_BOOL(lp_alternate_permissions,bAlternatePerm)
997 FN_LOCAL_BOOL(lp_revalidate,bRevalidate)
998 FN_LOCAL_BOOL(lp_casesensitive,bCaseSensitive)
999 FN_LOCAL_BOOL(lp_preservecase,bCasePreserve)
1000 FN_LOCAL_BOOL(lp_shortpreservecase,bShortCasePreserve)
1001 FN_LOCAL_BOOL(lp_casemangle,bCaseMangle)
1002 FN_LOCAL_BOOL(lp_status,status)
1003 FN_LOCAL_BOOL(lp_hide_dot_files,bHideDotFiles)
1004 FN_LOCAL_BOOL(lp_browseable,bBrowseable)
1005 FN_LOCAL_BOOL(lp_readonly,bRead_only)
1006 FN_LOCAL_BOOL(lp_no_set_dir,bNo_set_dir)
1007 FN_LOCAL_BOOL(lp_guest_ok,bGuest_ok)
1008 FN_LOCAL_BOOL(lp_guest_only,bGuest_only)
1009 FN_LOCAL_BOOL(lp_print_ok,bPrint_ok)
1010 FN_LOCAL_BOOL(lp_postscript,bPostscript)
1011 FN_LOCAL_BOOL(lp_map_hidden,bMap_hidden)
1012 FN_LOCAL_BOOL(lp_map_archive,bMap_archive)
1013 FN_LOCAL_BOOL(lp_locking,bLocking)
1014 FN_LOCAL_BOOL(lp_strict_locking,bStrictLocking)
1015 FN_LOCAL_BOOL(lp_share_modes,bShareModes)
1016 FN_LOCAL_BOOL(lp_oplocks,bOpLocks)
1017 FN_LOCAL_BOOL(lp_onlyuser,bOnlyUser)
1018 FN_LOCAL_BOOL(lp_manglednames,bMangledNames)
1019 FN_LOCAL_BOOL(lp_widelinks,bWidelinks)
1020 FN_LOCAL_BOOL(lp_symlinks,bSymlinks)
1021 FN_LOCAL_BOOL(lp_syncalways,bSyncAlways)
1022 FN_LOCAL_BOOL(lp_map_system,bMap_system)
1023 FN_LOCAL_BOOL(lp_delete_readonly,bDeleteReadonly)
1024 FN_LOCAL_BOOL(lp_fake_oplocks,bFakeOplocks)
1025 FN_LOCAL_BOOL(lp_recursive_veto_delete,bDeleteVetoFiles)
1026 FN_LOCAL_BOOL(lp_dos_filetimes,bDosFiletimes)
1028 FN_LOCAL_INTEGER(lp_create_mode,iCreate_mask)
1029 FN_LOCAL_INTEGER(lp_force_create_mode,iCreate_force_mode)
1030 FN_LOCAL_INTEGER(lp_dir_mode,iDir_mask)
1031 FN_LOCAL_INTEGER(lp_force_dir_mode,iDir_force_mode)
1032 FN_LOCAL_INTEGER(lp_max_connections,iMaxConnections)
1033 FN_LOCAL_INTEGER(lp_defaultcase,iDefaultCase)
1034 FN_LOCAL_INTEGER(lp_minprintspace,iMinPrintSpace)
1035 FN_LOCAL_INTEGER(lp_printing,iPrinting)
1037 FN_LOCAL_CHAR(lp_magicchar,magic_char)
1041 /* local prototypes */
1042 static int strwicmp( char *psz1, char *psz2 );
1043 static int map_parameter( char *pszParmName);
1044 static BOOL set_boolean( BOOL *pb, char *pszParmValue );
1045 static int getservicebyname(char *pszServiceName, service *pserviceDest);
1046 static void copy_service( service *pserviceDest,
1047 service *pserviceSource,
1048 BOOL *pcopymapDest );
1049 static BOOL service_ok(int iService);
1050 static BOOL do_parameter(char *pszParmName, char *pszParmValue);
1051 static BOOL do_section(char *pszSectionName);
1052 static void init_copymap(service *pservice);
1055 /***************************************************************************
1056 initialise a service to the defaults
1057 ***************************************************************************/
1058 static void init_service(service *pservice)
1060 bzero((char *)pservice,sizeof(service));
1061 copy_service(pservice,&sDefault,NULL);
1065 /***************************************************************************
1066 free the dynamically allocated parts of a service struct
1067 ***************************************************************************/
1068 static void free_service(service *pservice)
1074 for (i=0;parm_table[i].label;i++)
1075 if ((parm_table[i].type == P_STRING ||
1076 parm_table[i].type == P_STRING) &&
1077 parm_table[i].class == P_LOCAL)
1078 string_free((char **)(((char *)pservice) + PTR_DIFF(parm_table[i].ptr,&sDefault)));
1081 /***************************************************************************
1082 add a new service to the services array initialising it with the given
1084 ***************************************************************************/
1085 static int add_a_service(service *pservice, char *name)
1089 int num_to_alloc = iNumServices+1;
1091 tservice = *pservice;
1093 /* it might already exist */
1096 i = getservicebyname(name,NULL);
1101 /* find an invalid one */
1102 for (i=0;i<iNumServices;i++)
1103 if (!pSERVICE(i)->valid)
1106 /* if not, then create one */
1107 if (i == iNumServices)
1109 ServicePtrs = (service **)Realloc(ServicePtrs,sizeof(service *)*num_to_alloc);
1111 pSERVICE(iNumServices) = (service *)malloc(sizeof(service));
1113 if (!ServicePtrs || !pSERVICE(iNumServices))
1119 free_service(pSERVICE(i));
1121 pSERVICE(i)->valid = True;
1123 init_service(pSERVICE(i));
1124 copy_service(pSERVICE(i),&tservice,NULL);
1126 string_set(&iSERVICE(i).szService,name);
1131 /***************************************************************************
1132 add a new home service, with the specified home directory, defaults coming
1134 ***************************************************************************/
1135 BOOL lp_add_home(char *pszHomename, int iDefaultService, char *pszHomedir)
1137 int i = add_a_service(pSERVICE(iDefaultService),pszHomename);
1142 if (!(*(iSERVICE(i).szPath)) || strequal(iSERVICE(i).szPath,lp_pathname(-1)))
1143 string_set(&iSERVICE(i).szPath,pszHomedir);
1144 if (!(*(iSERVICE(i).comment)))
1147 sprintf(comment,"Home directory of %s",pszHomename);
1148 string_set(&iSERVICE(i).comment,comment);
1150 iSERVICE(i).bAvailable = sDefault.bAvailable;
1151 iSERVICE(i).bBrowseable = sDefault.bBrowseable;
1153 DEBUG(3,("adding home directory %s at %s\n", pszHomename, pszHomedir));
1158 /***************************************************************************
1159 add a new service, based on an old one
1160 ***************************************************************************/
1161 int lp_add_service(char *pszService, int iDefaultService)
1163 return(add_a_service(pSERVICE(iDefaultService),pszService));
1167 /***************************************************************************
1169 ***************************************************************************/
1170 static BOOL lp_add_ipc(void)
1173 int i = add_a_service(&sDefault,"IPC$");
1178 sprintf(comment,"IPC Service (%s)",lp_serverstring());
1180 string_set(&iSERVICE(i).szPath,tmpdir());
1181 string_set(&iSERVICE(i).szUsername,"");
1182 string_set(&iSERVICE(i).comment,comment);
1183 iSERVICE(i).status = False;
1184 iSERVICE(i).iMaxConnections = 0;
1185 iSERVICE(i).bAvailable = True;
1186 iSERVICE(i).bRead_only = True;
1187 iSERVICE(i).bGuest_only = False;
1188 iSERVICE(i).bGuest_ok = True;
1189 iSERVICE(i).bPrint_ok = False;
1190 iSERVICE(i).bBrowseable = sDefault.bBrowseable;
1192 DEBUG(3,("adding IPC service\n"));
1198 /***************************************************************************
1199 add a new printer service, with defaults coming from service iFrom
1200 ***************************************************************************/
1201 BOOL lp_add_printer(char *pszPrintername, int iDefaultService)
1203 char *comment = "From Printcap";
1204 int i = add_a_service(pSERVICE(iDefaultService),pszPrintername);
1209 /* note that we do NOT default the availability flag to True - */
1210 /* we take it from the default service passed. This allows all */
1211 /* dynamic printers to be disabled by disabling the [printers] */
1212 /* entry (if/when the 'available' keyword is implemented!). */
1214 /* the printer name is set to the service name. */
1215 string_set(&iSERVICE(i).szPrintername,pszPrintername);
1216 string_set(&iSERVICE(i).comment,comment);
1217 iSERVICE(i).bBrowseable = sDefault.bBrowseable;
1218 /* Printers cannot be read_only. */
1219 iSERVICE(i).bRead_only = False;
1220 /* No share modes on printer services. */
1221 iSERVICE(i).bShareModes = False;
1222 /* No oplocks on printer services. */
1223 iSERVICE(i).bOpLocks = False;
1224 /* Printer services must be printable. */
1225 iSERVICE(i).bPrint_ok = True;
1227 DEBUG(3,("adding printer service %s\n",pszPrintername));
1233 /***************************************************************************
1234 Do a case-insensitive, whitespace-ignoring string compare.
1235 ***************************************************************************/
1236 static int strwicmp(char *psz1, char *psz2)
1238 /* if BOTH strings are NULL, return TRUE, if ONE is NULL return */
1239 /* appropriate value. */
1249 /* sync the strings on first non-whitespace */
1252 while (isspace(*psz1))
1254 while (isspace(*psz2))
1256 if (toupper(*psz1) != toupper(*psz2) || *psz1 == '\0' || *psz2 == '\0')
1261 return (*psz1 - *psz2);
1264 /***************************************************************************
1265 Map a parameter's string representation to something we can use.
1266 Returns False if the parameter string is not recognised, else TRUE.
1267 ***************************************************************************/
1268 static int map_parameter(char *pszParmName)
1272 if (*pszParmName == '-')
1275 for (iIndex = 0; parm_table[iIndex].label; iIndex++)
1276 if (strwicmp(parm_table[iIndex].label, pszParmName) == 0)
1279 DEBUG(0,( "Unknown parameter encountered: \"%s\"\n", pszParmName));
1284 /***************************************************************************
1285 Set a boolean variable from the text value stored in the passed string.
1286 Returns True in success, False if the passed string does not correctly
1287 represent a boolean.
1288 ***************************************************************************/
1289 static BOOL set_boolean(BOOL *pb, char *pszParmValue)
1294 if (strwicmp(pszParmValue, "yes") == 0 ||
1295 strwicmp(pszParmValue, "true") == 0 ||
1296 strwicmp(pszParmValue, "1") == 0)
1299 if (strwicmp(pszParmValue, "no") == 0 ||
1300 strwicmp(pszParmValue, "False") == 0 ||
1301 strwicmp(pszParmValue, "0") == 0)
1305 DEBUG(0,( "Badly formed boolean in configuration file: \"%s\".\n",
1312 /***************************************************************************
1313 Find a service by name. Otherwise works like get_service.
1314 ***************************************************************************/
1315 static int getservicebyname(char *pszServiceName, service *pserviceDest)
1319 for (iService = iNumServices - 1; iService >= 0; iService--)
1320 if (VALID(iService) &&
1321 strwicmp(iSERVICE(iService).szService, pszServiceName) == 0)
1323 if (pserviceDest != NULL)
1324 copy_service(pserviceDest, pSERVICE(iService), NULL);
1333 /***************************************************************************
1334 Copy a service structure to another
1336 If pcopymapDest is NULL then copy all fields
1337 ***************************************************************************/
1338 static void copy_service(service *pserviceDest,
1339 service *pserviceSource,
1343 BOOL bcopyall = (pcopymapDest == NULL);
1345 for (i=0;parm_table[i].label;i++)
1346 if (parm_table[i].ptr && parm_table[i].class == P_LOCAL &&
1347 (bcopyall || pcopymapDest[i]))
1349 void *def_ptr = parm_table[i].ptr;
1351 ((char *)pserviceSource) + PTR_DIFF(def_ptr,&sDefault);
1353 ((char *)pserviceDest) + PTR_DIFF(def_ptr,&sDefault);
1355 switch (parm_table[i].type)
1359 *(BOOL *)dest_ptr = *(BOOL *)src_ptr;
1365 *(int *)dest_ptr = *(int *)src_ptr;
1369 *(char *)dest_ptr = *(char *)src_ptr;
1373 string_set(dest_ptr,*(char **)src_ptr);
1377 string_set(dest_ptr,*(char **)src_ptr);
1378 strupper(*(char **)dest_ptr);
1387 init_copymap(pserviceDest);
1388 if (pserviceSource->copymap)
1389 memcpy((void *)pserviceDest->copymap,
1390 (void *)pserviceSource->copymap,sizeof(BOOL)*NUMPARAMETERS);
1394 /***************************************************************************
1395 Check a service for consistency. Return False if the service is in any way
1396 incomplete or faulty, else True.
1397 ***************************************************************************/
1398 static BOOL service_ok(int iService)
1403 if (iSERVICE(iService).szService[0] == '\0')
1405 DEBUG(0,( "The following message indicates an internal error:\n"));
1406 DEBUG(0,( "No service name in service entry.\n"));
1410 /* The [printers] entry MUST be printable. I'm all for flexibility, but */
1411 /* I can't see why you'd want a non-printable printer service... */
1412 if (strwicmp(iSERVICE(iService).szService,PRINTERS_NAME) == 0)
1413 if (!iSERVICE(iService).bPrint_ok)
1415 DEBUG(0,( "WARNING: [%s] service MUST be printable!\n",
1416 iSERVICE(iService).szService));
1417 iSERVICE(iService).bPrint_ok = True;
1420 if (iSERVICE(iService).szPath[0] == '\0' &&
1421 strwicmp(iSERVICE(iService).szService,HOMES_NAME) != 0)
1423 DEBUG(0,("No path in service %s - using %s\n",iSERVICE(iService).szService,tmpdir()));
1424 string_set(&iSERVICE(iService).szPath,tmpdir());
1427 /* If a service is flagged unavailable, log the fact at level 0. */
1428 if (!iSERVICE(iService).bAvailable)
1429 DEBUG(1,( "NOTE: Service %s is flagged unavailable.\n",
1430 iSERVICE(iService).szService));
1435 static struct file_lists {
1436 struct file_lists *next;
1439 } *file_lists = NULL;
1441 /*******************************************************************
1442 keep a linked list of all config files so we know when one has changed
1443 it's date and needs to be reloaded
1444 ********************************************************************/
1445 static void add_to_file_list(char *fname)
1447 struct file_lists *f=file_lists;
1450 if (f->name && !strcmp(f->name,fname)) break;
1455 f = (struct file_lists *)malloc(sizeof(file_lists[0]));
1457 f->next = file_lists;
1458 f->name = strdup(fname);
1469 standard_sub_basic(n2);
1470 f->modtime = file_modtime(n2);
1475 /*******************************************************************
1476 check if a config file has changed date
1477 ********************************************************************/
1478 BOOL lp_file_list_changed(void)
1480 struct file_lists *f = file_lists;
1481 DEBUG(6,("lp_file_list_changed()\n"));
1488 pstrcpy(n2,f->name);
1489 standard_sub_basic(n2);
1491 DEBUG(6,("file %s -> %s last mod_time: %s\n",
1492 f->name, n2, ctime(&f->modtime)));
1494 mod_time = file_modtime(n2);
1496 if (f->modtime != mod_time) {
1497 DEBUG(6,("file %s modified: %s\n", n2, ctime(&mod_time)));
1498 f->modtime = mod_time;
1506 /***************************************************************************
1507 handle the interpretation of the coding system parameter
1508 *************************************************************************/
1509 static BOOL handle_coding_system(char *pszParmValue,char **ptr)
1511 string_set(ptr,pszParmValue);
1512 interpret_coding_system(pszParmValue);
1516 /***************************************************************************
1517 handle the interpretation of the character set system parameter
1518 ***************************************************************************/
1519 static BOOL handle_character_set(char *pszParmValue,char **ptr)
1521 string_set(ptr,pszParmValue);
1522 interpret_character_set(pszParmValue);
1527 /***************************************************************************
1528 handle the valid chars lines
1529 ***************************************************************************/
1530 static BOOL handle_valid_chars(char *pszParmValue,char **ptr)
1532 string_set(ptr,pszParmValue);
1534 /* A dependency here is that the parameter client code page must be
1535 set before this is called - as calling codepage_initialise()
1536 would overwrite the valid char lines.
1538 codepage_initialise(lp_client_code_page());
1540 add_char_string(pszParmValue);
1545 /***************************************************************************
1546 handle the include operation
1547 ***************************************************************************/
1548 static BOOL handle_include(char *pszParmValue,char **ptr)
1551 pstrcpy(fname,pszParmValue);
1553 add_to_file_list(fname);
1555 standard_sub_basic(fname);
1557 string_set(ptr,fname);
1559 if (file_exist(fname,NULL))
1560 return(pm_process(fname, do_section, do_parameter));
1562 DEBUG(2,("Can't find include file %s\n",fname));
1568 /***************************************************************************
1569 handle the interpretation of the copy parameter
1570 ***************************************************************************/
1571 static BOOL handle_copy(char *pszParmValue,char **ptr)
1575 service serviceTemp;
1577 string_set(ptr,pszParmValue);
1579 init_service(&serviceTemp);
1583 DEBUG(3,("Copying service from service %s\n",pszParmValue));
1585 if ((iTemp = getservicebyname(pszParmValue, &serviceTemp)) >= 0)
1587 if (iTemp == iServiceIndex)
1589 DEBUG(0,("Can't copy service %s - unable to copy self!\n",
1594 copy_service(pSERVICE(iServiceIndex),
1596 iSERVICE(iServiceIndex).copymap);
1602 DEBUG(0,( "Unable to copy service - source not found: %s\n",
1607 free_service(&serviceTemp);
1612 /***************************************************************************
1613 initialise a copymap
1614 ***************************************************************************/
1615 static void init_copymap(service *pservice)
1618 if (pservice->copymap) free(pservice->copymap);
1619 pservice->copymap = (BOOL *)malloc(sizeof(BOOL)*NUMPARAMETERS);
1620 if (!pservice->copymap)
1621 DEBUG(0,("Couldn't allocate copymap!! (size %d)\n",NUMPARAMETERS));
1623 for (i=0;i<NUMPARAMETERS;i++)
1624 pservice->copymap[i] = True;
1628 /***************************************************************************
1629 Process a parameter for a particular service number. If snum < 0
1630 then assume we are in the globals
1631 ***************************************************************************/
1632 BOOL lp_do_parameter(int snum, char *pszParmName, char *pszParmValue)
1635 void *parm_ptr=NULL; /* where we are going to store the result */
1638 parmnum = map_parameter(pszParmName);
1642 DEBUG(0,( "Ignoring unknown parameter \"%s\"\n", pszParmName));
1646 def_ptr = parm_table[parmnum].ptr;
1648 /* we might point at a service, the default service or a global */
1652 if (parm_table[parmnum].class == P_GLOBAL) {
1653 DEBUG(0,( "Global parameter %s found in service section!\n",pszParmName));
1656 parm_ptr = ((char *)pSERVICE(snum)) + PTR_DIFF(def_ptr,&sDefault);
1660 if (!iSERVICE(snum).copymap)
1661 init_copymap(pSERVICE(snum));
1663 /* this handles the aliases - set the copymap for other entries with
1664 the same data pointer */
1665 for (i=0;parm_table[i].label;i++)
1666 if (parm_table[i].ptr == parm_table[parmnum].ptr)
1667 iSERVICE(snum).copymap[i] = False;
1670 /* if it is a special case then go ahead */
1671 if (parm_table[parmnum].special) {
1672 parm_table[parmnum].special(pszParmValue,parm_ptr);
1676 /* now switch on the type of variable it is */
1677 switch (parm_table[parmnum].type)
1680 set_boolean(parm_ptr,pszParmValue);
1684 set_boolean(parm_ptr,pszParmValue);
1685 *(BOOL *)parm_ptr = ! *(BOOL *)parm_ptr;
1689 *(int *)parm_ptr = atoi(pszParmValue);
1693 *(char *)parm_ptr = *pszParmValue;
1697 sscanf(pszParmValue,"%o",(int *)parm_ptr);
1701 string_set(parm_ptr,pszParmValue);
1705 string_set(parm_ptr,pszParmValue);
1706 strupper(*(char **)parm_ptr);
1710 strcpy((char *)parm_ptr,pszParmValue);
1714 strcpy((char *)parm_ptr,pszParmValue);
1715 strupper((char *)parm_ptr);
1719 for (i=0;parm_table[parmnum].enum_list[i].name;i++) {
1720 if (strequal(pszParmValue, parm_table[parmnum].enum_list[i].name)) {
1721 *(int *)parm_ptr = parm_table[parmnum].enum_list[i].value;
1731 /***************************************************************************
1732 Process a parameter.
1733 ***************************************************************************/
1734 static BOOL do_parameter(char *pszParmName, char *pszParmValue)
1736 if (!bInGlobalSection && bGlobalOnly) return(True);
1738 DEBUG(3,("doing parameter %s = %s\n",pszParmName,pszParmValue));
1740 return lp_do_parameter(bInGlobalSection?-2:iServiceIndex, pszParmName, pszParmValue);
1744 /***************************************************************************
1745 print a parameter of the specified type
1746 ***************************************************************************/
1747 static void print_parameter(struct parm_struct *p,void *ptr, FILE *f)
1752 for (i=0;p->enum_list[i].name;i++) {
1753 if (*(int *)ptr == p->enum_list[i].value) {
1754 fprintf(f,"%s",p->enum_list[i].name);
1761 fprintf(f,"%s",BOOLSTR(*(BOOL *)ptr));
1765 fprintf(f,"%s",BOOLSTR(! *(BOOL *)ptr));
1769 fprintf(f,"%d",*(int *)ptr);
1773 fprintf(f,"%c",*(char *)ptr);
1777 fprintf(f,"0%o",*(int *)ptr);
1783 fprintf(f,"%s",(char *)ptr);
1789 fprintf(f,"%s",*(char **)ptr);
1795 /***************************************************************************
1796 print a parameter of the specified type
1797 ***************************************************************************/
1798 static void parameter_string(struct parm_struct *p,void *ptr,char *s)
1805 for (i=0;p->enum_list[i].name;i++) {
1806 if (*(int *)ptr == p->enum_list[i].value) {
1807 sprintf(s,"%s",p->enum_list[i].name);
1814 sprintf(s, "%s",BOOLSTR(*(BOOL *)ptr));
1818 sprintf(s, "%s",BOOLSTR(! *(BOOL *)ptr));
1822 sprintf(s, "%d",*(int *)ptr);
1826 sprintf(s, "%c",*(char *)ptr);
1830 sprintf(s, "0%o",*(int *)ptr);
1836 sprintf(s, "%s",(char *)ptr);
1842 sprintf(s, "%s",*(char **)ptr);
1848 /***************************************************************************
1849 check if two parameters are equal
1850 ***************************************************************************/
1851 static BOOL equal_parameter(parm_type type,void *ptr1,void *ptr2)
1857 return(*((BOOL *)ptr1) == *((BOOL *)ptr2));
1862 return(*((int *)ptr1) == *((int *)ptr2));
1865 return(*((char *)ptr1) == *((char *)ptr2));
1870 char *p1 = (char *)ptr1, *p2 = (char *)ptr2;
1871 if (p1 && !*p1) p1 = NULL;
1872 if (p2 && !*p2) p2 = NULL;
1873 return(p1==p2 || strequal(p1,p2));
1878 char *p1 = *(char **)ptr1, *p2 = *(char **)ptr2;
1879 if (p1 && !*p1) p1 = NULL;
1880 if (p2 && !*p2) p2 = NULL;
1881 return(p1==p2 || strequal(p1,p2));
1887 /***************************************************************************
1888 Process a new section (service). At this stage all sections are services.
1889 Later we'll have special sections that permit server parameters to be set.
1890 Returns True on success, False on failure.
1891 ***************************************************************************/
1892 static BOOL do_section(char *pszSectionName)
1895 BOOL isglobal = ((strwicmp(pszSectionName, GLOBAL_NAME) == 0) ||
1896 (strwicmp(pszSectionName, GLOBAL_NAME2) == 0));
1899 /* if we were in a global section then do the local inits */
1900 if (bInGlobalSection && !isglobal)
1903 /* if we've just struck a global section, note the fact. */
1904 bInGlobalSection = isglobal;
1906 /* check for multiple global sections */
1907 if (bInGlobalSection)
1909 DEBUG(3,( "Processing section \"[%s]\"\n", pszSectionName));
1913 if (!bInGlobalSection && bGlobalOnly) return(True);
1915 /* if we have a current service, tidy it up before moving on */
1918 if (iServiceIndex >= 0)
1919 bRetval = service_ok(iServiceIndex);
1921 /* if all is still well, move to the next record in the services array */
1924 /* We put this here to avoid an odd message order if messages are */
1925 /* issued by the post-processing of a previous section. */
1926 DEBUG(2,( "Processing section \"[%s]\"\n", pszSectionName));
1928 if ((iServiceIndex=add_a_service(&sDefault,pszSectionName)) < 0)
1930 DEBUG(0,("Failed to add a new service\n"));
1938 /***************************************************************************
1939 Display the contents of the global structure.
1940 ***************************************************************************/
1941 static void dump_globals(FILE *f)
1944 fprintf(f, "# Global parameters\n");
1946 for (i=0;parm_table[i].label;i++)
1947 if (parm_table[i].class == P_GLOBAL &&
1948 parm_table[i].ptr &&
1949 (i == 0 || (parm_table[i].ptr != parm_table[i-1].ptr)))
1951 fprintf(f,"\t%s = ",parm_table[i].label);
1952 print_parameter(&parm_table[i],parm_table[i].ptr, f);
1957 /***************************************************************************
1958 Display the contents of a single services record.
1959 ***************************************************************************/
1960 static void dump_a_service(service *pService, FILE *f)
1963 if (pService == &sDefault)
1964 fprintf(f,"\n\n# Default service parameters\n");
1966 fprintf(f,"\n[%s]\n",pService->szService);
1968 for (i=0;parm_table[i].label;i++)
1969 if (parm_table[i].class == P_LOCAL &&
1970 parm_table[i].ptr &&
1971 (*parm_table[i].label != '-') &&
1972 (i == 0 || (parm_table[i].ptr != parm_table[i-1].ptr)))
1974 int pdiff = PTR_DIFF(parm_table[i].ptr,&sDefault);
1976 if (pService == &sDefault || !equal_parameter(parm_table[i].type,
1977 ((char *)pService) + pdiff,
1978 ((char *)&sDefault) + pdiff))
1980 fprintf(f,"\t%s = ",parm_table[i].label);
1981 print_parameter(&parm_table[i],
1982 ((char *)pService) + pdiff, f);
1989 /***************************************************************************
1990 return info about the next service in a service. snum==-1 gives the default
1991 serice and snum==-2 gives the globals
1993 return 0 when out of parameters
1994 ***************************************************************************/
1995 int lp_next_parameter(int snum, int *i, char *label,
1996 char *value, int allparameters)
1999 /* do the globals */
2000 for (;parm_table[*i].label;(*i)++)
2001 if (parm_table[*i].class == P_GLOBAL &&
2002 parm_table[*i].ptr &&
2003 (*parm_table[*i].label != '-') &&
2005 (parm_table[*i].ptr != parm_table[(*i)-1].ptr))) {
2006 strcpy(label, parm_table[*i].label);
2007 parameter_string(&parm_table[*i],
2015 service *pService = (snum==-1?&sDefault:pSERVICE(snum));
2017 for (;parm_table[*i].label;(*i)++)
2018 if (parm_table[*i].class == P_LOCAL &&
2019 parm_table[*i].ptr &&
2020 (*parm_table[*i].label != '-') &&
2022 (parm_table[*i].ptr != parm_table[(*i)-1].ptr))) {
2023 int pdiff = PTR_DIFF(parm_table[*i].ptr,&sDefault);
2025 if (snum == -1 || allparameters ||
2026 !equal_parameter(parm_table[*i].type,
2027 ((char *)pService) + pdiff,
2028 ((char *)&sDefault) + pdiff)) {
2029 strcpy(label, parm_table[*i].label);
2030 parameter_string(&parm_table[*i],
2031 ((char *)pService) + pdiff,
2044 /***************************************************************************
2045 Display the contents of a single copy structure.
2046 ***************************************************************************/
2047 static void dump_copy_map(BOOL *pcopymap)
2050 if (!pcopymap) return;
2052 printf("\n\tNon-Copied parameters:\n");
2054 for (i=0;parm_table[i].label;i++)
2055 if (parm_table[i].class == P_LOCAL &&
2056 parm_table[i].ptr && !pcopymap[i] &&
2057 (i == 0 || (parm_table[i].ptr != parm_table[i-1].ptr)))
2059 printf("\t\t%s\n",parm_table[i].label);
2064 /***************************************************************************
2065 Return TRUE if the passed service number is within range.
2066 ***************************************************************************/
2067 BOOL lp_snum_ok(int iService)
2069 return (LP_SNUM_OK(iService) && iSERVICE(iService).bAvailable);
2073 /***************************************************************************
2074 auto-load some homes and printer services
2075 ***************************************************************************/
2076 static void lp_add_auto_services(char *str)
2080 int homes = lp_servicenumber(HOMES_NAME);
2081 int printers = lp_servicenumber(PRINTERS_NAME);
2089 for (p=strtok(s,LIST_SEP);p;p=strtok(NULL,LIST_SEP))
2091 char *home = get_home_dir(p);
2093 if (lp_servicenumber(p) >= 0) continue;
2095 if (home && homes >= 0)
2097 lp_add_home(p,homes,home);
2101 if (printers >= 0 && pcap_printername_ok(p,NULL))
2102 lp_add_printer(p,printers);
2107 /***************************************************************************
2108 auto-load one printer
2109 ***************************************************************************/
2110 static void lp_add_one_printer(char *name,char *comment)
2112 int printers = lp_servicenumber(PRINTERS_NAME);
2115 if (lp_servicenumber(name) < 0)
2117 lp_add_printer(name,printers);
2118 if ((i=lp_servicenumber(name)) >= 0)
2119 string_set(&iSERVICE(i).comment,comment);
2124 /***************************************************************************
2125 auto-load printer services
2126 ***************************************************************************/
2127 static void lp_add_all_printers(void)
2129 int printers = lp_servicenumber(PRINTERS_NAME);
2131 if (printers < 0) return;
2133 pcap_printer_fn(lp_add_one_printer);
2136 /***************************************************************************
2137 have we loaded a services file yet?
2138 ***************************************************************************/
2139 BOOL lp_loaded(void)
2144 /***************************************************************************
2145 unload unused services
2146 ***************************************************************************/
2147 void lp_killunused(BOOL (*snumused)(int ))
2150 for (i=0;i<iNumServices;i++)
2151 if (VALID(i) && (!snumused || !snumused(i)))
2153 iSERVICE(i).valid = False;
2154 free_service(pSERVICE(i));
2158 /***************************************************************************
2159 Load the services array from the services file. Return True on success,
2161 ***************************************************************************/
2162 BOOL lp_load(char *pszFname,BOOL global_only)
2167 add_to_file_list(pszFname);
2171 bInGlobalSection = True;
2172 bGlobalOnly = global_only;
2176 pstrcpy(n2,pszFname);
2177 standard_sub_basic(n2);
2179 /* We get sections first, so have to start 'behind' to make up */
2181 bRetval = pm_process(n2, do_section, do_parameter);
2183 /* finish up the last section */
2184 DEBUG(3,("pm_process() returned %s\n", BOOLSTR(bRetval)));
2186 if (iServiceIndex >= 0)
2187 bRetval = service_ok(iServiceIndex);
2189 lp_add_auto_services(lp_auto_services());
2190 if (lp_load_printers())
2191 lp_add_all_printers();
2195 set_default_server_announce_type();
2203 /***************************************************************************
2204 return the max number of services
2205 ***************************************************************************/
2206 int lp_numservices(void)
2208 return(iNumServices);
2211 /***************************************************************************
2212 Display the contents of the services array in human-readable form.
2213 ***************************************************************************/
2214 void lp_dump(FILE *f)
2220 dump_a_service(&sDefault, f);
2222 for (iService = 0; iService < iNumServices; iService++)
2224 if (VALID(iService))
2226 if (iSERVICE(iService).szService[0] == '\0')
2228 dump_a_service(pSERVICE(iService), f);
2234 /***************************************************************************
2235 Return the number of the service with the given name, or -1 if it doesn't
2236 exist. Note that this is a DIFFERENT ANIMAL from the internal function
2237 getservicebyname()! This works ONLY if all services have been loaded, and
2238 does not copy the found service.
2239 ***************************************************************************/
2240 int lp_servicenumber(char *pszServiceName)
2244 for (iService = iNumServices - 1; iService >= 0; iService--)
2245 if (VALID(iService) &&
2246 strequal(lp_servicename(iService), pszServiceName))
2250 DEBUG(7,("lp_servicenumber: couldn't find %s\n",pszServiceName));
2255 /*******************************************************************
2256 a useful volume label function
2257 ******************************************************************/
2258 char *volume_label(int snum)
2260 char *ret = lp_volume(snum);
2261 if (!*ret) return(lp_servicename(snum));
2267 * nmbd only loads the global section. There seems to be no way to
2268 * determine exactly is a service is printable by only looking at the
2269 * [global] section so for now always announce as a print server. This
2270 * will need looking at in the future. Jeremy (jallison@whistle.com).
2272 /*******************************************************************
2273 Return true if any printer services are defined.
2274 ******************************************************************/
2275 static BOOL lp_printer_services(void)
2279 for (iService = iNumServices - 1; iService >= 0; iService--)
2280 if (VALID(iService) && iSERVICE(iService).bPrint_ok)
2286 /*******************************************************************
2287 Set the server type we will announce as via nmbd.
2288 ********************************************************************/
2289 static void set_default_server_announce_type()
2291 default_server_announce = (SV_TYPE_WORKSTATION | SV_TYPE_SERVER |
2292 SV_TYPE_SERVER_UNIX | SV_TYPE_PRINTQ_SERVER);
2293 if(lp_announce_as() == ANNOUNCE_AS_NT)
2294 default_server_announce |= (SV_TYPE_SERVER_NT | SV_TYPE_NT);
2295 else if(lp_announce_as() == ANNOUNCE_AS_WIN95)
2296 default_server_announce |= SV_TYPE_WIN95_PLUS;
2297 else if(lp_announce_as() == ANNOUNCE_AS_WFW)
2298 default_server_announce |= SV_TYPE_WFW;
2299 default_server_announce |= (lp_time_server() ? SV_TYPE_TIME_SOURCE : 0);
2301 * nmbd only loads the [global] section. There seems to be no way to
2302 * determine exactly if any service is printable by only looking at the
2303 * [global] section so for now always announce as a print server. This
2304 * will need looking at in the future. Jeremy (jallison@whistle.com).
2307 default_server_announce |= (lp_printer_services() ? SV_TYPE_PRINTQ_SERVER : 0);
2312 /*******************************************************************
2314 ********************************************************************/
2315 void lp_rename_service(int snum, char *new_name)
2317 string_set(&pSERVICE(snum)->szService, new_name);
2320 /*******************************************************************
2322 ********************************************************************/
2323 void lp_remove_service(int snum)
2325 pSERVICE(snum)->valid = False;
2328 /*******************************************************************
2330 ********************************************************************/
2331 void lp_copy_service(int snum, char *new_name)
2333 char *oldname = lp_servicename(snum);
2334 do_section(new_name);
2336 snum = lp_servicenumber(new_name);
2338 lp_do_parameter(snum, "copy", oldname);
2343 /*******************************************************************
2344 Get the default server type we will announce as via nmbd.
2345 ********************************************************************/
2346 int lp_default_server_announce(void)
2348 return default_server_announce;
2351 /*******************************************************************
2352 Split the announce version into major and minor numbers.
2353 ********************************************************************/
2354 int lp_major_announce_version(void)
2356 static BOOL got_major = False;
2357 static int major_version = DEFAULT_MAJOR_VERSION;
2362 return major_version;
2365 if((vers = lp_announce_version()) == NULL)
2366 return major_version;
2368 if((p = strchr(vers, '.')) == 0)
2369 return major_version;
2372 major_version = atoi(vers);
2373 return major_version;
2376 int lp_minor_announce_version(void)
2378 static BOOL got_minor = False;
2379 static int minor_version = DEFAULT_MINOR_VERSION;
2384 return minor_version;
2387 if((vers = lp_announce_version()) == NULL)
2388 return minor_version;
2390 if((p = strchr(vers, '.')) == 0)
2391 return minor_version;
2394 minor_version = atoi(p);
2395 return minor_version;