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
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;
135 char *szRemoteAnnounce;
136 char *szSocketAddress;
137 char *szNISHomeMapName;
138 char *szAnnounceVersion; /* This is initialised in init_globals */
157 int client_code_page;
158 int announce_as; /* This is initialised in init_globals */
163 BOOL bPreferredMaster;
166 BOOL bEncryptPasswords;
173 BOOL bReadPrediction;
182 static global Globals;
187 * This structure describes a single service.
195 char *szGuestaccount;
196 char *szInvalidUsers;
204 char *szRootPostExec;
205 char *szPrintcommand;
208 char *szLppausecommand;
209 char *szLpresumecommand;
211 char *szPrinterDriver;
228 int iCreate_force_mode;
237 BOOL bShortCasePreserve;
262 BOOL bDeleteReadonly;
264 char dummy[3]; /* for alignment */
268 /* This is a default service used to prime a services structure */
269 static service sDefault =
272 NULL, /* szService */
274 NULL, /* szUsername */
275 NULL, /* szGuestAccount - this is set in init_globals() */
276 NULL, /* szInvalidUsers */
277 NULL, /* szValidUsers */
278 NULL, /* szAdminUsers */
280 NULL, /* szInclude */
281 NULL, /* szPreExec */
282 NULL, /* szPostExec */
283 NULL, /* szRootPreExec */
284 NULL, /* szRootPostExec */
285 NULL, /* szPrintcommand */
286 NULL, /* szLpqcommand */
287 NULL, /* szLprmcommand */
288 NULL, /* szLppausecommand */
289 NULL, /* szLpresumecommand */
290 NULL, /* szPrintername */
291 NULL, /* szPrinterDriver - this is set in init_globals() */
292 NULL, /* szDontdescend */
293 NULL, /* szHostsallow */
294 NULL, /* szHostsdeny */
295 NULL, /* szMagicScript */
296 NULL, /* szMagicOutput */
297 NULL, /* szMangledMap */
298 NULL, /* szVetoFiles */
299 NULL, /* szHideFiles */
301 NULL, /* force user */
302 NULL, /* force group */
304 NULL, /* writelist */
306 0, /* iMinPrintSpace */
307 0744, /* iCreate_mask */
308 0000, /* iCreate_force_mode */
309 0755, /* iDir_mask */
310 0000, /* iDir_force_mode */
311 0, /* iMaxConnections */
312 CASE_LOWER, /* iDefaultCase */
313 False, /* bAlternatePerm */
314 False, /* revalidate */
315 False, /* case sensitive */
316 False, /* case preserve */
317 False, /* short case preserve */
318 False, /* case mangle */
320 True, /* bHideDotFiles */
321 True, /* bBrowseable */
322 True, /* bAvailable */
323 True, /* bRead_only */
324 True, /* bNo_set_dir */
325 False, /* bGuest_only */
326 False, /* bGuest_ok */
327 False, /* bPrint_ok */
328 False, /* bPostscript */
329 False, /* bMap_system */
330 False, /* bMap_hidden */
331 True, /* bMap_archive */
333 False, /* bStrictLocking */
334 True, /* bShareModes */
335 False, /* bOnlyUser */
336 True, /* bMangledNames */
337 True, /* bWidelinks */
338 True, /* bSymlinks */
339 False, /* bSyncAlways */
340 '~', /* magic char */
342 False, /* bDeleteReadonly */
343 False, /* bFakeOplocks */
349 /* local variables */
350 static service **ServicePtrs = NULL;
351 static int iNumServices = 0;
352 static int iServiceIndex = 0;
353 static BOOL bInGlobalSection = True;
354 static BOOL bGlobalOnly = False;
355 static int default_server_announce;
357 #define NUMPARAMETERS (sizeof(parm_table) / sizeof(struct parm_struct))
359 /* prototypes for the special type handlers */
360 static BOOL handle_valid_chars(char *pszParmValue, char **ptr);
361 static BOOL handle_include(char *pszParmValue, char **ptr);
362 static BOOL handle_copy(char *pszParmValue, char **ptr);
363 static BOOL handle_protocol(char *pszParmValue,int *val);
364 static BOOL handle_security(char *pszParmValue,int *val);
365 static BOOL handle_case(char *pszParmValue,int *val);
366 static BOOL handle_printing(char *pszParmValue,int *val);
367 static BOOL handle_character_set(char *pszParmValue,int *val);
368 static BOOL handle_announce_as(char *pszParmValue, int *val);
370 static BOOL handle_coding_system(char *pszParmValue,int *val);
382 {"debuglevel", P_INTEGER, P_GLOBAL, &DEBUGLEVEL, NULL},
383 {"log level", P_INTEGER, P_GLOBAL, &DEBUGLEVEL, NULL},
384 {"syslog", P_INTEGER, P_GLOBAL, &Globals.syslog, NULL},
385 {"syslog only", P_BOOL, P_GLOBAL, &Globals.bSyslogOnly, NULL},
386 {"protocol", P_INTEGER, P_GLOBAL, &Globals.maxprotocol,handle_protocol},
387 {"security", P_INTEGER, P_GLOBAL, &Globals.security,handle_security},
388 {"printing", P_INTEGER, P_GLOBAL, &Globals.printing,handle_printing},
389 {"max disk size", P_INTEGER, P_GLOBAL, &Globals.maxdisksize, NULL},
390 {"lpq cache time", P_INTEGER, P_GLOBAL, &Globals.lpqcachetime, NULL},
391 {"announce as", P_INTEGER, P_GLOBAL, &Globals.announce_as, handle_announce_as},
392 {"encrypt passwords",P_BOOL, P_GLOBAL, &Globals.bEncryptPasswords, NULL},
393 {"getwd cache", P_BOOL, P_GLOBAL, &use_getwd_cache, NULL},
394 {"read prediction", P_BOOL, P_GLOBAL, &Globals.bReadPrediction, NULL},
395 {"read bmpx", P_BOOL, P_GLOBAL, &Globals.bReadbmpx, NULL},
396 {"read raw", P_BOOL, P_GLOBAL, &Globals.bReadRaw, NULL},
397 {"write raw", P_BOOL, P_GLOBAL, &Globals.bWriteRaw, NULL},
398 {"use rhosts", P_BOOL, P_GLOBAL, &Globals.bUseRhosts, NULL},
399 {"load printers", P_BOOL, P_GLOBAL, &Globals.bLoadPrinters, NULL},
400 {"null passwords", P_BOOL, P_GLOBAL, &Globals.bNullPasswords, NULL},
401 {"strip dot", P_BOOL, P_GLOBAL, &Globals.bStripDot, NULL},
402 {"interfaces", P_STRING, P_GLOBAL, &Globals.szInterfaces, NULL},
403 {"password server", P_STRING, P_GLOBAL, &Globals.szPasswordServer, NULL},
404 {"socket options", P_GSTRING, P_GLOBAL, user_socket_options, NULL},
405 {"netbios name", P_UGSTRING,P_GLOBAL, myname, NULL},
406 {"smbrun", P_STRING, P_GLOBAL, &Globals.szSmbrun, NULL},
407 {"log file", P_STRING, P_GLOBAL, &Globals.szLogFile, NULL},
408 {"config file", P_STRING, P_GLOBAL, &Globals.szConfigFile, NULL},
409 {"smb passwd file", P_STRING, P_GLOBAL, &Globals.szSMBPasswdFile, NULL},
410 {"hosts equiv", P_STRING, P_GLOBAL, &Globals.szHostsEquiv, NULL},
411 {"preload", P_STRING, P_GLOBAL, &Globals.szAutoServices, NULL},
412 {"auto services", P_STRING, P_GLOBAL, &Globals.szAutoServices, NULL},
413 {"server string", P_STRING, P_GLOBAL, &Globals.szServerString, NULL},
414 {"printcap name", P_STRING, P_GLOBAL, &Globals.szPrintcapname, NULL},
415 {"printcap", P_STRING, P_GLOBAL, &Globals.szPrintcapname, NULL},
416 {"lock dir", P_STRING, P_GLOBAL, &Globals.szLockDir, NULL},
417 {"lock directory", P_STRING, P_GLOBAL, &Globals.szLockDir, NULL},
418 {"root directory", P_STRING, P_GLOBAL, &Globals.szRootdir, NULL},
419 {"root dir", P_STRING, P_GLOBAL, &Globals.szRootdir, NULL},
420 {"root", P_STRING, P_GLOBAL, &Globals.szRootdir, NULL},
421 {"default service", P_STRING, P_GLOBAL, &Globals.szDefaultService, NULL},
422 {"default", P_STRING, P_GLOBAL, &Globals.szDefaultService, NULL},
423 {"message command", P_STRING, P_GLOBAL, &Globals.szMsgCommand, NULL},
424 {"dfree command", P_STRING, P_GLOBAL, &Globals.szDfree, NULL},
425 {"passwd program", P_STRING, P_GLOBAL, &Globals.szPasswdProgram, NULL},
426 {"passwd chat", P_STRING, P_GLOBAL, &Globals.szPasswdChat, NULL},
427 {"valid chars", P_STRING, P_GLOBAL, &Globals.szValidChars, handle_valid_chars},
428 {"workgroup", P_USTRING, P_GLOBAL, &Globals.szWorkGroup, NULL},
429 {"domain controller",P_STRING, P_GLOBAL, &Globals.szDomainController,NULL},
430 {"username map", P_STRING, P_GLOBAL, &Globals.szUsernameMap, NULL},
431 {"character set", P_STRING, P_GLOBAL, &Globals.szCharacterSet, handle_character_set},
432 {"logon script", P_STRING, P_GLOBAL, &Globals.szLogonScript, NULL},
433 {"logon path", P_STRING, P_GLOBAL, &Globals.szLogonPath, NULL},
434 {"remote announce", P_STRING, P_GLOBAL, &Globals.szRemoteAnnounce, NULL},
435 {"socket address", P_STRING, P_GLOBAL, &Globals.szSocketAddress, NULL},
436 {"homedir map", P_STRING, P_GLOBAL, &Globals.szNISHomeMapName, NULL},
437 {"announce version", P_STRING, P_GLOBAL, &Globals.szAnnounceVersion, NULL},
438 {"max log size", P_INTEGER, P_GLOBAL, &Globals.max_log_size, NULL},
439 {"mangled stack", P_INTEGER, P_GLOBAL, &Globals.mangled_stack, NULL},
440 {"max mux", P_INTEGER, P_GLOBAL, &Globals.max_mux, NULL},
441 {"max xmit", P_INTEGER, P_GLOBAL, &Globals.max_xmit, NULL},
442 {"max packet", P_INTEGER, P_GLOBAL, &Globals.max_packet, NULL},
443 {"packet size", P_INTEGER, P_GLOBAL, &Globals.max_packet, NULL},
444 {"password level", P_INTEGER, P_GLOBAL, &Globals.pwordlevel, NULL},
445 {"keepalive", P_INTEGER, P_GLOBAL, &keepalive, NULL},
446 {"deadtime", P_INTEGER, P_GLOBAL, &Globals.deadtime, NULL},
447 {"time offset", P_INTEGER, P_GLOBAL, &extra_time_offset, NULL},
448 {"read size", P_INTEGER, P_GLOBAL, &Globals.ReadSize, NULL},
449 {"shared mem size", P_INTEGER, P_GLOBAL, &Globals.shmem_size, NULL},
450 {"shared file entries", P_INTEGER, P_GLOBAL, &Globals.shmem_hash_size, NULL},
452 {"coding system", P_INTEGER, P_GLOBAL, &coding_system, handle_coding_system},
454 {"client code page", P_INTEGER, P_GLOBAL, &Globals.client_code_page, NULL},
455 {"os level", P_INTEGER, P_GLOBAL, &Globals.os_level, NULL},
456 {"max ttl", P_INTEGER, P_GLOBAL, &Globals.max_ttl, NULL},
457 {"dns proxy", P_BOOL, P_GLOBAL, &Globals.bDNSproxy, NULL},
458 {"wins support", P_BOOL, P_GLOBAL, &Globals.bWINSsupport, NULL},
459 {"wins proxy", P_BOOL, P_GLOBAL, &Globals.bWINSproxy, NULL},
460 {"wins server", P_STRING, P_GLOBAL, &Globals.szWINSserver, NULL},
461 {"preferred master", P_BOOL, P_GLOBAL, &Globals.bPreferredMaster, NULL},
462 {"prefered master", P_BOOL, P_GLOBAL, &Globals.bPreferredMaster, NULL},
463 {"local master", P_BOOL, P_GLOBAL, &Globals.bLocalMaster, NULL},
464 {"domain master", P_BOOL, P_GLOBAL, &Globals.bDomainMaster, NULL},
465 {"domain logons", P_BOOL, P_GLOBAL, &Globals.bDomainLogons, NULL},
466 {"browse list", P_BOOL, P_GLOBAL, &Globals.bBrowseList, NULL},
467 {"unix realname", P_BOOL, P_GLOBAL, &Globals.bUnixRealname, NULL},
468 {"NIS homedir", P_BOOL, P_GLOBAL, &Globals.bNISHomeMap, NULL},
469 {"time server", P_BOOL, P_GLOBAL, &Globals.bTimeServer, NULL},
470 {"-valid", P_BOOL, P_LOCAL, &sDefault.valid, NULL},
471 {"comment", P_STRING, P_LOCAL, &sDefault.comment, NULL},
472 {"copy", P_STRING, P_LOCAL, &sDefault.szCopy, handle_copy},
473 {"include", P_STRING, P_LOCAL, &sDefault.szInclude, handle_include},
474 {"exec", P_STRING, P_LOCAL, &sDefault.szPreExec, NULL},
475 {"preexec", P_STRING, P_LOCAL, &sDefault.szPreExec, NULL},
476 {"postexec", P_STRING, P_LOCAL, &sDefault.szPostExec, NULL},
477 {"root preexec", P_STRING, P_LOCAL, &sDefault.szRootPreExec, NULL},
478 {"root postexec", P_STRING, P_LOCAL, &sDefault.szRootPostExec, NULL},
479 {"alternate permissions",P_BOOL,P_LOCAL, &sDefault.bAlternatePerm, NULL},
480 {"revalidate", P_BOOL, P_LOCAL, &sDefault.bRevalidate, NULL},
481 {"default case", P_INTEGER, P_LOCAL, &sDefault.iDefaultCase, handle_case},
482 {"case sensitive", P_BOOL, P_LOCAL, &sDefault.bCaseSensitive, NULL},
483 {"casesignames", P_BOOL, P_LOCAL, &sDefault.bCaseSensitive, NULL},
484 {"preserve case", P_BOOL, P_LOCAL, &sDefault.bCasePreserve, NULL},
485 {"short preserve case",P_BOOL, P_LOCAL, &sDefault.bShortCasePreserve,NULL},
486 {"mangle case", P_BOOL, P_LOCAL, &sDefault.bCaseMangle, NULL},
487 {"mangling char", P_CHAR, P_LOCAL, &sDefault.magic_char, NULL},
488 {"browseable", P_BOOL, P_LOCAL, &sDefault.bBrowseable, NULL},
489 {"browsable", P_BOOL, P_LOCAL, &sDefault.bBrowseable, NULL},
490 {"available", P_BOOL, P_LOCAL, &sDefault.bAvailable, NULL},
491 {"path", P_STRING, P_LOCAL, &sDefault.szPath, NULL},
492 {"directory", P_STRING, P_LOCAL, &sDefault.szPath, NULL},
493 {"username", P_STRING, P_LOCAL, &sDefault.szUsername, NULL},
494 {"user", P_STRING, P_LOCAL, &sDefault.szUsername, NULL},
495 {"users", P_STRING, P_LOCAL, &sDefault.szUsername, NULL},
496 {"guest account", P_STRING, P_LOCAL, &sDefault.szGuestaccount, NULL},
497 {"invalid users", P_STRING, P_LOCAL, &sDefault.szInvalidUsers, NULL},
498 {"valid users", P_STRING, P_LOCAL, &sDefault.szValidUsers, NULL},
499 {"admin users", P_STRING, P_LOCAL, &sDefault.szAdminUsers, NULL},
500 {"read list", P_STRING, P_LOCAL, &sDefault.readlist, NULL},
501 {"write list", P_STRING, P_LOCAL, &sDefault.writelist, NULL},
502 {"volume", P_STRING, P_LOCAL, &sDefault.volume, NULL},
503 {"force user", P_STRING, P_LOCAL, &sDefault.force_user, NULL},
504 {"force group", P_STRING, P_LOCAL, &sDefault.force_group, NULL},
505 {"group", P_STRING, P_LOCAL, &sDefault.force_group, NULL},
506 {"read only", P_BOOL, P_LOCAL, &sDefault.bRead_only, NULL},
507 {"write ok", P_BOOLREV, P_LOCAL, &sDefault.bRead_only, NULL},
508 {"writeable", P_BOOLREV, P_LOCAL, &sDefault.bRead_only, NULL},
509 {"writable", P_BOOLREV, P_LOCAL, &sDefault.bRead_only, NULL},
510 {"max connections", P_INTEGER, P_LOCAL, &sDefault.iMaxConnections, NULL},
511 {"min print space", P_INTEGER, P_LOCAL, &sDefault.iMinPrintSpace, NULL},
512 {"create mask", P_OCTAL, P_LOCAL, &sDefault.iCreate_mask, NULL},
513 {"create mode", P_OCTAL, P_LOCAL, &sDefault.iCreate_mask, NULL},
514 {"force create mode",P_OCTAL, P_LOCAL, &sDefault.iCreate_force_mode, NULL},
515 {"directory mask", P_OCTAL, P_LOCAL, &sDefault.iDir_mask, NULL},
516 {"directory mode", P_OCTAL, P_LOCAL, &sDefault.iDir_mask, NULL},
517 {"force directory mode", P_OCTAL, P_LOCAL, &sDefault.iDir_force_mode, NULL},
518 {"set directory", P_BOOLREV, P_LOCAL, &sDefault.bNo_set_dir, NULL},
519 {"status", P_BOOL, P_LOCAL, &sDefault.status, NULL},
520 {"hide dot files", P_BOOL, P_LOCAL, &sDefault.bHideDotFiles, NULL},
521 {"veto files", P_STRING, P_LOCAL, &sDefault.szVetoFiles, NULL},
522 {"hide files", P_STRING, P_LOCAL, &sDefault.szHideFiles, NULL},
523 {"guest only", P_BOOL, P_LOCAL, &sDefault.bGuest_only, NULL},
524 {"only guest", P_BOOL, P_LOCAL, &sDefault.bGuest_only, NULL},
525 {"guest ok", P_BOOL, P_LOCAL, &sDefault.bGuest_ok, NULL},
526 {"public", P_BOOL, P_LOCAL, &sDefault.bGuest_ok, NULL},
527 {"print ok", P_BOOL, P_LOCAL, &sDefault.bPrint_ok, NULL},
528 {"printable", P_BOOL, P_LOCAL, &sDefault.bPrint_ok, NULL},
529 {"postscript", P_BOOL, P_LOCAL, &sDefault.bPostscript, NULL},
530 {"map system", P_BOOL, P_LOCAL, &sDefault.bMap_system, NULL},
531 {"map hidden", P_BOOL, P_LOCAL, &sDefault.bMap_hidden, NULL},
532 {"map archive", P_BOOL, P_LOCAL, &sDefault.bMap_archive, NULL},
533 {"locking", P_BOOL, P_LOCAL, &sDefault.bLocking, NULL},
534 {"strict locking", P_BOOL, P_LOCAL, &sDefault.bStrictLocking, NULL},
535 {"share modes", P_BOOL, P_LOCAL, &sDefault.bShareModes, NULL},
536 {"only user", P_BOOL, P_LOCAL, &sDefault.bOnlyUser, NULL},
537 {"wide links", P_BOOL, P_LOCAL, &sDefault.bWidelinks, NULL},
538 {"follow symlinks", P_BOOL, P_LOCAL, &sDefault.bSymlinks, NULL},
539 {"sync always", P_BOOL, P_LOCAL, &sDefault.bSyncAlways, NULL},
540 {"mangled names", P_BOOL, P_LOCAL, &sDefault.bMangledNames, NULL},
541 {"fake oplocks", P_BOOL, P_LOCAL, &sDefault.bFakeOplocks, NULL},
542 {"print command", P_STRING, P_LOCAL, &sDefault.szPrintcommand, NULL},
543 {"lpq command", P_STRING, P_LOCAL, &sDefault.szLpqcommand, NULL},
544 {"lprm command", P_STRING, P_LOCAL, &sDefault.szLprmcommand, NULL},
545 {"lppause command", P_STRING, P_LOCAL, &sDefault.szLppausecommand, NULL},
546 {"lpresume command", P_STRING, P_LOCAL, &sDefault.szLpresumecommand,NULL},
547 {"printer", P_STRING, P_LOCAL, &sDefault.szPrintername, NULL},
548 {"printer name", P_STRING, P_LOCAL, &sDefault.szPrintername, NULL},
549 {"printer driver", P_STRING, P_LOCAL, &sDefault.szPrinterDriver, NULL},
550 {"hosts allow", P_STRING, P_LOCAL, &sDefault.szHostsallow, NULL},
551 {"allow hosts", P_STRING, P_LOCAL, &sDefault.szHostsallow, NULL},
552 {"hosts deny", P_STRING, P_LOCAL, &sDefault.szHostsdeny, NULL},
553 {"deny hosts", P_STRING, P_LOCAL, &sDefault.szHostsdeny, NULL},
554 {"dont descend", P_STRING, P_LOCAL, &sDefault.szDontdescend, NULL},
555 {"magic script", P_STRING, P_LOCAL, &sDefault.szMagicScript, NULL},
556 {"magic output", P_STRING, P_LOCAL, &sDefault.szMagicOutput, NULL},
557 {"mangled map", P_STRING, P_LOCAL, &sDefault.szMangledMap, NULL},
558 {"delete readonly", P_BOOL, P_LOCAL, &sDefault.bDeleteReadonly, NULL},
560 {NULL, P_BOOL, P_NONE, NULL, NULL}
565 /***************************************************************************
566 Initialise the global parameter structure.
567 ***************************************************************************/
568 static void init_globals(void)
570 static BOOL done_init = False;
576 bzero((void *)&Globals,sizeof(Globals));
578 for (i = 0; parm_table[i].label; i++)
579 if ((parm_table[i].type == P_STRING ||
580 parm_table[i].type == P_USTRING) &&
582 string_init(parm_table[i].ptr,"");
584 string_set(&sDefault.szGuestaccount, GUEST_ACCOUNT);
585 string_set(&sDefault.szPrinterDriver, "NULL");
591 DEBUG(3,("Initialising global parameters\n"));
593 #ifdef SMB_PASSWD_FILE
594 string_set(&Globals.szSMBPasswdFile, SMB_PASSWD_FILE);
596 string_set(&Globals.szPasswdChat,"*old*password* %o\\n *new*password* %n\\n *new*password* %n\\n *changed*");
597 string_set(&Globals.szWorkGroup, WORKGROUP);
599 string_set(&Globals.szPasswdProgram, SMB_PASSWD);
601 string_set(&Globals.szPasswdProgram, "/bin/passwd");
603 string_set(&Globals.szPrintcapname, PRINTCAP_NAME);
604 string_set(&Globals.szLockDir, LOCKDIR);
605 string_set(&Globals.szRootdir, "/");
606 string_set(&Globals.szSmbrun, SMBRUN);
607 string_set(&Globals.szSocketAddress, "0.0.0.0");
608 sprintf(s,"Samba %s",VERSION);
609 string_set(&Globals.szServerString,s);
610 sprintf(s,"%d.%d", DEFAULT_MAJOR_VERSION, DEFAULT_MINOR_VERSION);
611 string_set(&Globals.szAnnounceVersion,s);
612 Globals.bLoadPrinters = True;
613 Globals.bUseRhosts = False;
614 Globals.max_packet = 65535;
615 Globals.mangled_stack = 50;
616 Globals.max_xmit = 65535;
617 Globals.max_mux = 50; /* This is *needed* for profile support. */
618 Globals.lpqcachetime = 10;
619 Globals.pwordlevel = 0;
620 Globals.deadtime = 0;
621 Globals.max_log_size = 5000;
622 Globals.maxprotocol = PROTOCOL_NT1;
623 Globals.security = SEC_SHARE;
624 Globals.bEncryptPasswords = False;
625 Globals.printing = DEFAULT_PRINTING;
626 Globals.bReadRaw = True;
627 Globals.bWriteRaw = True;
628 Globals.bReadPrediction = False;
629 Globals.bReadbmpx = True;
630 Globals.bNullPasswords = False;
631 Globals.bStripDot = False;
633 Globals.bSyslogOnly = False;
634 Globals.os_level = 0;
635 Globals.max_ttl = 60*60*4; /* 2 hours default */
636 Globals.ReadSize = 16*1024;
637 Globals.shmem_size = SHMEM_SIZE;
638 Globals.shmem_hash_size = SHMEM_HASH_SIZE;
639 Globals.announce_as = ANNOUNCE_AS_NT;
640 Globals.bUnixRealname = False;
641 #if (defined(NETGROUP) && defined(AUTOMOUNT))
642 Globals.bNISHomeMap = False;
643 string_set(&Globals.szNISHomeMapName, "auto.home");
646 coding_system = interpret_coding_system (KANJI, SJIS_CODE);
648 Globals.client_code_page = DEFAULT_CLIENT_CODE_PAGE;
649 Globals.bTimeServer = False;
651 /* these parameters are set to defaults that are more appropriate
652 for the increasing samba install base:
654 as a member of the workgroup, that will possibly become a
655 _local_ master browser (lm = True). this is opposed to a forced
656 local master browser startup (pm = True).
658 doesn't provide WINS server service by default (wsupp = False),
659 and doesn't provide domain master browser services by default, either.
663 Globals.bPreferredMaster = False;
664 Globals.bLocalMaster = True;
665 Globals.bDomainMaster = False;
666 Globals.bDomainLogons = False;
667 Globals.bBrowseList = True;
668 Globals.bWINSsupport = False;
669 Globals.bWINSproxy = False;
671 /* this parameter is currently set to the default functionality
672 in samba. given that w95 and NT is starting to use DNS for
673 server resolution, i expect that at some point it would be
674 sensible to default this to False.
676 this parameter is added because nmbd is a single process, and
677 gethostbyname is a blocking call, which can take out nmbd for
678 several seconds while a dns lookup is performed.
682 Globals.bDNSproxy = True;
685 /***************************************************************************
686 check if a string is initialised and if not then initialise it
687 ***************************************************************************/
688 static void string_initial(char **s,char *v)
695 /***************************************************************************
696 Initialise the sDefault parameter structure.
697 ***************************************************************************/
698 static void init_locals(void)
700 /* choose defaults depending on the type of printing */
701 switch (Globals.printing)
707 string_initial(&sDefault.szLpqcommand,"lpq -P%p");
708 string_initial(&sDefault.szLprmcommand,"lprm -P%p %j");
709 string_initial(&sDefault.szPrintcommand,"lpr -r -P%p %s");
714 string_initial(&sDefault.szLpqcommand,"lpstat -o%p");
715 string_initial(&sDefault.szLprmcommand,"cancel %p-%j");
716 string_initial(&sDefault.szPrintcommand,"lp -c -d%p %s; rm %s");
718 string_initial(&sDefault.szLppausecommand,"lp -i %p-%j -H hold");
719 string_initial(&sDefault.szLpresumecommand,"lp -i %p-%j -H resume");
724 string_initial(&sDefault.szLpqcommand,"lpq -P%p");
725 string_initial(&sDefault.szLprmcommand,"lprm -P%p %j");
726 string_initial(&sDefault.szPrintcommand,"lp -r -P%p %s");
734 /******************************************************************* a
735 convenience routine to grab string parameters into a rotating buffer,
736 and run standard_sub_basic on them. The buffers can be written to by
737 callers without affecting the source string.
738 ********************************************************************/
739 char *lp_string(char *s)
741 static char *bufs[10];
742 static int buflen[10];
743 static int next = -1;
746 int len = s?strlen(s):0;
757 len = MAX(len+100,sizeof(pstring)); /* the +100 is for some
760 if (buflen[next] != len) {
762 if (bufs[next]) free(bufs[next]);
763 bufs[next] = (char *)malloc(len);
765 DEBUG(0,("out of memory in lp_string()"));
770 ret = &bufs[next][0];
778 standard_sub_basic(ret);
784 In this section all the functions that are used to access the
785 parameters from the rest of the program are defined
788 #define FN_GLOBAL_STRING(fn_name,ptr) \
789 char *fn_name(void) {return(lp_string(*(char **)(ptr) ? *(char **)(ptr) : ""));}
790 #define FN_GLOBAL_BOOL(fn_name,ptr) \
791 BOOL fn_name(void) {return(*(BOOL *)(ptr));}
792 #define FN_GLOBAL_CHAR(fn_name,ptr) \
793 char fn_name(void) {return(*(char *)(ptr));}
794 #define FN_GLOBAL_INTEGER(fn_name,ptr) \
795 int fn_name(void) {return(*(int *)(ptr));}
797 #define FN_LOCAL_STRING(fn_name,val) \
798 char *fn_name(int i) {return(lp_string((LP_SNUM_OK(i)&&pSERVICE(i)->val)?pSERVICE(i)->val : sDefault.val));}
799 #define FN_LOCAL_BOOL(fn_name,val) \
800 BOOL fn_name(int i) {return(LP_SNUM_OK(i)? pSERVICE(i)->val : sDefault.val);}
801 #define FN_LOCAL_CHAR(fn_name,val) \
802 char fn_name(int i) {return(LP_SNUM_OK(i)? pSERVICE(i)->val : sDefault.val);}
803 #define FN_LOCAL_INTEGER(fn_name,val) \
804 int fn_name(int i) {return(LP_SNUM_OK(i)? pSERVICE(i)->val : sDefault.val);}
806 FN_GLOBAL_STRING(lp_logfile,&Globals.szLogFile)
807 FN_GLOBAL_STRING(lp_smbrun,&Globals.szSmbrun)
808 FN_GLOBAL_STRING(lp_configfile,&Globals.szConfigFile)
809 FN_GLOBAL_STRING(lp_smb_passwd_file,&Globals.szSMBPasswdFile)
810 FN_GLOBAL_STRING(lp_serverstring,&Globals.szServerString)
811 FN_GLOBAL_STRING(lp_printcapname,&Globals.szPrintcapname)
812 FN_GLOBAL_STRING(lp_lockdir,&Globals.szLockDir)
813 FN_GLOBAL_STRING(lp_rootdir,&Globals.szRootdir)
814 FN_GLOBAL_STRING(lp_defaultservice,&Globals.szDefaultService)
815 FN_GLOBAL_STRING(lp_msg_command,&Globals.szMsgCommand)
816 FN_GLOBAL_STRING(lp_dfree_command,&Globals.szDfree)
817 FN_GLOBAL_STRING(lp_hosts_equiv,&Globals.szHostsEquiv)
818 FN_GLOBAL_STRING(lp_auto_services,&Globals.szAutoServices)
819 FN_GLOBAL_STRING(lp_passwd_program,&Globals.szPasswdProgram)
820 FN_GLOBAL_STRING(lp_passwd_chat,&Globals.szPasswdChat)
821 FN_GLOBAL_STRING(lp_passwordserver,&Globals.szPasswordServer)
822 FN_GLOBAL_STRING(lp_workgroup,&Globals.szWorkGroup)
823 FN_GLOBAL_STRING(lp_domain_controller,&Globals.szDomainController)
824 FN_GLOBAL_STRING(lp_username_map,&Globals.szUsernameMap)
825 FN_GLOBAL_STRING(lp_character_set,&Globals.szCharacterSet)
826 FN_GLOBAL_STRING(lp_logon_script,&Globals.szLogonScript)
827 FN_GLOBAL_STRING(lp_logon_path,&Globals.szLogonPath)
828 FN_GLOBAL_STRING(lp_remote_announce,&Globals.szRemoteAnnounce)
829 FN_GLOBAL_STRING(lp_wins_server,&Globals.szWINSserver)
830 FN_GLOBAL_STRING(lp_interfaces,&Globals.szInterfaces)
831 FN_GLOBAL_STRING(lp_socket_address,&Globals.szSocketAddress)
832 FN_GLOBAL_STRING(lp_nis_home_map_name,&Globals.szNISHomeMapName)
833 FN_GLOBAL_STRING(lp_announce_version,&Globals.szAnnounceVersion)
835 FN_GLOBAL_BOOL(lp_dns_proxy,&Globals.bDNSproxy)
836 FN_GLOBAL_BOOL(lp_wins_support,&Globals.bWINSsupport)
837 FN_GLOBAL_BOOL(lp_wins_proxy,&Globals.bWINSproxy)
838 FN_GLOBAL_BOOL(lp_local_master,&Globals.bLocalMaster)
839 FN_GLOBAL_BOOL(lp_domain_master,&Globals.bDomainMaster)
840 FN_GLOBAL_BOOL(lp_domain_logons,&Globals.bDomainLogons)
841 FN_GLOBAL_BOOL(lp_preferred_master,&Globals.bPreferredMaster)
842 FN_GLOBAL_BOOL(lp_load_printers,&Globals.bLoadPrinters)
843 FN_GLOBAL_BOOL(lp_use_rhosts,&Globals.bUseRhosts)
844 FN_GLOBAL_BOOL(lp_getwdcache,&use_getwd_cache)
845 FN_GLOBAL_BOOL(lp_readprediction,&Globals.bReadPrediction)
846 FN_GLOBAL_BOOL(lp_readbmpx,&Globals.bReadbmpx)
847 FN_GLOBAL_BOOL(lp_readraw,&Globals.bReadRaw)
848 FN_GLOBAL_BOOL(lp_writeraw,&Globals.bWriteRaw)
849 FN_GLOBAL_BOOL(lp_null_passwords,&Globals.bNullPasswords)
850 FN_GLOBAL_BOOL(lp_strip_dot,&Globals.bStripDot)
851 FN_GLOBAL_BOOL(lp_encrypted_passwords,&Globals.bEncryptPasswords)
852 FN_GLOBAL_BOOL(lp_syslog_only,&Globals.bSyslogOnly)
853 FN_GLOBAL_BOOL(lp_browse_list,&Globals.bBrowseList)
854 FN_GLOBAL_BOOL(lp_unix_realname,&Globals.bUnixRealname)
855 FN_GLOBAL_BOOL(lp_nis_home_map,&Globals.bNISHomeMap)
856 FN_GLOBAL_BOOL(lp_time_server,&Globals.bTimeServer)
858 FN_GLOBAL_INTEGER(lp_os_level,&Globals.os_level)
859 FN_GLOBAL_INTEGER(lp_max_ttl,&Globals.max_ttl)
860 FN_GLOBAL_INTEGER(lp_max_log_size,&Globals.max_log_size)
861 FN_GLOBAL_INTEGER(lp_mangledstack,&Globals.mangled_stack)
862 FN_GLOBAL_INTEGER(lp_maxxmit,&Globals.max_xmit)
863 FN_GLOBAL_INTEGER(lp_maxmux,&Globals.max_mux)
864 FN_GLOBAL_INTEGER(lp_maxpacket,&Globals.max_packet)
865 FN_GLOBAL_INTEGER(lp_keepalive,&keepalive)
866 FN_GLOBAL_INTEGER(lp_passwordlevel,&Globals.pwordlevel)
867 FN_GLOBAL_INTEGER(lp_readsize,&Globals.ReadSize)
868 FN_GLOBAL_INTEGER(lp_shmem_size,&Globals.shmem_size)
869 FN_GLOBAL_INTEGER(lp_shmem_hash_size,&Globals.shmem_hash_size)
870 FN_GLOBAL_INTEGER(lp_deadtime,&Globals.deadtime)
871 FN_GLOBAL_INTEGER(lp_maxprotocol,&Globals.maxprotocol)
872 FN_GLOBAL_INTEGER(lp_security,&Globals.security)
873 FN_GLOBAL_INTEGER(lp_printing,&Globals.printing)
874 FN_GLOBAL_INTEGER(lp_maxdisksize,&Globals.maxdisksize)
875 FN_GLOBAL_INTEGER(lp_lpqcachetime,&Globals.lpqcachetime)
876 FN_GLOBAL_INTEGER(lp_syslog,&Globals.syslog)
877 FN_GLOBAL_INTEGER(lp_client_code_page,&Globals.client_code_page)
878 FN_GLOBAL_INTEGER(lp_announce_as,&Globals.announce_as)
880 FN_LOCAL_STRING(lp_preexec,szPreExec)
881 FN_LOCAL_STRING(lp_postexec,szPostExec)
882 FN_LOCAL_STRING(lp_rootpreexec,szRootPreExec)
883 FN_LOCAL_STRING(lp_rootpostexec,szRootPostExec)
884 FN_LOCAL_STRING(lp_servicename,szService)
885 FN_LOCAL_STRING(lp_pathname,szPath)
886 FN_LOCAL_STRING(lp_dontdescend,szDontdescend)
887 FN_LOCAL_STRING(lp_username,szUsername)
888 FN_LOCAL_STRING(lp_guestaccount,szGuestaccount)
889 FN_LOCAL_STRING(lp_invalid_users,szInvalidUsers)
890 FN_LOCAL_STRING(lp_valid_users,szValidUsers)
891 FN_LOCAL_STRING(lp_admin_users,szAdminUsers)
892 FN_LOCAL_STRING(lp_printcommand,szPrintcommand)
893 FN_LOCAL_STRING(lp_lpqcommand,szLpqcommand)
894 FN_LOCAL_STRING(lp_lprmcommand,szLprmcommand)
895 FN_LOCAL_STRING(lp_lppausecommand,szLppausecommand)
896 FN_LOCAL_STRING(lp_lpresumecommand,szLpresumecommand)
897 FN_LOCAL_STRING(lp_printername,szPrintername)
898 FN_LOCAL_STRING(lp_printerdriver,szPrinterDriver)
899 FN_LOCAL_STRING(lp_hostsallow,szHostsallow)
900 FN_LOCAL_STRING(lp_hostsdeny,szHostsdeny)
901 FN_LOCAL_STRING(lp_magicscript,szMagicScript)
902 FN_LOCAL_STRING(lp_magicoutput,szMagicOutput)
903 FN_LOCAL_STRING(lp_comment,comment)
904 FN_LOCAL_STRING(lp_force_user,force_user)
905 FN_LOCAL_STRING(lp_force_group,force_group)
906 FN_LOCAL_STRING(lp_readlist,readlist)
907 FN_LOCAL_STRING(lp_writelist,writelist)
908 FN_LOCAL_STRING(lp_volume,volume)
909 FN_LOCAL_STRING(lp_mangled_map,szMangledMap)
910 FN_LOCAL_STRING(lp_veto_files,szVetoFiles)
911 FN_LOCAL_STRING(lp_hide_files,szHideFiles)
913 FN_LOCAL_BOOL(lp_alternate_permissions,bAlternatePerm)
914 FN_LOCAL_BOOL(lp_revalidate,bRevalidate)
915 FN_LOCAL_BOOL(lp_casesensitive,bCaseSensitive)
916 FN_LOCAL_BOOL(lp_preservecase,bCasePreserve)
917 FN_LOCAL_BOOL(lp_shortpreservecase,bShortCasePreserve)
918 FN_LOCAL_BOOL(lp_casemangle,bCaseMangle)
919 FN_LOCAL_BOOL(lp_status,status)
920 FN_LOCAL_BOOL(lp_hide_dot_files,bHideDotFiles)
921 FN_LOCAL_BOOL(lp_browseable,bBrowseable)
922 FN_LOCAL_BOOL(lp_readonly,bRead_only)
923 FN_LOCAL_BOOL(lp_no_set_dir,bNo_set_dir)
924 FN_LOCAL_BOOL(lp_guest_ok,bGuest_ok)
925 FN_LOCAL_BOOL(lp_guest_only,bGuest_only)
926 FN_LOCAL_BOOL(lp_print_ok,bPrint_ok)
927 FN_LOCAL_BOOL(lp_postscript,bPostscript)
928 FN_LOCAL_BOOL(lp_map_hidden,bMap_hidden)
929 FN_LOCAL_BOOL(lp_map_archive,bMap_archive)
930 FN_LOCAL_BOOL(lp_locking,bLocking)
931 FN_LOCAL_BOOL(lp_strict_locking,bStrictLocking)
932 FN_LOCAL_BOOL(lp_share_modes,bShareModes)
933 FN_LOCAL_BOOL(lp_onlyuser,bOnlyUser)
934 FN_LOCAL_BOOL(lp_manglednames,bMangledNames)
935 FN_LOCAL_BOOL(lp_widelinks,bWidelinks)
936 FN_LOCAL_BOOL(lp_symlinks,bSymlinks)
937 FN_LOCAL_BOOL(lp_syncalways,bSyncAlways)
938 FN_LOCAL_BOOL(lp_map_system,bMap_system)
939 FN_LOCAL_BOOL(lp_delete_readonly,bDeleteReadonly)
940 FN_LOCAL_BOOL(lp_fake_oplocks,bFakeOplocks)
942 FN_LOCAL_INTEGER(lp_create_mode,iCreate_mask)
943 FN_LOCAL_INTEGER(lp_force_create_mode,iCreate_force_mode)
944 FN_LOCAL_INTEGER(lp_dir_mode,iDir_mask)
945 FN_LOCAL_INTEGER(lp_force_dir_mode,iDir_force_mode)
946 FN_LOCAL_INTEGER(lp_max_connections,iMaxConnections)
947 FN_LOCAL_INTEGER(lp_defaultcase,iDefaultCase)
948 FN_LOCAL_INTEGER(lp_minprintspace,iMinPrintSpace)
950 FN_LOCAL_CHAR(lp_magicchar,magic_char)
954 /* local prototypes */
955 static int strwicmp( char *psz1, char *psz2 );
956 static int map_parameter( char *pszParmName);
957 static BOOL set_boolean( BOOL *pb, char *pszParmValue );
958 static int getservicebyname(char *pszServiceName, service *pserviceDest);
959 static void copy_service( service *pserviceDest,
960 service *pserviceSource,
961 BOOL *pcopymapDest );
962 static BOOL service_ok(int iService);
963 static BOOL do_parameter(char *pszParmName, char *pszParmValue);
964 static BOOL do_section(char *pszSectionName);
965 static void dump_globals(void);
966 static void dump_a_service(service *pService);
967 static void init_copymap(service *pservice);
970 /***************************************************************************
971 initialise a service to the defaults
972 ***************************************************************************/
973 static void init_service(service *pservice)
975 bzero((char *)pservice,sizeof(service));
976 copy_service(pservice,&sDefault,NULL);
980 /***************************************************************************
981 free the dynamically allocated parts of a service struct
982 ***************************************************************************/
983 static void free_service(service *pservice)
989 for (i=0;parm_table[i].label;i++)
990 if ((parm_table[i].type == P_STRING ||
991 parm_table[i].type == P_STRING) &&
992 parm_table[i].class == P_LOCAL)
993 string_free((char **)(((char *)pservice) + PTR_DIFF(parm_table[i].ptr,&sDefault)));
996 /***************************************************************************
997 add a new service to the services array initialising it with the given
999 ***************************************************************************/
1000 static int add_a_service(service *pservice, char *name)
1004 int num_to_alloc = iNumServices+1;
1006 tservice = *pservice;
1008 /* it might already exist */
1011 i = getservicebyname(name,NULL);
1016 /* find an invalid one */
1017 for (i=0;i<iNumServices;i++)
1018 if (!pSERVICE(i)->valid)
1021 /* if not, then create one */
1022 if (i == iNumServices)
1024 ServicePtrs = (service **)Realloc(ServicePtrs,sizeof(service *)*num_to_alloc);
1026 pSERVICE(iNumServices) = (service *)malloc(sizeof(service));
1028 if (!ServicePtrs || !pSERVICE(iNumServices))
1034 free_service(pSERVICE(i));
1036 pSERVICE(i)->valid = True;
1038 init_service(pSERVICE(i));
1039 copy_service(pSERVICE(i),&tservice,NULL);
1041 string_set(&iSERVICE(i).szService,name);
1046 /***************************************************************************
1047 add a new home service, with the specified home directory, defaults coming
1049 ***************************************************************************/
1050 BOOL lp_add_home(char *pszHomename, int iDefaultService, char *pszHomedir)
1052 int i = add_a_service(pSERVICE(iDefaultService),pszHomename);
1057 if (!(*(iSERVICE(i).szPath)) || strequal(iSERVICE(i).szPath,lp_pathname(-1)))
1058 string_set(&iSERVICE(i).szPath,pszHomedir);
1059 if (!(*(iSERVICE(i).comment)))
1062 sprintf(comment,"Home directory of %s",pszHomename);
1063 string_set(&iSERVICE(i).comment,comment);
1065 iSERVICE(i).bAvailable = sDefault.bAvailable;
1066 iSERVICE(i).bBrowseable = sDefault.bBrowseable;
1068 DEBUG(3,("adding home directory %s at %s\n", pszHomename, pszHomedir));
1073 /***************************************************************************
1074 add a new service, based on an old one
1075 ***************************************************************************/
1076 int lp_add_service(char *pszService, int iDefaultService)
1078 return(add_a_service(pSERVICE(iDefaultService),pszService));
1082 /***************************************************************************
1084 ***************************************************************************/
1085 static BOOL lp_add_ipc(void)
1088 int i = add_a_service(&sDefault,"IPC$");
1093 sprintf(comment,"IPC Service (%s)",lp_serverstring());
1095 string_set(&iSERVICE(i).szPath,tmpdir());
1096 string_set(&iSERVICE(i).szUsername,"");
1097 string_set(&iSERVICE(i).comment,comment);
1098 iSERVICE(i).status = False;
1099 iSERVICE(i).iMaxConnections = 0;
1100 iSERVICE(i).bAvailable = True;
1101 iSERVICE(i).bRead_only = True;
1102 iSERVICE(i).bGuest_only = False;
1103 iSERVICE(i).bGuest_ok = True;
1104 iSERVICE(i).bPrint_ok = False;
1105 iSERVICE(i).bBrowseable = sDefault.bBrowseable;
1107 DEBUG(3,("adding IPC service\n"));
1113 /***************************************************************************
1114 add a new printer service, with defaults coming from service iFrom
1115 ***************************************************************************/
1116 BOOL lp_add_printer(char *pszPrintername, int iDefaultService)
1118 char *comment = "From Printcap";
1119 int i = add_a_service(pSERVICE(iDefaultService),pszPrintername);
1124 /* note that we do NOT default the availability flag to True - */
1125 /* we take it from the default service passed. This allows all */
1126 /* dynamic printers to be disabled by disabling the [printers] */
1127 /* entry (if/when the 'available' keyword is implemented!). */
1129 /* the printer name is set to the service name. */
1130 string_set(&iSERVICE(i).szPrintername,pszPrintername);
1131 string_set(&iSERVICE(i).comment,comment);
1132 iSERVICE(i).bBrowseable = sDefault.bBrowseable;
1133 /* Printers cannot be read_only. */
1134 iSERVICE(i).bRead_only = False;
1135 /* No share modes on printer services. */
1136 iSERVICE(i).bShareModes = False;
1137 /* Printer services must be printable. */
1138 iSERVICE(i).bPrint_ok = True;
1140 DEBUG(3,("adding printer service %s\n",pszPrintername));
1146 /***************************************************************************
1147 Do a case-insensitive, whitespace-ignoring string compare.
1148 ***************************************************************************/
1149 static int strwicmp(char *psz1, char *psz2)
1151 /* if BOTH strings are NULL, return TRUE, if ONE is NULL return */
1152 /* appropriate value. */
1162 /* sync the strings on first non-whitespace */
1165 while (isspace(*psz1))
1167 while (isspace(*psz2))
1169 if (toupper(*psz1) != toupper(*psz2) || *psz1 == '\0' || *psz2 == '\0')
1174 return (*psz1 - *psz2);
1177 /***************************************************************************
1178 Map a parameter's string representation to something we can use.
1179 Returns False if the parameter string is not recognised, else TRUE.
1180 ***************************************************************************/
1181 static int map_parameter(char *pszParmName)
1185 if (*pszParmName == '-')
1188 for (iIndex = 0; parm_table[iIndex].label; iIndex++)
1189 if (strwicmp(parm_table[iIndex].label, pszParmName) == 0)
1192 DEBUG(0,( "Unknown parameter encountered: \"%s\"\n", pszParmName));
1197 /***************************************************************************
1198 Set a boolean variable from the text value stored in the passed string.
1199 Returns True in success, False if the passed string does not correctly
1200 represent a boolean.
1201 ***************************************************************************/
1202 static BOOL set_boolean(BOOL *pb, char *pszParmValue)
1207 if (strwicmp(pszParmValue, "yes") == 0 ||
1208 strwicmp(pszParmValue, "true") == 0 ||
1209 strwicmp(pszParmValue, "1") == 0)
1212 if (strwicmp(pszParmValue, "no") == 0 ||
1213 strwicmp(pszParmValue, "False") == 0 ||
1214 strwicmp(pszParmValue, "0") == 0)
1218 DEBUG(0,( "Badly formed boolean in configuration file: \"%s\".\n",
1225 /***************************************************************************
1226 Find a service by name. Otherwise works like get_service.
1227 ***************************************************************************/
1228 static int getservicebyname(char *pszServiceName, service *pserviceDest)
1232 for (iService = iNumServices - 1; iService >= 0; iService--)
1233 if (VALID(iService) &&
1234 strwicmp(iSERVICE(iService).szService, pszServiceName) == 0)
1236 if (pserviceDest != NULL)
1237 copy_service(pserviceDest, pSERVICE(iService), NULL);
1246 /***************************************************************************
1247 Copy a service structure to another
1249 If pcopymapDest is NULL then copy all fields
1250 ***************************************************************************/
1251 static void copy_service(service *pserviceDest,
1252 service *pserviceSource,
1256 BOOL bcopyall = (pcopymapDest == NULL);
1258 for (i=0;parm_table[i].label;i++)
1259 if (parm_table[i].ptr && parm_table[i].class == P_LOCAL &&
1260 (bcopyall || pcopymapDest[i]))
1262 void *def_ptr = parm_table[i].ptr;
1264 ((char *)pserviceSource) + PTR_DIFF(def_ptr,&sDefault);
1266 ((char *)pserviceDest) + PTR_DIFF(def_ptr,&sDefault);
1268 switch (parm_table[i].type)
1272 *(BOOL *)dest_ptr = *(BOOL *)src_ptr;
1277 *(int *)dest_ptr = *(int *)src_ptr;
1281 *(char *)dest_ptr = *(char *)src_ptr;
1285 string_set(dest_ptr,*(char **)src_ptr);
1289 string_set(dest_ptr,*(char **)src_ptr);
1290 strupper(*(char **)dest_ptr);
1299 init_copymap(pserviceDest);
1300 if (pserviceSource->copymap)
1301 memcpy((void *)pserviceDest->copymap,
1302 (void *)pserviceSource->copymap,sizeof(BOOL)*NUMPARAMETERS);
1306 /***************************************************************************
1307 Check a service for consistency. Return False if the service is in any way
1308 incomplete or faulty, else True.
1309 ***************************************************************************/
1310 static BOOL service_ok(int iService)
1315 if (iSERVICE(iService).szService[0] == '\0')
1317 DEBUG(0,( "The following message indicates an internal error:\n"));
1318 DEBUG(0,( "No service name in service entry.\n"));
1322 /* The [printers] entry MUST be printable. I'm all for flexibility, but */
1323 /* I can't see why you'd want a non-printable printer service... */
1324 if (strwicmp(iSERVICE(iService).szService,PRINTERS_NAME) == 0)
1325 if (!iSERVICE(iService).bPrint_ok)
1327 DEBUG(0,( "WARNING: [%s] service MUST be printable!\n",
1328 iSERVICE(iService).szService));
1329 iSERVICE(iService).bPrint_ok = True;
1332 if (iSERVICE(iService).szPath[0] == '\0' &&
1333 strwicmp(iSERVICE(iService).szService,HOMES_NAME) != 0)
1335 DEBUG(0,("No path in service %s - using %s\n",iSERVICE(iService).szService,tmpdir()));
1336 string_set(&iSERVICE(iService).szPath,tmpdir());
1339 /* If a service is flagged unavailable, log the fact at level 0. */
1340 if (!iSERVICE(iService).bAvailable)
1341 DEBUG(1,( "NOTE: Service %s is flagged unavailable.\n",
1342 iSERVICE(iService).szService));
1347 static struct file_lists {
1348 struct file_lists *next;
1351 } *file_lists = NULL;
1353 /*******************************************************************
1354 keep a linked list of all config files so we know when one has changed
1355 it's date and needs to be reloaded
1356 ********************************************************************/
1357 static void add_to_file_list(char *fname)
1359 struct file_lists *f=file_lists;
1362 if (f->name && !strcmp(f->name,fname)) break;
1367 f = (struct file_lists *)malloc(sizeof(file_lists[0]));
1369 f->next = file_lists;
1370 f->name = strdup(fname);
1381 standard_sub_basic(n2);
1382 f->modtime = file_modtime(n2);
1387 /*******************************************************************
1388 check if a config file has changed date
1389 ********************************************************************/
1390 BOOL lp_file_list_changed(void)
1392 struct file_lists *f = file_lists;
1396 standard_sub_basic(n2);
1397 if (f->modtime != file_modtime(n2)) return(True);
1404 /***************************************************************************
1405 handle the interpretation of the coding system parameter
1406 *************************************************************************/
1407 static BOOL handle_coding_system(char *pszParmValue,int *val)
1409 *val = interpret_coding_system(pszParmValue,*val);
1414 /***************************************************************************
1415 handle the interpretation of the character set system parameter
1416 ***************************************************************************/
1417 static BOOL handle_character_set(char *pszParmValue,int *val)
1419 string_set(&Globals.szCharacterSet,pszParmValue);
1420 *val = interpret_character_set(pszParmValue,*val);
1425 /***************************************************************************
1426 handle the interpretation of the protocol parameter
1427 ***************************************************************************/
1428 static BOOL handle_protocol(char *pszParmValue,int *val)
1430 *val = interpret_protocol(pszParmValue,*val);
1434 /***************************************************************************
1435 handle the interpretation of the security parameter
1436 ***************************************************************************/
1437 static BOOL handle_security(char *pszParmValue,int *val)
1439 *val = interpret_security(pszParmValue,*val);
1443 /***************************************************************************
1444 handle the interpretation of the default case
1445 ***************************************************************************/
1446 static BOOL handle_case(char *pszParmValue,int *val)
1448 if (strnequal(pszParmValue,"LOWER", 5))
1450 else if (strnequal(pszParmValue,"UPPER", 5))
1455 /***************************************************************************
1456 handle the interpretation of the printing system
1457 ***************************************************************************/
1458 static BOOL handle_printing(char *pszParmValue,int *val)
1460 if (strnequal(pszParmValue,"sysv", 4))
1462 else if (strnequal(pszParmValue,"aix", 3))
1464 else if (strnequal(pszParmValue,"hpux", 4))
1466 else if (strnequal(pszParmValue,"bsd", 3))
1468 else if (strnequal(pszParmValue,"qnx",3))
1470 else if (strnequal(pszParmValue,"plp", 3))
1472 else if (strnequal(pszParmValue,"lprng", 5))
1477 /***************************************************************************
1478 handle the announce as parameter
1479 ***************************************************************************/
1480 static BOOL handle_announce_as(char *pszParmValue,int *val)
1482 if (strnequal(pszParmValue,"NT", 2))
1483 *val = ANNOUNCE_AS_NT;
1484 else if (strnequal(pszParmValue,"win95", 5))
1485 *val = ANNOUNCE_AS_WIN95;
1486 else if (strnequal(pszParmValue,"WfW", 3))
1487 *val = ANNOUNCE_AS_WFW;
1491 /***************************************************************************
1492 handle the valid chars lines
1493 ***************************************************************************/
1494 static BOOL handle_valid_chars(char *pszParmValue,char **ptr)
1496 string_set(ptr,pszParmValue);
1498 add_char_string(pszParmValue);
1503 /***************************************************************************
1504 handle the include operation
1505 ***************************************************************************/
1506 static BOOL handle_include(char *pszParmValue,char **ptr)
1509 strcpy(fname,pszParmValue);
1511 add_to_file_list(fname);
1513 standard_sub_basic(fname);
1515 string_set(ptr,fname);
1517 if (file_exist(fname,NULL))
1518 return(pm_process(fname, do_section, do_parameter));
1520 DEBUG(2,("Can't find include file %s\n",fname));
1526 /***************************************************************************
1527 handle the interpretation of the copy parameter
1528 ***************************************************************************/
1529 static BOOL handle_copy(char *pszParmValue,char **ptr)
1533 service serviceTemp;
1535 string_set(ptr,pszParmValue);
1537 init_service(&serviceTemp);
1541 DEBUG(3,("Copying service from service %s\n",pszParmValue));
1543 if ((iTemp = getservicebyname(pszParmValue, &serviceTemp)) >= 0)
1545 if (iTemp == iServiceIndex)
1547 DEBUG(0,("Can't copy service %s - unable to copy self!\n",
1552 copy_service(pSERVICE(iServiceIndex),
1554 iSERVICE(iServiceIndex).copymap);
1560 DEBUG(0,( "Unable to copy service - source not found: %s\n",
1565 free_service(&serviceTemp);
1570 /***************************************************************************
1571 initialise a copymap
1572 ***************************************************************************/
1573 static void init_copymap(service *pservice)
1576 if (pservice->copymap) free(pservice->copymap);
1577 pservice->copymap = (BOOL *)malloc(sizeof(BOOL)*NUMPARAMETERS);
1578 if (!pservice->copymap)
1579 DEBUG(0,("Couldn't allocate copymap!! (size %d)\n",NUMPARAMETERS));
1581 for (i=0;i<NUMPARAMETERS;i++)
1582 pservice->copymap[i] = True;
1586 /***************************************************************************
1587 Process a parameter.
1588 ***************************************************************************/
1589 static BOOL do_parameter(char *pszParmName, char *pszParmValue)
1592 void *parm_ptr=NULL; /* where we are going to store the result */
1595 if (!bInGlobalSection && bGlobalOnly) return(True);
1597 DEBUG(3,("doing parameter %s = %s\n",pszParmName,pszParmValue));
1599 parmnum = map_parameter(pszParmName);
1603 DEBUG(0,( "Ignoring unknown parameter \"%s\"\n", pszParmName));
1607 def_ptr = parm_table[parmnum].ptr;
1609 /* we might point at a service, the default service or a global */
1610 if (bInGlobalSection)
1614 if (parm_table[parmnum].class == P_GLOBAL)
1616 DEBUG(0,( "Global parameter %s found in service section!\n",pszParmName));
1619 parm_ptr = ((char *)pSERVICE(iServiceIndex)) + PTR_DIFF(def_ptr,&sDefault);
1622 if (!bInGlobalSection)
1625 if (!iSERVICE(iServiceIndex).copymap)
1626 init_copymap(pSERVICE(iServiceIndex));
1628 /* this handles the aliases - set the copymap for other entries with
1629 the same data pointer */
1630 for (i=0;parm_table[i].label;i++)
1631 if (parm_table[i].ptr == parm_table[parmnum].ptr)
1632 iSERVICE(iServiceIndex).copymap[i] = False;
1635 /* if it is a special case then go ahead */
1636 if (parm_table[parmnum].special)
1638 parm_table[parmnum].special(pszParmValue,parm_ptr);
1642 /* now switch on the type of variable it is */
1643 switch (parm_table[parmnum].type)
1646 set_boolean(parm_ptr,pszParmValue);
1650 set_boolean(parm_ptr,pszParmValue);
1651 *(BOOL *)parm_ptr = ! *(BOOL *)parm_ptr;
1655 *(int *)parm_ptr = atoi(pszParmValue);
1659 *(char *)parm_ptr = *pszParmValue;
1663 sscanf(pszParmValue,"%o",(int *)parm_ptr);
1667 string_set(parm_ptr,pszParmValue);
1671 string_set(parm_ptr,pszParmValue);
1672 strupper(*(char **)parm_ptr);
1676 strcpy((char *)parm_ptr,pszParmValue);
1680 strcpy((char *)parm_ptr,pszParmValue);
1681 strupper((char *)parm_ptr);
1688 /***************************************************************************
1689 print a parameter of the specified type
1690 ***************************************************************************/
1691 static void print_parameter(parm_type type,void *ptr)
1696 printf("%s",BOOLSTR(*(BOOL *)ptr));
1700 printf("%s",BOOLSTR(! *(BOOL *)ptr));
1704 printf("%d",*(int *)ptr);
1708 printf("%c",*(char *)ptr);
1712 printf("0%o",*(int *)ptr);
1718 printf("%s",(char *)ptr);
1724 printf("%s",*(char **)ptr);
1730 /***************************************************************************
1731 check if two parameters are equal
1732 ***************************************************************************/
1733 static BOOL equal_parameter(parm_type type,void *ptr1,void *ptr2)
1739 return(*((BOOL *)ptr1) == *((BOOL *)ptr2));
1743 return(*((int *)ptr1) == *((int *)ptr2));
1746 return(*((char *)ptr1) == *((char *)ptr2));
1751 char *p1 = (char *)ptr1, *p2 = (char *)ptr2;
1752 if (p1 && !*p1) p1 = NULL;
1753 if (p2 && !*p2) p2 = NULL;
1754 return(p1==p2 || strequal(p1,p2));
1759 char *p1 = *(char **)ptr1, *p2 = *(char **)ptr2;
1760 if (p1 && !*p1) p1 = NULL;
1761 if (p2 && !*p2) p2 = NULL;
1762 return(p1==p2 || strequal(p1,p2));
1768 /***************************************************************************
1769 Process a new section (service). At this stage all sections are services.
1770 Later we'll have special sections that permit server parameters to be set.
1771 Returns True on success, False on failure.
1772 ***************************************************************************/
1773 static BOOL do_section(char *pszSectionName)
1776 BOOL isglobal = ((strwicmp(pszSectionName, GLOBAL_NAME) == 0) ||
1777 (strwicmp(pszSectionName, GLOBAL_NAME2) == 0));
1780 /* if we were in a global section then do the local inits */
1781 if (bInGlobalSection && !isglobal)
1784 /* if we've just struck a global section, note the fact. */
1785 bInGlobalSection = isglobal;
1787 /* check for multiple global sections */
1788 if (bInGlobalSection)
1790 DEBUG(3,( "Processing section \"[%s]\"\n", pszSectionName));
1794 if (!bInGlobalSection && bGlobalOnly) return(True);
1796 /* if we have a current service, tidy it up before moving on */
1799 if (iServiceIndex >= 0)
1800 bRetval = service_ok(iServiceIndex);
1802 /* if all is still well, move to the next record in the services array */
1805 /* We put this here to avoid an odd message order if messages are */
1806 /* issued by the post-processing of a previous section. */
1807 DEBUG(2,( "Processing section \"[%s]\"\n", pszSectionName));
1809 if ((iServiceIndex=add_a_service(&sDefault,pszSectionName)) < 0)
1811 DEBUG(0,("Failed to add a new service\n"));
1819 /***************************************************************************
1820 Display the contents of the global structure.
1821 ***************************************************************************/
1822 static void dump_globals(void)
1825 printf("Global parameters:\n");
1827 for (i=0;parm_table[i].label;i++)
1828 if (parm_table[i].class == P_GLOBAL &&
1829 parm_table[i].ptr &&
1830 (i == 0 || (parm_table[i].ptr != parm_table[i-1].ptr)))
1832 printf("\t%s: ",parm_table[i].label);
1833 print_parameter(parm_table[i].type,parm_table[i].ptr);
1838 /***************************************************************************
1839 Display the contents of a single services record.
1840 ***************************************************************************/
1841 static void dump_a_service(service *pService)
1844 if (pService == &sDefault)
1845 printf("\nDefault service parameters:\n");
1847 printf("\nService parameters [%s]:\n",pService->szService);
1849 for (i=0;parm_table[i].label;i++)
1850 if (parm_table[i].class == P_LOCAL &&
1851 parm_table[i].ptr &&
1852 (*parm_table[i].label != '-') &&
1853 (i == 0 || (parm_table[i].ptr != parm_table[i-1].ptr)))
1855 int pdiff = PTR_DIFF(parm_table[i].ptr,&sDefault);
1857 if (pService == &sDefault || !equal_parameter(parm_table[i].type,
1858 ((char *)pService) + pdiff,
1859 ((char *)&sDefault) + pdiff))
1861 printf("\t%s: ",parm_table[i].label);
1862 print_parameter(parm_table[i].type,
1863 ((char *)pService) + pdiff);
1870 /***************************************************************************
1871 Display the contents of a single copy structure.
1872 ***************************************************************************/
1873 static void dump_copy_map(BOOL *pcopymap)
1876 if (!pcopymap) return;
1878 printf("\n\tNon-Copied parameters:\n");
1880 for (i=0;parm_table[i].label;i++)
1881 if (parm_table[i].class == P_LOCAL &&
1882 parm_table[i].ptr && !pcopymap[i] &&
1883 (i == 0 || (parm_table[i].ptr != parm_table[i-1].ptr)))
1885 printf("\t\t%s\n",parm_table[i].label);
1890 /***************************************************************************
1891 Return TRUE if the passed service number is within range.
1892 ***************************************************************************/
1893 BOOL lp_snum_ok(int iService)
1895 return (LP_SNUM_OK(iService) && iSERVICE(iService).bAvailable);
1899 /***************************************************************************
1900 auto-load some homes and printer services
1901 ***************************************************************************/
1902 static void lp_add_auto_services(char *str)
1906 int homes = lp_servicenumber(HOMES_NAME);
1907 int printers = lp_servicenumber(PRINTERS_NAME);
1915 for (p=strtok(s,LIST_SEP);p;p=strtok(NULL,LIST_SEP))
1917 char *home = get_home_dir(p);
1919 if (lp_servicenumber(p) >= 0) continue;
1921 if (home && homes >= 0)
1923 lp_add_home(p,homes,home);
1927 if (printers >= 0 && pcap_printername_ok(p,NULL))
1928 lp_add_printer(p,printers);
1933 /***************************************************************************
1934 auto-load one printer
1935 ***************************************************************************/
1936 static void lp_add_one_printer(char *name,char *comment)
1938 int printers = lp_servicenumber(PRINTERS_NAME);
1941 if (lp_servicenumber(name) < 0)
1943 lp_add_printer(name,printers);
1944 if ((i=lp_servicenumber(name)) >= 0)
1945 string_set(&iSERVICE(i).comment,comment);
1950 /***************************************************************************
1951 auto-load printer services
1952 ***************************************************************************/
1953 static void lp_add_all_printers(void)
1955 int printers = lp_servicenumber(PRINTERS_NAME);
1957 if (printers < 0) return;
1959 pcap_printer_fn(lp_add_one_printer);
1962 /***************************************************************************
1963 have we loaded a services file yet?
1964 ***************************************************************************/
1965 BOOL lp_loaded(void)
1970 /***************************************************************************
1971 unload unused services
1972 ***************************************************************************/
1973 void lp_killunused(BOOL (*snumused)(int ))
1976 for (i=0;i<iNumServices;i++)
1977 if (VALID(i) && !snumused(i))
1979 iSERVICE(i).valid = False;
1980 free_service(pSERVICE(i));
1984 /***************************************************************************
1985 Load the services array from the services file. Return True on success,
1987 ***************************************************************************/
1988 BOOL lp_load(char *pszFname,BOOL global_only)
1992 static void set_default_server_announce_type(void);
1994 add_to_file_list(pszFname);
1998 bInGlobalSection = True;
1999 bGlobalOnly = global_only;
2003 strcpy(n2,pszFname);
2004 standard_sub_basic(n2);
2006 /* We get sections first, so have to start 'behind' to make up */
2008 bRetval = pm_process(n2, do_section, do_parameter);
2010 /* finish up the last section */
2011 DEBUG(3,("pm_process() returned %s\n", BOOLSTR(bRetval)));
2013 if (iServiceIndex >= 0)
2014 bRetval = service_ok(iServiceIndex);
2016 lp_add_auto_services(lp_auto_services());
2017 if (lp_load_printers())
2018 lp_add_all_printers();
2022 set_default_server_announce_type();
2030 /***************************************************************************
2031 return the max number of services
2032 ***************************************************************************/
2033 int lp_numservices(void)
2035 return(iNumServices);
2038 /***************************************************************************
2039 Display the contents of the services array in human-readable form.
2040 ***************************************************************************/
2047 dump_a_service(&sDefault);
2049 for (iService = 0; iService < iNumServices; iService++)
2051 if (VALID(iService))
2053 if (iSERVICE(iService).szService[0] == '\0')
2055 dump_a_service(pSERVICE(iService));
2060 /***************************************************************************
2061 Return the number of the service with the given name, or -1 if it doesn't
2062 exist. Note that this is a DIFFERENT ANIMAL from the internal function
2063 getservicebyname()! This works ONLY if all services have been loaded, and
2064 does not copy the found service.
2065 ***************************************************************************/
2066 int lp_servicenumber(char *pszServiceName)
2070 for (iService = iNumServices - 1; iService >= 0; iService--)
2071 if (VALID(iService) &&
2072 strwicmp(iSERVICE(iService).szService, pszServiceName) == 0)
2076 DEBUG(7,("lp_servicenumber: couldn't find %s\n",pszServiceName));
2081 /*******************************************************************
2082 a useful volume label function
2083 ******************************************************************/
2084 char *volume_label(int snum)
2086 char *ret = lp_volume(snum);
2087 if (!*ret) return(lp_servicename(snum));
2093 * nmbd only loads the global section. There seems to be no way to
2094 * determine exactly is a service is printable by only looking at the
2095 * [global] section so for now always announce as a print server. This
2096 * will need looking at in the future. Jeremy (jallison@whistle.com).
2098 /*******************************************************************
2099 Return true if any printer services are defined.
2100 ******************************************************************/
2101 static BOOL lp_printer_services(void)
2105 for (iService = iNumServices - 1; iService >= 0; iService--)
2106 if (VALID(iService) && iSERVICE(iService).bPrint_ok)
2112 /*******************************************************************
2113 Set the server type we will announce as via nmbd.
2114 ********************************************************************/
2115 static void set_default_server_announce_type()
2117 default_server_announce = (SV_TYPE_WORKSTATION | SV_TYPE_SERVER |
2118 SV_TYPE_SERVER_UNIX | SV_TYPE_PRINTQ_SERVER);
2119 if(lp_announce_as() == ANNOUNCE_AS_NT)
2120 default_server_announce |= (SV_TYPE_SERVER_NT | SV_TYPE_NT);
2121 else if(lp_announce_as() == ANNOUNCE_AS_WIN95)
2122 default_server_announce |= SV_TYPE_WIN95_PLUS;
2123 else if(lp_announce_as() == ANNOUNCE_AS_WFW)
2124 default_server_announce |= SV_TYPE_WFW;
2125 default_server_announce |= (lp_time_server() ? SV_TYPE_TIME_SOURCE : 0);
2127 * nmbd only loads the [global] section. There seems to be no way to
2128 * determine exactly if any service is printable by only looking at the
2129 * [global] section so for now always announce as a print server. This
2130 * will need looking at in the future. Jeremy (jallison@whistle.com).
2133 default_server_announce |= (lp_printer_services() ? SV_TYPE_PRINTQ_SERVER : 0);
2137 /*******************************************************************
2138 Get the default server type we will announce as via nmbd.
2139 ********************************************************************/
2140 int lp_default_server_announce(void)
2142 return default_server_announce;
2145 /*******************************************************************
2146 Split the announce version into major and minor numbers.
2147 ********************************************************************/
2148 int lp_major_announce_version(void)
2150 static BOOL got_major = False;
2151 static int major_version = DEFAULT_MAJOR_VERSION;
2156 return major_version;
2159 if((vers = lp_announce_version()) == NULL)
2160 return major_version;
2162 if((p = strchr(vers, '.')) == 0)
2163 return major_version;
2166 major_version = atoi(vers);
2167 return major_version;
2170 int lp_minor_announce_version(void)
2172 static BOOL got_minor = False;
2173 static int minor_version = DEFAULT_MINOR_VERSION;
2178 return minor_version;
2181 if((vers = lp_announce_version()) == NULL)
2182 return minor_version;
2184 if((p = strchr(vers, '.')) == 0)
2185 return minor_version;
2188 minor_version = atoi(p);
2189 return minor_version;