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"
69 #define PRINTCAP_NAME "/etc/qconfig"
71 #define PRINTCAP_NAME "/etc/printcap"
76 #define PRINTERS_NAME "printers"
80 #define HOMES_NAME "homes"
83 /* some helpful bits */
84 #define pSERVICE(i) ServicePtrs[i]
85 #define iSERVICE(i) (*pSERVICE(i))
86 #define LP_SNUM_OK(iService) (((iService) >= 0) && ((iService) < iNumServices) && iSERVICE(iService).valid)
87 #define VALID(i) iSERVICE(i).valid
89 /* these are the types of parameter we have */
92 P_BOOL,P_BOOLREV,P_CHAR,P_INTEGER,P_OCTAL,
93 P_STRING,P_USTRING,P_GSTRING,P_UGSTRING
98 P_LOCAL,P_GLOBAL,P_NONE
102 extern BOOL use_getwd_cache;
104 extern int extra_time_offset;
105 extern int coding_system;
108 * This structure describes global (ie., server-wide) parameters.
112 char *szPrintcapname;
115 char *szDefaultService;
119 char *szServerString;
120 char *szAutoServices;
121 char *szPasswdProgram;
125 char *szSMBPasswdFile;
126 char *szPasswordServer;
127 char *szSocketOptions;
130 char *szDomainController;
131 char *szDomainAdminUsers;
132 char *szDomainGuestUsers;
134 char *szCharacterSet;
142 char *szRemoteAnnounce;
143 char *szSocketAddress;
144 char *szNISHomeMapName;
145 char *szAnnounceVersion; /* This is initialised in init_globals */
146 char *szNetbiosAliases;
148 char *szDomainOtherSIDs;
149 char *szDomainGroups;
170 int client_code_page;
171 int announce_as; /* This is initialised in init_globals */
176 BOOL bPreferredMaster;
179 BOOL bEncryptPasswords;
186 BOOL bReadPrediction;
193 BOOL bBindInterfacesOnly;
196 static global Globals;
201 * This structure describes a single service.
209 char *szGuestaccount;
210 char *szInvalidUsers;
218 char *szRootPostExec;
219 char *szPrintcommand;
222 char *szLppausecommand;
223 char *szLpresumecommand;
225 char *szPrinterDriver;
226 char *szPrinterDriverLocation;
243 int iCreate_force_mode;
252 BOOL bShortCasePreserve;
278 BOOL bDeleteReadonly;
280 BOOL bDeleteVetoFiles;
282 char dummy[3]; /* for alignment */
286 /* This is a default service used to prime a services structure */
287 static service sDefault =
290 NULL, /* szService */
292 NULL, /* szUsername */
293 NULL, /* szGuestAccount - this is set in init_globals() */
294 NULL, /* szInvalidUsers */
295 NULL, /* szValidUsers */
296 NULL, /* szAdminUsers */
298 NULL, /* szInclude */
299 NULL, /* szPreExec */
300 NULL, /* szPostExec */
301 NULL, /* szRootPreExec */
302 NULL, /* szRootPostExec */
303 NULL, /* szPrintcommand */
304 NULL, /* szLpqcommand */
305 NULL, /* szLprmcommand */
306 NULL, /* szLppausecommand */
307 NULL, /* szLpresumecommand */
308 NULL, /* szPrintername */
309 NULL, /* szPrinterDriver - this is set in init_globals() */
310 NULL, /* szPrinterDriverLocation */
311 NULL, /* szDontdescend */
312 NULL, /* szHostsallow */
313 NULL, /* szHostsdeny */
314 NULL, /* szMagicScript */
315 NULL, /* szMagicOutput */
316 NULL, /* szMangledMap */
317 NULL, /* szVetoFiles */
318 NULL, /* szHideFiles */
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 False, /* bAlternatePerm */
333 False, /* revalidate */
334 False, /* case sensitive */
335 False, /* case preserve */
336 False, /* short case preserve */
337 False, /* case mangle */
339 True, /* bHideDotFiles */
340 True, /* bBrowseable */
341 True, /* bAvailable */
342 True, /* bRead_only */
343 True, /* bNo_set_dir */
344 False, /* bGuest_only */
345 False, /* bGuest_ok */
346 False, /* bPrint_ok */
347 False, /* bPostscript */
348 False, /* bMap_system */
349 False, /* bMap_hidden */
350 True, /* bMap_archive */
352 False, /* bStrictLocking */
353 True, /* bShareModes */
355 False, /* bOnlyUser */
356 True, /* bMangledNames */
357 True, /* bWidelinks */
358 True, /* bSymlinks */
359 False, /* bSyncAlways */
360 '~', /* magic char */
362 False, /* bDeleteReadonly */
363 False, /* bFakeOplocks */
364 False, /* bDeleteVetoFiles */
365 False, /* bDosFiletimes */
371 /* local variables */
372 static service **ServicePtrs = NULL;
373 static int iNumServices = 0;
374 static int iServiceIndex = 0;
375 static BOOL bInGlobalSection = True;
376 static BOOL bGlobalOnly = False;
377 static int default_server_announce;
379 #define NUMPARAMETERS (sizeof(parm_table) / sizeof(struct parm_struct))
381 /* prototypes for the special type handlers */
382 static BOOL handle_valid_chars(char *pszParmValue, char **ptr);
383 static BOOL handle_include(char *pszParmValue, char **ptr);
384 static BOOL handle_copy(char *pszParmValue, char **ptr);
385 static BOOL handle_protocol(char *pszParmValue,int *val);
386 static BOOL handle_security(char *pszParmValue,int *val);
387 static BOOL handle_case(char *pszParmValue,int *val);
388 static BOOL handle_printing(char *pszParmValue,int *val);
389 static BOOL handle_character_set(char *pszParmValue,int *val);
390 static BOOL handle_announce_as(char *pszParmValue, int *val);
391 static BOOL handle_coding_system(char *pszParmValue,int *val);
393 static void set_default_server_announce_type(void);
404 {"debuglevel", P_INTEGER, P_GLOBAL, &DEBUGLEVEL, NULL},
405 {"log level", P_INTEGER, P_GLOBAL, &DEBUGLEVEL, NULL},
406 {"syslog", P_INTEGER, P_GLOBAL, &Globals.syslog, NULL},
407 {"syslog only", P_BOOL, P_GLOBAL, &Globals.bSyslogOnly, NULL},
408 {"protocol", P_INTEGER, P_GLOBAL, &Globals.maxprotocol,handle_protocol},
409 {"security", P_INTEGER, P_GLOBAL, &Globals.security,handle_security},
410 {"printing", P_INTEGER, P_GLOBAL, &Globals.printing,handle_printing},
411 {"max disk size", P_INTEGER, P_GLOBAL, &Globals.maxdisksize, NULL},
412 {"lpq cache time", P_INTEGER, P_GLOBAL, &Globals.lpqcachetime, NULL},
413 {"announce as", P_INTEGER, P_GLOBAL, &Globals.announce_as, handle_announce_as},
414 {"encrypt passwords",P_BOOL, P_GLOBAL, &Globals.bEncryptPasswords, NULL},
415 {"getwd cache", P_BOOL, P_GLOBAL, &use_getwd_cache, NULL},
416 {"read prediction", P_BOOL, P_GLOBAL, &Globals.bReadPrediction, NULL},
417 {"read bmpx", P_BOOL, P_GLOBAL, &Globals.bReadbmpx, NULL},
418 {"read raw", P_BOOL, P_GLOBAL, &Globals.bReadRaw, NULL},
419 {"write raw", P_BOOL, P_GLOBAL, &Globals.bWriteRaw, NULL},
420 {"use rhosts", P_BOOL, P_GLOBAL, &Globals.bUseRhosts, NULL},
421 {"load printers", P_BOOL, P_GLOBAL, &Globals.bLoadPrinters, NULL},
422 {"null passwords", P_BOOL, P_GLOBAL, &Globals.bNullPasswords, NULL},
423 {"strip dot", P_BOOL, P_GLOBAL, &Globals.bStripDot, NULL},
424 {"interfaces", P_STRING, P_GLOBAL, &Globals.szInterfaces, NULL},
425 {"bind interfaces only", P_BOOL,P_GLOBAL, &Globals.bBindInterfacesOnly,NULL},
426 {"password server", P_STRING, P_GLOBAL, &Globals.szPasswordServer, NULL},
427 {"socket options", P_GSTRING, P_GLOBAL, user_socket_options, NULL},
428 {"netbios name", P_UGSTRING,P_GLOBAL, myname, NULL},
429 {"netbios aliases", P_STRING, P_GLOBAL, &Globals.szNetbiosAliases, NULL},
430 {"smbrun", P_STRING, P_GLOBAL, &Globals.szSmbrun, NULL},
431 {"log file", P_STRING, P_GLOBAL, &Globals.szLogFile, NULL},
432 {"config file", P_STRING, P_GLOBAL, &Globals.szConfigFile, NULL},
433 {"smb passwd file", P_STRING, P_GLOBAL, &Globals.szSMBPasswdFile, NULL},
434 {"hosts equiv", P_STRING, P_GLOBAL, &Globals.szHostsEquiv, NULL},
435 {"preload", P_STRING, P_GLOBAL, &Globals.szAutoServices, NULL},
436 {"auto services", P_STRING, P_GLOBAL, &Globals.szAutoServices, NULL},
437 {"server string", P_STRING, P_GLOBAL, &Globals.szServerString, NULL},
438 {"printcap name", P_STRING, P_GLOBAL, &Globals.szPrintcapname, NULL},
439 {"printcap", P_STRING, P_GLOBAL, &Globals.szPrintcapname, NULL},
440 {"lock dir", P_STRING, P_GLOBAL, &Globals.szLockDir, NULL},
441 {"lock directory", P_STRING, P_GLOBAL, &Globals.szLockDir, NULL},
442 {"root directory", P_STRING, P_GLOBAL, &Globals.szRootdir, NULL},
443 {"root dir", P_STRING, P_GLOBAL, &Globals.szRootdir, NULL},
444 {"root", P_STRING, P_GLOBAL, &Globals.szRootdir, NULL},
445 {"default service", P_STRING, P_GLOBAL, &Globals.szDefaultService, NULL},
446 {"default", P_STRING, P_GLOBAL, &Globals.szDefaultService, NULL},
447 {"message command", P_STRING, P_GLOBAL, &Globals.szMsgCommand, NULL},
448 {"dfree command", P_STRING, P_GLOBAL, &Globals.szDfree, NULL},
449 {"passwd program", P_STRING, P_GLOBAL, &Globals.szPasswdProgram, NULL},
450 {"passwd chat", P_STRING, P_GLOBAL, &Globals.szPasswdChat, NULL},
451 {"valid chars", P_STRING, P_GLOBAL, &Globals.szValidChars, handle_valid_chars},
452 {"workgroup", P_USTRING, P_GLOBAL, &Globals.szWorkGroup, NULL},
453 {"domain sid", P_USTRING, P_GLOBAL, &Globals.szDomainSID, NULL},
454 {"domain other sids", P_USTRING, P_GLOBAL, &Globals.szDomainOtherSIDs, NULL},
455 {"domain groups", P_USTRING, P_GLOBAL, &Globals.szDomainGroups, NULL},
456 {"domain controller",P_STRING, P_GLOBAL, &Globals.szDomainController,NULL},
457 {"domain admin users",P_STRING, P_GLOBAL, &Globals.szDomainAdminUsers, NULL},
458 {"domain guest users",P_STRING, P_GLOBAL, &Globals.szDomainGuestUsers, NULL},
459 {"username map", P_STRING, P_GLOBAL, &Globals.szUsernameMap, NULL},
460 {"character set", P_STRING, P_GLOBAL, &Globals.szCharacterSet, handle_character_set},
461 {"logon script", P_STRING, P_GLOBAL, &Globals.szLogonScript, NULL},
462 {"logon path", P_STRING, P_GLOBAL, &Globals.szLogonPath, NULL},
463 {"logon drive", P_STRING, P_GLOBAL, &Globals.szLogonDrive, NULL},
464 {"logon home", P_STRING, P_GLOBAL, &Globals.szLogonHome, NULL},
465 {"remote announce", P_STRING, P_GLOBAL, &Globals.szRemoteAnnounce, NULL},
466 {"socket address", P_STRING, P_GLOBAL, &Globals.szSocketAddress, NULL},
467 {"homedir map", P_STRING, P_GLOBAL, &Globals.szNISHomeMapName, NULL},
468 {"announce version", P_STRING, P_GLOBAL, &Globals.szAnnounceVersion, NULL},
469 {"max log size", P_INTEGER, P_GLOBAL, &Globals.max_log_size, NULL},
470 {"mangled stack", P_INTEGER, P_GLOBAL, &Globals.mangled_stack, NULL},
471 {"max mux", P_INTEGER, P_GLOBAL, &Globals.max_mux, NULL},
472 {"max xmit", P_INTEGER, P_GLOBAL, &Globals.max_xmit, NULL},
473 {"max packet", P_INTEGER, P_GLOBAL, &Globals.max_packet, NULL},
474 {"packet size", P_INTEGER, P_GLOBAL, &Globals.max_packet, NULL},
475 {"password level", P_INTEGER, P_GLOBAL, &Globals.pwordlevel, NULL},
476 {"username level", P_INTEGER, P_GLOBAL, &Globals.unamelevel, NULL},
477 {"keepalive", P_INTEGER, P_GLOBAL, &keepalive, NULL},
478 {"deadtime", P_INTEGER, P_GLOBAL, &Globals.deadtime, NULL},
479 {"time offset", P_INTEGER, P_GLOBAL, &extra_time_offset, NULL},
480 {"read size", P_INTEGER, P_GLOBAL, &Globals.ReadSize, NULL},
481 {"shared mem size", P_INTEGER, P_GLOBAL, &Globals.shmem_size, NULL},
482 {"shared file entries", P_INTEGER, P_GLOBAL, &Globals.shmem_hash_size, NULL},
483 {"coding system", P_INTEGER, P_GLOBAL, &coding_system, handle_coding_system},
484 {"client code page", P_INTEGER, P_GLOBAL, &Globals.client_code_page, NULL},
485 {"os level", P_INTEGER, P_GLOBAL, &Globals.os_level, NULL},
486 {"max ttl", P_INTEGER, P_GLOBAL, &Globals.max_ttl, NULL},
487 {"dns proxy", P_BOOL, P_GLOBAL, &Globals.bDNSproxy, NULL},
488 {"wins support", P_BOOL, P_GLOBAL, &Globals.bWINSsupport, NULL},
489 {"wins proxy", P_BOOL, P_GLOBAL, &Globals.bWINSproxy, NULL},
490 {"wins server", P_STRING, P_GLOBAL, &Globals.szWINSserver, NULL},
491 {"preferred master", P_BOOL, P_GLOBAL, &Globals.bPreferredMaster, NULL},
492 {"prefered master", P_BOOL, P_GLOBAL, &Globals.bPreferredMaster, NULL},
493 {"local master", P_BOOL, P_GLOBAL, &Globals.bLocalMaster, NULL},
494 {"domain master", P_BOOL, P_GLOBAL, &Globals.bDomainMaster, NULL},
495 {"domain logons", P_BOOL, P_GLOBAL, &Globals.bDomainLogons, NULL},
496 {"browse list", P_BOOL, P_GLOBAL, &Globals.bBrowseList, NULL},
497 {"unix realname", P_BOOL, P_GLOBAL, &Globals.bUnixRealname, NULL},
498 {"NIS homedir", P_BOOL, P_GLOBAL, &Globals.bNISHomeMap, NULL},
499 {"time server", P_BOOL, P_GLOBAL, &Globals.bTimeServer, NULL},
500 {"printer driver file", P_STRING, P_GLOBAL, &Globals.szDriverFile, NULL},
501 {"-valid", P_BOOL, P_LOCAL, &sDefault.valid, NULL},
502 {"comment", P_STRING, P_LOCAL, &sDefault.comment, NULL},
503 {"copy", P_STRING, P_LOCAL, &sDefault.szCopy, handle_copy},
504 {"include", P_STRING, P_LOCAL, &sDefault.szInclude, handle_include},
505 {"exec", P_STRING, P_LOCAL, &sDefault.szPreExec, NULL},
506 {"preexec", P_STRING, P_LOCAL, &sDefault.szPreExec, NULL},
507 {"postexec", P_STRING, P_LOCAL, &sDefault.szPostExec, NULL},
508 {"root preexec", P_STRING, P_LOCAL, &sDefault.szRootPreExec, NULL},
509 {"root postexec", P_STRING, P_LOCAL, &sDefault.szRootPostExec, NULL},
510 {"alternate permissions",P_BOOL,P_LOCAL, &sDefault.bAlternatePerm, NULL},
511 {"revalidate", P_BOOL, P_LOCAL, &sDefault.bRevalidate, NULL},
512 {"default case", P_INTEGER, P_LOCAL, &sDefault.iDefaultCase, handle_case},
513 {"case sensitive", P_BOOL, P_LOCAL, &sDefault.bCaseSensitive, NULL},
514 {"casesignames", P_BOOL, P_LOCAL, &sDefault.bCaseSensitive, NULL},
515 {"preserve case", P_BOOL, P_LOCAL, &sDefault.bCasePreserve, NULL},
516 {"short preserve case",P_BOOL, P_LOCAL, &sDefault.bShortCasePreserve,NULL},
517 {"mangle case", P_BOOL, P_LOCAL, &sDefault.bCaseMangle, NULL},
518 {"mangling char", P_CHAR, P_LOCAL, &sDefault.magic_char, NULL},
519 {"browseable", P_BOOL, P_LOCAL, &sDefault.bBrowseable, NULL},
520 {"browsable", P_BOOL, P_LOCAL, &sDefault.bBrowseable, NULL},
521 {"available", P_BOOL, P_LOCAL, &sDefault.bAvailable, NULL},
522 {"path", P_STRING, P_LOCAL, &sDefault.szPath, NULL},
523 {"directory", P_STRING, P_LOCAL, &sDefault.szPath, NULL},
524 {"username", P_STRING, P_LOCAL, &sDefault.szUsername, NULL},
525 {"user", P_STRING, P_LOCAL, &sDefault.szUsername, NULL},
526 {"users", P_STRING, P_LOCAL, &sDefault.szUsername, NULL},
527 {"guest account", P_STRING, P_LOCAL, &sDefault.szGuestaccount, NULL},
528 {"invalid users", P_STRING, P_LOCAL, &sDefault.szInvalidUsers, NULL},
529 {"valid users", P_STRING, P_LOCAL, &sDefault.szValidUsers, NULL},
530 {"admin users", P_STRING, P_LOCAL, &sDefault.szAdminUsers, NULL},
531 {"read list", P_STRING, P_LOCAL, &sDefault.readlist, NULL},
532 {"write list", P_STRING, P_LOCAL, &sDefault.writelist, NULL},
533 {"volume", P_STRING, P_LOCAL, &sDefault.volume, NULL},
534 {"force user", P_STRING, P_LOCAL, &sDefault.force_user, NULL},
535 {"force group", P_STRING, P_LOCAL, &sDefault.force_group, NULL},
536 {"group", P_STRING, P_LOCAL, &sDefault.force_group, NULL},
537 {"read only", P_BOOL, P_LOCAL, &sDefault.bRead_only, NULL},
538 {"write ok", P_BOOLREV, P_LOCAL, &sDefault.bRead_only, NULL},
539 {"writeable", P_BOOLREV, P_LOCAL, &sDefault.bRead_only, NULL},
540 {"writable", P_BOOLREV, P_LOCAL, &sDefault.bRead_only, NULL},
541 {"max connections", P_INTEGER, P_LOCAL, &sDefault.iMaxConnections, NULL},
542 {"min print space", P_INTEGER, P_LOCAL, &sDefault.iMinPrintSpace, NULL},
543 {"create mask", P_OCTAL, P_LOCAL, &sDefault.iCreate_mask, NULL},
544 {"create mode", P_OCTAL, P_LOCAL, &sDefault.iCreate_mask, NULL},
545 {"force create mode",P_OCTAL, P_LOCAL, &sDefault.iCreate_force_mode, NULL},
546 {"directory mask", P_OCTAL, P_LOCAL, &sDefault.iDir_mask, NULL},
547 {"directory mode", P_OCTAL, P_LOCAL, &sDefault.iDir_mask, NULL},
548 {"force directory mode", P_OCTAL, P_LOCAL, &sDefault.iDir_force_mode, NULL},
549 {"set directory", P_BOOLREV, P_LOCAL, &sDefault.bNo_set_dir, NULL},
550 {"status", P_BOOL, P_LOCAL, &sDefault.status, NULL},
551 {"hide dot files", P_BOOL, P_LOCAL, &sDefault.bHideDotFiles, NULL},
552 {"delete veto files",P_BOOL, P_LOCAL, &sDefault.bDeleteVetoFiles, NULL},
553 {"veto files", P_STRING, P_LOCAL, &sDefault.szVetoFiles, NULL},
554 {"hide files", P_STRING, P_LOCAL, &sDefault.szHideFiles, NULL},
555 {"guest only", P_BOOL, P_LOCAL, &sDefault.bGuest_only, NULL},
556 {"only guest", P_BOOL, P_LOCAL, &sDefault.bGuest_only, NULL},
557 {"guest ok", P_BOOL, P_LOCAL, &sDefault.bGuest_ok, NULL},
558 {"public", P_BOOL, P_LOCAL, &sDefault.bGuest_ok, NULL},
559 {"print ok", P_BOOL, P_LOCAL, &sDefault.bPrint_ok, NULL},
560 {"printable", P_BOOL, P_LOCAL, &sDefault.bPrint_ok, NULL},
561 {"postscript", P_BOOL, P_LOCAL, &sDefault.bPostscript, NULL},
562 {"map system", P_BOOL, P_LOCAL, &sDefault.bMap_system, NULL},
563 {"map hidden", P_BOOL, P_LOCAL, &sDefault.bMap_hidden, NULL},
564 {"map archive", P_BOOL, P_LOCAL, &sDefault.bMap_archive, NULL},
565 {"locking", P_BOOL, P_LOCAL, &sDefault.bLocking, NULL},
566 {"strict locking", P_BOOL, P_LOCAL, &sDefault.bStrictLocking, NULL},
567 {"share modes", P_BOOL, P_LOCAL, &sDefault.bShareModes, NULL},
568 {"oplocks", P_BOOL, P_LOCAL, &sDefault.bOpLocks, NULL},
569 {"only user", P_BOOL, P_LOCAL, &sDefault.bOnlyUser, NULL},
570 {"wide links", P_BOOL, P_LOCAL, &sDefault.bWidelinks, NULL},
571 {"follow symlinks", P_BOOL, P_LOCAL, &sDefault.bSymlinks, NULL},
572 {"sync always", P_BOOL, P_LOCAL, &sDefault.bSyncAlways, NULL},
573 {"mangled names", P_BOOL, P_LOCAL, &sDefault.bMangledNames, NULL},
574 {"fake oplocks", P_BOOL, P_LOCAL, &sDefault.bFakeOplocks, NULL},
575 {"print command", P_STRING, P_LOCAL, &sDefault.szPrintcommand, NULL},
576 {"lpq command", P_STRING, P_LOCAL, &sDefault.szLpqcommand, NULL},
577 {"lprm command", P_STRING, P_LOCAL, &sDefault.szLprmcommand, NULL},
578 {"lppause command", P_STRING, P_LOCAL, &sDefault.szLppausecommand, NULL},
579 {"lpresume command", P_STRING, P_LOCAL, &sDefault.szLpresumecommand,NULL},
580 {"printer", P_STRING, P_LOCAL, &sDefault.szPrintername, NULL},
581 {"printer name", P_STRING, P_LOCAL, &sDefault.szPrintername, NULL},
582 {"printer driver", P_STRING, P_LOCAL, &sDefault.szPrinterDriver, NULL},
583 {"printer driver location", P_STRING, P_LOCAL, &sDefault.szPrinterDriverLocation, NULL},
584 {"hosts allow", P_STRING, P_LOCAL, &sDefault.szHostsallow, NULL},
585 {"allow hosts", P_STRING, P_LOCAL, &sDefault.szHostsallow, NULL},
586 {"hosts deny", P_STRING, P_LOCAL, &sDefault.szHostsdeny, NULL},
587 {"deny hosts", P_STRING, P_LOCAL, &sDefault.szHostsdeny, NULL},
588 {"dont descend", P_STRING, P_LOCAL, &sDefault.szDontdescend, NULL},
589 {"magic script", P_STRING, P_LOCAL, &sDefault.szMagicScript, NULL},
590 {"magic output", P_STRING, P_LOCAL, &sDefault.szMagicOutput, NULL},
591 {"mangled map", P_STRING, P_LOCAL, &sDefault.szMangledMap, NULL},
592 {"delete readonly", P_BOOL, P_LOCAL, &sDefault.bDeleteReadonly, NULL},
593 {"dos filetimes", P_BOOL, P_LOCAL, &sDefault.bDosFiletimes, NULL},
595 {NULL, P_BOOL, P_NONE, NULL, NULL}
600 /***************************************************************************
601 Initialise the global parameter structure.
602 ***************************************************************************/
603 static void init_globals(void)
605 static BOOL done_init = False;
611 bzero((void *)&Globals,sizeof(Globals));
613 for (i = 0; parm_table[i].label; i++)
614 if ((parm_table[i].type == P_STRING ||
615 parm_table[i].type == P_USTRING) &&
617 string_init(parm_table[i].ptr,"");
619 string_set(&sDefault.szGuestaccount, GUEST_ACCOUNT);
620 string_set(&sDefault.szPrinterDriver, "NULL");
626 DEBUG(3,("Initialising global parameters\n"));
628 #ifdef SMB_PASSWD_FILE
629 string_set(&Globals.szSMBPasswdFile, SMB_PASSWD_FILE);
631 string_set(&Globals.szPasswdChat,"*old*password* %o\\n *new*password* %n\\n *new*password* %n\\n *changed*");
632 string_set(&Globals.szWorkGroup, WORKGROUP);
633 string_set(&Globals.szPasswdProgram, SMB_PASSWD);
634 string_set(&Globals.szPrintcapname, PRINTCAP_NAME);
635 string_set(&Globals.szDriverFile, DRIVERFILE);
636 string_set(&Globals.szLockDir, LOCKDIR);
637 string_set(&Globals.szRootdir, "/");
638 string_set(&Globals.szSmbrun, SMBRUN);
639 string_set(&Globals.szSocketAddress, "0.0.0.0");
640 sprintf(s,"Samba %s",VERSION);
641 string_set(&Globals.szServerString,s);
642 sprintf(s,"%d.%d", DEFAULT_MAJOR_VERSION, DEFAULT_MINOR_VERSION);
643 string_set(&Globals.szAnnounceVersion,s);
645 string_set(&Globals.szLogonDrive, "");
646 /* %N is the NIS auto.home server if -DAUTOHOME is used, else same as %L */
647 string_set(&Globals.szLogonHome, "\\\\%N\\%U");
648 string_set(&Globals.szLogonPath, "\\\\%N\\%U\\profile");
650 Globals.bLoadPrinters = True;
651 Globals.bUseRhosts = False;
652 Globals.max_packet = 65535;
653 Globals.mangled_stack = 50;
654 Globals.max_xmit = 65535;
655 Globals.max_mux = 50; /* This is *needed* for profile support. */
656 Globals.lpqcachetime = 10;
657 Globals.pwordlevel = 0;
658 Globals.unamelevel = 0;
659 Globals.deadtime = 0;
660 Globals.max_log_size = 5000;
661 Globals.maxprotocol = PROTOCOL_NT1;
662 Globals.security = SEC_SHARE;
663 Globals.bEncryptPasswords = False;
664 Globals.printing = DEFAULT_PRINTING;
665 Globals.bReadRaw = True;
666 Globals.bWriteRaw = True;
667 Globals.bReadPrediction = False;
668 Globals.bReadbmpx = True;
669 Globals.bNullPasswords = False;
670 Globals.bStripDot = False;
672 Globals.bSyslogOnly = False;
673 Globals.os_level = 0;
674 Globals.max_ttl = 60*60*4; /* 2 hours default */
675 Globals.ReadSize = 16*1024;
676 Globals.shmem_size = SHMEM_SIZE;
677 Globals.shmem_hash_size = SHMEM_HASH_SIZE;
678 Globals.announce_as = ANNOUNCE_AS_NT;
679 Globals.bUnixRealname = False;
680 #if (defined(NETGROUP) && defined(AUTOMOUNT))
681 Globals.bNISHomeMap = False;
682 string_set(&Globals.szNISHomeMapName, "auto.home");
684 coding_system = interpret_coding_system (KANJI, SJIS_CODE);
685 Globals.client_code_page = DEFAULT_CLIENT_CODE_PAGE;
686 Globals.bTimeServer = False;
687 Globals.bBindInterfacesOnly = False;
689 /* these parameters are set to defaults that are more appropriate
690 for the increasing samba install base:
692 as a member of the workgroup, that will possibly become a
693 _local_ master browser (lm = True). this is opposed to a forced
694 local master browser startup (pm = True).
696 doesn't provide WINS server service by default (wsupp = False),
697 and doesn't provide domain master browser services by default, either.
701 Globals.bPreferredMaster = False;
702 Globals.bLocalMaster = True;
703 Globals.bDomainMaster = False;
704 Globals.bDomainLogons = False;
705 Globals.bBrowseList = True;
706 Globals.bWINSsupport = False;
707 Globals.bWINSproxy = False;
709 /* this parameter is currently set to the default functionality
710 in samba. given that w95 and NT is starting to use DNS for
711 server resolution, i expect that at some point it would be
712 sensible to default this to False.
714 this parameter is added because nmbd is a single process, and
715 gethostbyname is a blocking call, which can take out nmbd for
716 several seconds while a dns lookup is performed.
720 Globals.bDNSproxy = True;
723 /***************************************************************************
724 check if a string is initialised and if not then initialise it
725 ***************************************************************************/
726 static void string_initial(char **s,char *v)
733 /***************************************************************************
734 Initialise the sDefault parameter structure.
735 ***************************************************************************/
736 static void init_locals(void)
738 /* choose defaults depending on the type of printing */
739 switch (Globals.printing)
745 string_initial(&sDefault.szLpqcommand,"lpq -P%p");
746 string_initial(&sDefault.szLprmcommand,"lprm -P%p %j");
747 string_initial(&sDefault.szPrintcommand,"lpr -r -P%p %s");
752 string_initial(&sDefault.szLpqcommand,"lpstat -o%p");
753 string_initial(&sDefault.szLprmcommand,"cancel %p-%j");
754 string_initial(&sDefault.szPrintcommand,"lp -c -d%p %s; rm %s");
756 string_initial(&sDefault.szLppausecommand,"lp -i %p-%j -H hold");
757 string_initial(&sDefault.szLpresumecommand,"lp -i %p-%j -H resume");
762 string_initial(&sDefault.szLpqcommand,"lpq -P%p");
763 string_initial(&sDefault.szLprmcommand,"lprm -P%p %j");
764 string_initial(&sDefault.szPrintcommand,"lp -r -P%p %s");
772 /******************************************************************* a
773 convenience routine to grab string parameters into a rotating buffer,
774 and run standard_sub_basic on them. The buffers can be written to by
775 callers without affecting the source string.
776 ********************************************************************/
777 char *lp_string(char *s)
779 static char *bufs[10];
780 static int buflen[10];
781 static int next = -1;
784 int len = s?strlen(s):0;
795 len = MAX(len+100,sizeof(pstring)); /* the +100 is for some
798 if (buflen[next] != len) {
800 if (bufs[next]) free(bufs[next]);
801 bufs[next] = (char *)malloc(len);
803 DEBUG(0,("out of memory in lp_string()"));
808 ret = &bufs[next][0];
816 trim_string(ret, "\"", "\"");
818 standard_sub_basic(ret);
824 In this section all the functions that are used to access the
825 parameters from the rest of the program are defined
828 #define FN_GLOBAL_STRING(fn_name,ptr) \
829 char *fn_name(void) {return(lp_string(*(char **)(ptr) ? *(char **)(ptr) : ""));}
830 #define FN_GLOBAL_BOOL(fn_name,ptr) \
831 BOOL fn_name(void) {return(*(BOOL *)(ptr));}
832 #define FN_GLOBAL_CHAR(fn_name,ptr) \
833 char fn_name(void) {return(*(char *)(ptr));}
834 #define FN_GLOBAL_INTEGER(fn_name,ptr) \
835 int fn_name(void) {return(*(int *)(ptr));}
837 #define FN_LOCAL_STRING(fn_name,val) \
838 char *fn_name(int i) {return(lp_string((LP_SNUM_OK(i)&&pSERVICE(i)->val)?pSERVICE(i)->val : sDefault.val));}
839 #define FN_LOCAL_BOOL(fn_name,val) \
840 BOOL fn_name(int i) {return(LP_SNUM_OK(i)? pSERVICE(i)->val : sDefault.val);}
841 #define FN_LOCAL_CHAR(fn_name,val) \
842 char fn_name(int i) {return(LP_SNUM_OK(i)? pSERVICE(i)->val : sDefault.val);}
843 #define FN_LOCAL_INTEGER(fn_name,val) \
844 int fn_name(int i) {return(LP_SNUM_OK(i)? pSERVICE(i)->val : sDefault.val);}
846 FN_GLOBAL_STRING(lp_logfile,&Globals.szLogFile)
847 FN_GLOBAL_STRING(lp_smbrun,&Globals.szSmbrun)
848 FN_GLOBAL_STRING(lp_configfile,&Globals.szConfigFile)
849 FN_GLOBAL_STRING(lp_smb_passwd_file,&Globals.szSMBPasswdFile)
850 FN_GLOBAL_STRING(lp_serverstring,&Globals.szServerString)
851 FN_GLOBAL_STRING(lp_printcapname,&Globals.szPrintcapname)
852 FN_GLOBAL_STRING(lp_lockdir,&Globals.szLockDir)
853 FN_GLOBAL_STRING(lp_rootdir,&Globals.szRootdir)
854 FN_GLOBAL_STRING(lp_defaultservice,&Globals.szDefaultService)
855 FN_GLOBAL_STRING(lp_msg_command,&Globals.szMsgCommand)
856 FN_GLOBAL_STRING(lp_dfree_command,&Globals.szDfree)
857 FN_GLOBAL_STRING(lp_hosts_equiv,&Globals.szHostsEquiv)
858 FN_GLOBAL_STRING(lp_auto_services,&Globals.szAutoServices)
859 FN_GLOBAL_STRING(lp_passwd_program,&Globals.szPasswdProgram)
860 FN_GLOBAL_STRING(lp_passwd_chat,&Globals.szPasswdChat)
861 FN_GLOBAL_STRING(lp_passwordserver,&Globals.szPasswordServer)
862 FN_GLOBAL_STRING(lp_workgroup,&Globals.szWorkGroup)
863 FN_GLOBAL_STRING(lp_domain_controller,&Globals.szDomainController)
864 FN_GLOBAL_STRING(lp_username_map,&Globals.szUsernameMap)
865 FN_GLOBAL_STRING(lp_character_set,&Globals.szCharacterSet)
866 FN_GLOBAL_STRING(lp_logon_script,&Globals.szLogonScript)
867 FN_GLOBAL_STRING(lp_logon_path,&Globals.szLogonPath)
868 FN_GLOBAL_STRING(lp_logon_drive,&Globals.szLogonDrive)
869 FN_GLOBAL_STRING(lp_logon_home,&Globals.szLogonHome)
870 FN_GLOBAL_STRING(lp_remote_announce,&Globals.szRemoteAnnounce)
871 FN_GLOBAL_STRING(lp_wins_server,&Globals.szWINSserver)
872 FN_GLOBAL_STRING(lp_interfaces,&Globals.szInterfaces)
873 FN_GLOBAL_STRING(lp_socket_address,&Globals.szSocketAddress)
874 FN_GLOBAL_STRING(lp_nis_home_map_name,&Globals.szNISHomeMapName)
875 FN_GLOBAL_STRING(lp_announce_version,&Globals.szAnnounceVersion)
876 FN_GLOBAL_STRING(lp_netbios_aliases,&Globals.szNetbiosAliases)
877 FN_GLOBAL_STRING(lp_driverfile,&Globals.szDriverFile)
879 FN_GLOBAL_STRING(lp_domain_sid,&Globals.szDomainSID)
880 FN_GLOBAL_STRING(lp_domain_other_sids,&Globals.szDomainOtherSIDs)
881 FN_GLOBAL_STRING(lp_domain_groups,&Globals.szDomainGroups)
882 FN_GLOBAL_STRING(lp_domain_admin_users,&Globals.szDomainAdminUsers)
883 FN_GLOBAL_STRING(lp_domain_guest_users,&Globals.szDomainGuestUsers)
885 FN_GLOBAL_BOOL(lp_dns_proxy,&Globals.bDNSproxy)
886 FN_GLOBAL_BOOL(lp_wins_support,&Globals.bWINSsupport)
887 FN_GLOBAL_BOOL(lp_wins_proxy,&Globals.bWINSproxy)
888 FN_GLOBAL_BOOL(lp_local_master,&Globals.bLocalMaster)
889 FN_GLOBAL_BOOL(lp_domain_master,&Globals.bDomainMaster)
890 FN_GLOBAL_BOOL(lp_domain_logons,&Globals.bDomainLogons)
891 FN_GLOBAL_BOOL(lp_preferred_master,&Globals.bPreferredMaster)
892 FN_GLOBAL_BOOL(lp_load_printers,&Globals.bLoadPrinters)
893 FN_GLOBAL_BOOL(lp_use_rhosts,&Globals.bUseRhosts)
894 FN_GLOBAL_BOOL(lp_getwdcache,&use_getwd_cache)
895 FN_GLOBAL_BOOL(lp_readprediction,&Globals.bReadPrediction)
896 FN_GLOBAL_BOOL(lp_readbmpx,&Globals.bReadbmpx)
897 FN_GLOBAL_BOOL(lp_readraw,&Globals.bReadRaw)
898 FN_GLOBAL_BOOL(lp_writeraw,&Globals.bWriteRaw)
899 FN_GLOBAL_BOOL(lp_null_passwords,&Globals.bNullPasswords)
900 FN_GLOBAL_BOOL(lp_strip_dot,&Globals.bStripDot)
901 FN_GLOBAL_BOOL(lp_encrypted_passwords,&Globals.bEncryptPasswords)
902 FN_GLOBAL_BOOL(lp_syslog_only,&Globals.bSyslogOnly)
903 FN_GLOBAL_BOOL(lp_browse_list,&Globals.bBrowseList)
904 FN_GLOBAL_BOOL(lp_unix_realname,&Globals.bUnixRealname)
905 FN_GLOBAL_BOOL(lp_nis_home_map,&Globals.bNISHomeMap)
906 FN_GLOBAL_BOOL(lp_time_server,&Globals.bTimeServer)
907 FN_GLOBAL_BOOL(lp_bind_interfaces_only,&Globals.bBindInterfacesOnly)
909 FN_GLOBAL_INTEGER(lp_os_level,&Globals.os_level)
910 FN_GLOBAL_INTEGER(lp_max_ttl,&Globals.max_ttl)
911 FN_GLOBAL_INTEGER(lp_max_log_size,&Globals.max_log_size)
912 FN_GLOBAL_INTEGER(lp_mangledstack,&Globals.mangled_stack)
913 FN_GLOBAL_INTEGER(lp_maxxmit,&Globals.max_xmit)
914 FN_GLOBAL_INTEGER(lp_maxmux,&Globals.max_mux)
915 FN_GLOBAL_INTEGER(lp_maxpacket,&Globals.max_packet)
916 FN_GLOBAL_INTEGER(lp_keepalive,&keepalive)
917 FN_GLOBAL_INTEGER(lp_passwordlevel,&Globals.pwordlevel)
918 FN_GLOBAL_INTEGER(lp_usernamelevel,&Globals.unamelevel)
919 FN_GLOBAL_INTEGER(lp_readsize,&Globals.ReadSize)
920 FN_GLOBAL_INTEGER(lp_shmem_size,&Globals.shmem_size)
921 FN_GLOBAL_INTEGER(lp_shmem_hash_size,&Globals.shmem_hash_size)
922 FN_GLOBAL_INTEGER(lp_deadtime,&Globals.deadtime)
923 FN_GLOBAL_INTEGER(lp_maxprotocol,&Globals.maxprotocol)
924 FN_GLOBAL_INTEGER(lp_security,&Globals.security)
925 FN_GLOBAL_INTEGER(lp_printing,&Globals.printing)
926 FN_GLOBAL_INTEGER(lp_maxdisksize,&Globals.maxdisksize)
927 FN_GLOBAL_INTEGER(lp_lpqcachetime,&Globals.lpqcachetime)
928 FN_GLOBAL_INTEGER(lp_syslog,&Globals.syslog)
929 FN_GLOBAL_INTEGER(lp_client_code_page,&Globals.client_code_page)
930 FN_GLOBAL_INTEGER(lp_announce_as,&Globals.announce_as)
932 FN_LOCAL_STRING(lp_preexec,szPreExec)
933 FN_LOCAL_STRING(lp_postexec,szPostExec)
934 FN_LOCAL_STRING(lp_rootpreexec,szRootPreExec)
935 FN_LOCAL_STRING(lp_rootpostexec,szRootPostExec)
936 FN_LOCAL_STRING(lp_servicename,szService)
937 FN_LOCAL_STRING(lp_pathname,szPath)
938 FN_LOCAL_STRING(lp_dontdescend,szDontdescend)
939 FN_LOCAL_STRING(lp_username,szUsername)
940 FN_LOCAL_STRING(lp_guestaccount,szGuestaccount)
941 FN_LOCAL_STRING(lp_invalid_users,szInvalidUsers)
942 FN_LOCAL_STRING(lp_valid_users,szValidUsers)
943 FN_LOCAL_STRING(lp_admin_users,szAdminUsers)
944 FN_LOCAL_STRING(lp_printcommand,szPrintcommand)
945 FN_LOCAL_STRING(lp_lpqcommand,szLpqcommand)
946 FN_LOCAL_STRING(lp_lprmcommand,szLprmcommand)
947 FN_LOCAL_STRING(lp_lppausecommand,szLppausecommand)
948 FN_LOCAL_STRING(lp_lpresumecommand,szLpresumecommand)
949 FN_LOCAL_STRING(lp_printername,szPrintername)
950 FN_LOCAL_STRING(lp_printerdriver,szPrinterDriver)
951 FN_LOCAL_STRING(lp_hostsallow,szHostsallow)
952 FN_LOCAL_STRING(lp_hostsdeny,szHostsdeny)
953 FN_LOCAL_STRING(lp_magicscript,szMagicScript)
954 FN_LOCAL_STRING(lp_magicoutput,szMagicOutput)
955 FN_LOCAL_STRING(lp_comment,comment)
956 FN_LOCAL_STRING(lp_force_user,force_user)
957 FN_LOCAL_STRING(lp_force_group,force_group)
958 FN_LOCAL_STRING(lp_readlist,readlist)
959 FN_LOCAL_STRING(lp_writelist,writelist)
960 FN_LOCAL_STRING(lp_volume,volume)
961 FN_LOCAL_STRING(lp_mangled_map,szMangledMap)
962 FN_LOCAL_STRING(lp_veto_files,szVetoFiles)
963 FN_LOCAL_STRING(lp_hide_files,szHideFiles)
964 FN_LOCAL_STRING(lp_driverlocation,szPrinterDriverLocation)
966 FN_LOCAL_BOOL(lp_alternate_permissions,bAlternatePerm)
967 FN_LOCAL_BOOL(lp_revalidate,bRevalidate)
968 FN_LOCAL_BOOL(lp_casesensitive,bCaseSensitive)
969 FN_LOCAL_BOOL(lp_preservecase,bCasePreserve)
970 FN_LOCAL_BOOL(lp_shortpreservecase,bShortCasePreserve)
971 FN_LOCAL_BOOL(lp_casemangle,bCaseMangle)
972 FN_LOCAL_BOOL(lp_status,status)
973 FN_LOCAL_BOOL(lp_hide_dot_files,bHideDotFiles)
974 FN_LOCAL_BOOL(lp_browseable,bBrowseable)
975 FN_LOCAL_BOOL(lp_readonly,bRead_only)
976 FN_LOCAL_BOOL(lp_no_set_dir,bNo_set_dir)
977 FN_LOCAL_BOOL(lp_guest_ok,bGuest_ok)
978 FN_LOCAL_BOOL(lp_guest_only,bGuest_only)
979 FN_LOCAL_BOOL(lp_print_ok,bPrint_ok)
980 FN_LOCAL_BOOL(lp_postscript,bPostscript)
981 FN_LOCAL_BOOL(lp_map_hidden,bMap_hidden)
982 FN_LOCAL_BOOL(lp_map_archive,bMap_archive)
983 FN_LOCAL_BOOL(lp_locking,bLocking)
984 FN_LOCAL_BOOL(lp_strict_locking,bStrictLocking)
985 FN_LOCAL_BOOL(lp_share_modes,bShareModes)
986 FN_LOCAL_BOOL(lp_oplocks,bOpLocks)
987 FN_LOCAL_BOOL(lp_onlyuser,bOnlyUser)
988 FN_LOCAL_BOOL(lp_manglednames,bMangledNames)
989 FN_LOCAL_BOOL(lp_widelinks,bWidelinks)
990 FN_LOCAL_BOOL(lp_symlinks,bSymlinks)
991 FN_LOCAL_BOOL(lp_syncalways,bSyncAlways)
992 FN_LOCAL_BOOL(lp_map_system,bMap_system)
993 FN_LOCAL_BOOL(lp_delete_readonly,bDeleteReadonly)
994 FN_LOCAL_BOOL(lp_fake_oplocks,bFakeOplocks)
995 FN_LOCAL_BOOL(lp_recursive_veto_delete,bDeleteVetoFiles)
996 FN_LOCAL_BOOL(lp_dos_filetimes,bDosFiletimes)
998 FN_LOCAL_INTEGER(lp_create_mode,iCreate_mask)
999 FN_LOCAL_INTEGER(lp_force_create_mode,iCreate_force_mode)
1000 FN_LOCAL_INTEGER(lp_dir_mode,iDir_mask)
1001 FN_LOCAL_INTEGER(lp_force_dir_mode,iDir_force_mode)
1002 FN_LOCAL_INTEGER(lp_max_connections,iMaxConnections)
1003 FN_LOCAL_INTEGER(lp_defaultcase,iDefaultCase)
1004 FN_LOCAL_INTEGER(lp_minprintspace,iMinPrintSpace)
1006 FN_LOCAL_CHAR(lp_magicchar,magic_char)
1010 /* local prototypes */
1011 static int strwicmp( char *psz1, char *psz2 );
1012 static int map_parameter( char *pszParmName);
1013 static BOOL set_boolean( BOOL *pb, char *pszParmValue );
1014 static int getservicebyname(char *pszServiceName, service *pserviceDest);
1015 static void copy_service( service *pserviceDest,
1016 service *pserviceSource,
1017 BOOL *pcopymapDest );
1018 static BOOL service_ok(int iService);
1019 static BOOL do_parameter(char *pszParmName, char *pszParmValue);
1020 static BOOL do_section(char *pszSectionName);
1021 static void init_copymap(service *pservice);
1024 /***************************************************************************
1025 initialise a service to the defaults
1026 ***************************************************************************/
1027 static void init_service(service *pservice)
1029 bzero((char *)pservice,sizeof(service));
1030 copy_service(pservice,&sDefault,NULL);
1034 /***************************************************************************
1035 free the dynamically allocated parts of a service struct
1036 ***************************************************************************/
1037 static void free_service(service *pservice)
1043 for (i=0;parm_table[i].label;i++)
1044 if ((parm_table[i].type == P_STRING ||
1045 parm_table[i].type == P_STRING) &&
1046 parm_table[i].class == P_LOCAL)
1047 string_free((char **)(((char *)pservice) + PTR_DIFF(parm_table[i].ptr,&sDefault)));
1050 /***************************************************************************
1051 add a new service to the services array initialising it with the given
1053 ***************************************************************************/
1054 static int add_a_service(service *pservice, char *name)
1058 int num_to_alloc = iNumServices+1;
1060 tservice = *pservice;
1062 /* it might already exist */
1065 i = getservicebyname(name,NULL);
1070 /* find an invalid one */
1071 for (i=0;i<iNumServices;i++)
1072 if (!pSERVICE(i)->valid)
1075 /* if not, then create one */
1076 if (i == iNumServices)
1078 ServicePtrs = (service **)Realloc(ServicePtrs,sizeof(service *)*num_to_alloc);
1080 pSERVICE(iNumServices) = (service *)malloc(sizeof(service));
1082 if (!ServicePtrs || !pSERVICE(iNumServices))
1088 free_service(pSERVICE(i));
1090 pSERVICE(i)->valid = True;
1092 init_service(pSERVICE(i));
1093 copy_service(pSERVICE(i),&tservice,NULL);
1095 string_set(&iSERVICE(i).szService,name);
1100 /***************************************************************************
1101 add a new home service, with the specified home directory, defaults coming
1103 ***************************************************************************/
1104 BOOL lp_add_home(char *pszHomename, int iDefaultService, char *pszHomedir)
1106 int i = add_a_service(pSERVICE(iDefaultService),pszHomename);
1111 if (!(*(iSERVICE(i).szPath)) || strequal(iSERVICE(i).szPath,lp_pathname(-1)))
1112 string_set(&iSERVICE(i).szPath,pszHomedir);
1113 if (!(*(iSERVICE(i).comment)))
1116 sprintf(comment,"Home directory of %s",pszHomename);
1117 string_set(&iSERVICE(i).comment,comment);
1119 iSERVICE(i).bAvailable = sDefault.bAvailable;
1120 iSERVICE(i).bBrowseable = sDefault.bBrowseable;
1122 DEBUG(3,("adding home directory %s at %s\n", pszHomename, pszHomedir));
1127 /***************************************************************************
1128 add a new service, based on an old one
1129 ***************************************************************************/
1130 int lp_add_service(char *pszService, int iDefaultService)
1132 return(add_a_service(pSERVICE(iDefaultService),pszService));
1136 /***************************************************************************
1138 ***************************************************************************/
1139 static BOOL lp_add_ipc(void)
1142 int i = add_a_service(&sDefault,"IPC$");
1147 sprintf(comment,"IPC Service (%s)",lp_serverstring());
1149 string_set(&iSERVICE(i).szPath,tmpdir());
1150 string_set(&iSERVICE(i).szUsername,"");
1151 string_set(&iSERVICE(i).comment,comment);
1152 iSERVICE(i).status = False;
1153 iSERVICE(i).iMaxConnections = 0;
1154 iSERVICE(i).bAvailable = True;
1155 iSERVICE(i).bRead_only = True;
1156 iSERVICE(i).bGuest_only = False;
1157 iSERVICE(i).bGuest_ok = True;
1158 iSERVICE(i).bPrint_ok = False;
1159 iSERVICE(i).bBrowseable = sDefault.bBrowseable;
1161 DEBUG(3,("adding IPC service\n"));
1167 /***************************************************************************
1168 add a new printer service, with defaults coming from service iFrom
1169 ***************************************************************************/
1170 BOOL lp_add_printer(char *pszPrintername, int iDefaultService)
1172 char *comment = "From Printcap";
1173 int i = add_a_service(pSERVICE(iDefaultService),pszPrintername);
1178 /* note that we do NOT default the availability flag to True - */
1179 /* we take it from the default service passed. This allows all */
1180 /* dynamic printers to be disabled by disabling the [printers] */
1181 /* entry (if/when the 'available' keyword is implemented!). */
1183 /* the printer name is set to the service name. */
1184 string_set(&iSERVICE(i).szPrintername,pszPrintername);
1185 string_set(&iSERVICE(i).comment,comment);
1186 iSERVICE(i).bBrowseable = sDefault.bBrowseable;
1187 /* Printers cannot be read_only. */
1188 iSERVICE(i).bRead_only = False;
1189 /* No share modes on printer services. */
1190 iSERVICE(i).bShareModes = False;
1191 /* No oplocks on printer services. */
1192 iSERVICE(i).bOpLocks = False;
1193 /* Printer services must be printable. */
1194 iSERVICE(i).bPrint_ok = True;
1196 DEBUG(3,("adding printer service %s\n",pszPrintername));
1202 /***************************************************************************
1203 Do a case-insensitive, whitespace-ignoring string compare.
1204 ***************************************************************************/
1205 static int strwicmp(char *psz1, char *psz2)
1207 /* if BOTH strings are NULL, return TRUE, if ONE is NULL return */
1208 /* appropriate value. */
1218 /* sync the strings on first non-whitespace */
1221 while (isspace(*psz1))
1223 while (isspace(*psz2))
1225 if (toupper(*psz1) != toupper(*psz2) || *psz1 == '\0' || *psz2 == '\0')
1230 return (*psz1 - *psz2);
1233 /***************************************************************************
1234 Map a parameter's string representation to something we can use.
1235 Returns False if the parameter string is not recognised, else TRUE.
1236 ***************************************************************************/
1237 static int map_parameter(char *pszParmName)
1241 if (*pszParmName == '-')
1244 for (iIndex = 0; parm_table[iIndex].label; iIndex++)
1245 if (strwicmp(parm_table[iIndex].label, pszParmName) == 0)
1248 DEBUG(0,( "Unknown parameter encountered: \"%s\"\n", pszParmName));
1253 /***************************************************************************
1254 Set a boolean variable from the text value stored in the passed string.
1255 Returns True in success, False if the passed string does not correctly
1256 represent a boolean.
1257 ***************************************************************************/
1258 static BOOL set_boolean(BOOL *pb, char *pszParmValue)
1263 if (strwicmp(pszParmValue, "yes") == 0 ||
1264 strwicmp(pszParmValue, "true") == 0 ||
1265 strwicmp(pszParmValue, "1") == 0)
1268 if (strwicmp(pszParmValue, "no") == 0 ||
1269 strwicmp(pszParmValue, "False") == 0 ||
1270 strwicmp(pszParmValue, "0") == 0)
1274 DEBUG(0,( "Badly formed boolean in configuration file: \"%s\".\n",
1281 /***************************************************************************
1282 Find a service by name. Otherwise works like get_service.
1283 ***************************************************************************/
1284 static int getservicebyname(char *pszServiceName, service *pserviceDest)
1288 for (iService = iNumServices - 1; iService >= 0; iService--)
1289 if (VALID(iService) &&
1290 strwicmp(iSERVICE(iService).szService, pszServiceName) == 0)
1292 if (pserviceDest != NULL)
1293 copy_service(pserviceDest, pSERVICE(iService), NULL);
1302 /***************************************************************************
1303 Copy a service structure to another
1305 If pcopymapDest is NULL then copy all fields
1306 ***************************************************************************/
1307 static void copy_service(service *pserviceDest,
1308 service *pserviceSource,
1312 BOOL bcopyall = (pcopymapDest == NULL);
1314 for (i=0;parm_table[i].label;i++)
1315 if (parm_table[i].ptr && parm_table[i].class == P_LOCAL &&
1316 (bcopyall || pcopymapDest[i]))
1318 void *def_ptr = parm_table[i].ptr;
1320 ((char *)pserviceSource) + PTR_DIFF(def_ptr,&sDefault);
1322 ((char *)pserviceDest) + PTR_DIFF(def_ptr,&sDefault);
1324 switch (parm_table[i].type)
1328 *(BOOL *)dest_ptr = *(BOOL *)src_ptr;
1333 *(int *)dest_ptr = *(int *)src_ptr;
1337 *(char *)dest_ptr = *(char *)src_ptr;
1341 string_set(dest_ptr,*(char **)src_ptr);
1345 string_set(dest_ptr,*(char **)src_ptr);
1346 strupper(*(char **)dest_ptr);
1355 init_copymap(pserviceDest);
1356 if (pserviceSource->copymap)
1357 memcpy((void *)pserviceDest->copymap,
1358 (void *)pserviceSource->copymap,sizeof(BOOL)*NUMPARAMETERS);
1362 /***************************************************************************
1363 Check a service for consistency. Return False if the service is in any way
1364 incomplete or faulty, else True.
1365 ***************************************************************************/
1366 static BOOL service_ok(int iService)
1371 if (iSERVICE(iService).szService[0] == '\0')
1373 DEBUG(0,( "The following message indicates an internal error:\n"));
1374 DEBUG(0,( "No service name in service entry.\n"));
1378 /* The [printers] entry MUST be printable. I'm all for flexibility, but */
1379 /* I can't see why you'd want a non-printable printer service... */
1380 if (strwicmp(iSERVICE(iService).szService,PRINTERS_NAME) == 0)
1381 if (!iSERVICE(iService).bPrint_ok)
1383 DEBUG(0,( "WARNING: [%s] service MUST be printable!\n",
1384 iSERVICE(iService).szService));
1385 iSERVICE(iService).bPrint_ok = True;
1388 if (iSERVICE(iService).szPath[0] == '\0' &&
1389 strwicmp(iSERVICE(iService).szService,HOMES_NAME) != 0)
1391 DEBUG(0,("No path in service %s - using %s\n",iSERVICE(iService).szService,tmpdir()));
1392 string_set(&iSERVICE(iService).szPath,tmpdir());
1395 /* If a service is flagged unavailable, log the fact at level 0. */
1396 if (!iSERVICE(iService).bAvailable)
1397 DEBUG(1,( "NOTE: Service %s is flagged unavailable.\n",
1398 iSERVICE(iService).szService));
1403 static struct file_lists {
1404 struct file_lists *next;
1407 } *file_lists = NULL;
1409 /*******************************************************************
1410 keep a linked list of all config files so we know when one has changed
1411 it's date and needs to be reloaded
1412 ********************************************************************/
1413 static void add_to_file_list(char *fname)
1415 struct file_lists *f=file_lists;
1418 if (f->name && !strcmp(f->name,fname)) break;
1423 f = (struct file_lists *)malloc(sizeof(file_lists[0]));
1425 f->next = file_lists;
1426 f->name = strdup(fname);
1437 standard_sub_basic(n2);
1438 f->modtime = file_modtime(n2);
1443 /*******************************************************************
1444 check if a config file has changed date
1445 ********************************************************************/
1446 BOOL lp_file_list_changed(void)
1448 struct file_lists *f = file_lists;
1449 DEBUG(6,("lp_file_list_changed()\n"));
1456 pstrcpy(n2,f->name);
1457 standard_sub_basic(n2);
1459 DEBUG(6,("file %s -> %s last mod_time: %s\n",
1460 f->name, n2, ctime(&f->modtime)));
1462 mod_time = file_modtime(n2);
1464 if (f->modtime != mod_time) {
1465 DEBUG(6,("file %s modified: %s\n", n2, ctime(&mod_time)));
1466 f->modtime = mod_time;
1474 /***************************************************************************
1475 handle the interpretation of the coding system parameter
1476 *************************************************************************/
1477 static BOOL handle_coding_system(char *pszParmValue,int *val)
1479 *val = interpret_coding_system(pszParmValue,*val);
1483 /***************************************************************************
1484 handle the interpretation of the character set system parameter
1485 ***************************************************************************/
1486 static BOOL handle_character_set(char *pszParmValue,int *val)
1488 string_set(&Globals.szCharacterSet,pszParmValue);
1489 *val = interpret_character_set(pszParmValue,*val);
1494 /***************************************************************************
1495 handle the interpretation of the protocol parameter
1496 ***************************************************************************/
1497 static BOOL handle_protocol(char *pszParmValue,int *val)
1499 *val = interpret_protocol(pszParmValue,*val);
1503 /***************************************************************************
1504 handle the interpretation of the security parameter
1505 ***************************************************************************/
1506 static BOOL handle_security(char *pszParmValue,int *val)
1508 *val = interpret_security(pszParmValue,*val);
1512 /***************************************************************************
1513 handle the interpretation of the default case
1514 ***************************************************************************/
1515 static BOOL handle_case(char *pszParmValue,int *val)
1517 if (strnequal(pszParmValue,"LOWER", 5))
1519 else if (strnequal(pszParmValue,"UPPER", 5))
1524 /***************************************************************************
1525 handle the interpretation of the printing system
1526 ***************************************************************************/
1527 static BOOL handle_printing(char *pszParmValue,int *val)
1529 if (strnequal(pszParmValue,"sysv", 4))
1531 else if (strnequal(pszParmValue,"aix", 3))
1533 else if (strnequal(pszParmValue,"hpux", 4))
1535 else if (strnequal(pszParmValue,"bsd", 3))
1537 else if (strnequal(pszParmValue,"qnx",3))
1539 else if (strnequal(pszParmValue,"plp", 3))
1541 else if (strnequal(pszParmValue,"lprng", 5))
1546 /***************************************************************************
1547 handle the announce as parameter
1548 ***************************************************************************/
1549 static BOOL handle_announce_as(char *pszParmValue,int *val)
1551 if (strnequal(pszParmValue,"NT", 2))
1552 *val = ANNOUNCE_AS_NT;
1553 else if (strnequal(pszParmValue,"win95", 5))
1554 *val = ANNOUNCE_AS_WIN95;
1555 else if (strnequal(pszParmValue,"WfW", 3))
1556 *val = ANNOUNCE_AS_WFW;
1560 /***************************************************************************
1561 handle the valid chars lines
1562 ***************************************************************************/
1563 static BOOL handle_valid_chars(char *pszParmValue,char **ptr)
1565 string_set(ptr,pszParmValue);
1567 /* A dependency here is that the parameter client code page must be
1568 set before this is called - as calling codepage_initialise()
1569 would overwrite the valid char lines.
1571 codepage_initialise(lp_client_code_page());
1573 add_char_string(pszParmValue);
1578 /***************************************************************************
1579 handle the include operation
1580 ***************************************************************************/
1581 static BOOL handle_include(char *pszParmValue,char **ptr)
1584 pstrcpy(fname,pszParmValue);
1586 add_to_file_list(fname);
1588 standard_sub_basic(fname);
1590 string_set(ptr,fname);
1592 if (file_exist(fname,NULL))
1593 return(pm_process(fname, do_section, do_parameter));
1595 DEBUG(2,("Can't find include file %s\n",fname));
1601 /***************************************************************************
1602 handle the interpretation of the copy parameter
1603 ***************************************************************************/
1604 static BOOL handle_copy(char *pszParmValue,char **ptr)
1608 service serviceTemp;
1610 string_set(ptr,pszParmValue);
1612 init_service(&serviceTemp);
1616 DEBUG(3,("Copying service from service %s\n",pszParmValue));
1618 if ((iTemp = getservicebyname(pszParmValue, &serviceTemp)) >= 0)
1620 if (iTemp == iServiceIndex)
1622 DEBUG(0,("Can't copy service %s - unable to copy self!\n",
1627 copy_service(pSERVICE(iServiceIndex),
1629 iSERVICE(iServiceIndex).copymap);
1635 DEBUG(0,( "Unable to copy service - source not found: %s\n",
1640 free_service(&serviceTemp);
1645 /***************************************************************************
1646 initialise a copymap
1647 ***************************************************************************/
1648 static void init_copymap(service *pservice)
1651 if (pservice->copymap) free(pservice->copymap);
1652 pservice->copymap = (BOOL *)malloc(sizeof(BOOL)*NUMPARAMETERS);
1653 if (!pservice->copymap)
1654 DEBUG(0,("Couldn't allocate copymap!! (size %d)\n",NUMPARAMETERS));
1656 for (i=0;i<NUMPARAMETERS;i++)
1657 pservice->copymap[i] = True;
1661 /***************************************************************************
1662 Process a parameter for a particular service number. If snum < 0
1663 then assume we are in the globals
1664 ***************************************************************************/
1665 BOOL lp_do_parameter(int snum, char *pszParmName, char *pszParmValue)
1668 void *parm_ptr=NULL; /* where we are going to store the result */
1671 parmnum = map_parameter(pszParmName);
1675 DEBUG(0,( "Ignoring unknown parameter \"%s\"\n", pszParmName));
1679 def_ptr = parm_table[parmnum].ptr;
1681 /* we might point at a service, the default service or a global */
1685 if (parm_table[parmnum].class == P_GLOBAL) {
1686 DEBUG(0,( "Global parameter %s found in service section!\n",pszParmName));
1689 parm_ptr = ((char *)pSERVICE(snum)) + PTR_DIFF(def_ptr,&sDefault);
1694 if (!iSERVICE(snum).copymap)
1695 init_copymap(pSERVICE(snum));
1697 /* this handles the aliases - set the copymap for other entries with
1698 the same data pointer */
1699 for (i=0;parm_table[i].label;i++)
1700 if (parm_table[i].ptr == parm_table[parmnum].ptr)
1701 iSERVICE(snum).copymap[i] = False;
1704 /* if it is a special case then go ahead */
1705 if (parm_table[parmnum].special) {
1706 parm_table[parmnum].special(pszParmValue,parm_ptr);
1710 /* now switch on the type of variable it is */
1711 switch (parm_table[parmnum].type)
1714 set_boolean(parm_ptr,pszParmValue);
1718 set_boolean(parm_ptr,pszParmValue);
1719 *(BOOL *)parm_ptr = ! *(BOOL *)parm_ptr;
1723 *(int *)parm_ptr = atoi(pszParmValue);
1727 *(char *)parm_ptr = *pszParmValue;
1731 sscanf(pszParmValue,"%o",(int *)parm_ptr);
1735 string_set(parm_ptr,pszParmValue);
1739 string_set(parm_ptr,pszParmValue);
1740 strupper(*(char **)parm_ptr);
1744 strcpy((char *)parm_ptr,pszParmValue);
1748 strcpy((char *)parm_ptr,pszParmValue);
1749 strupper((char *)parm_ptr);
1756 /***************************************************************************
1757 Process a parameter.
1758 ***************************************************************************/
1759 static BOOL do_parameter(char *pszParmName, char *pszParmValue)
1761 if (!bInGlobalSection && bGlobalOnly) return(True);
1763 DEBUG(3,("doing parameter %s = %s\n",pszParmName,pszParmValue));
1765 return lp_do_parameter(bInGlobalSection?-2:iServiceIndex, pszParmName, pszParmValue);
1769 /***************************************************************************
1770 print a parameter of the specified type
1771 ***************************************************************************/
1772 static void print_parameter(parm_type type,void *ptr, FILE *f)
1777 fprintf(f,"%s",BOOLSTR(*(BOOL *)ptr));
1781 fprintf(f,"%s",BOOLSTR(! *(BOOL *)ptr));
1785 fprintf(f,"%d",*(int *)ptr);
1789 fprintf(f,"%c",*(char *)ptr);
1793 fprintf(f,"0%o",*(int *)ptr);
1799 fprintf(f,"%s",(char *)ptr);
1805 fprintf(f,"%s",*(char **)ptr);
1811 /***************************************************************************
1812 print a parameter of the specified type
1813 ***************************************************************************/
1814 static void parameter_string(parm_type type,void *ptr,char *s)
1821 sprintf(s, "%s",BOOLSTR(*(BOOL *)ptr));
1825 sprintf(s, "%s",BOOLSTR(! *(BOOL *)ptr));
1829 sprintf(s, "%d",*(int *)ptr);
1833 sprintf(s, "%c",*(char *)ptr);
1837 sprintf(s, "0%o",*(int *)ptr);
1843 sprintf(s, "%s",(char *)ptr);
1849 sprintf(s, "%s",*(char **)ptr);
1855 /***************************************************************************
1856 check if two parameters are equal
1857 ***************************************************************************/
1858 static BOOL equal_parameter(parm_type type,void *ptr1,void *ptr2)
1864 return(*((BOOL *)ptr1) == *((BOOL *)ptr2));
1868 return(*((int *)ptr1) == *((int *)ptr2));
1871 return(*((char *)ptr1) == *((char *)ptr2));
1876 char *p1 = (char *)ptr1, *p2 = (char *)ptr2;
1877 if (p1 && !*p1) p1 = NULL;
1878 if (p2 && !*p2) p2 = NULL;
1879 return(p1==p2 || strequal(p1,p2));
1884 char *p1 = *(char **)ptr1, *p2 = *(char **)ptr2;
1885 if (p1 && !*p1) p1 = NULL;
1886 if (p2 && !*p2) p2 = NULL;
1887 return(p1==p2 || strequal(p1,p2));
1893 /***************************************************************************
1894 Process a new section (service). At this stage all sections are services.
1895 Later we'll have special sections that permit server parameters to be set.
1896 Returns True on success, False on failure.
1897 ***************************************************************************/
1898 static BOOL do_section(char *pszSectionName)
1901 BOOL isglobal = ((strwicmp(pszSectionName, GLOBAL_NAME) == 0) ||
1902 (strwicmp(pszSectionName, GLOBAL_NAME2) == 0));
1905 /* if we were in a global section then do the local inits */
1906 if (bInGlobalSection && !isglobal)
1909 /* if we've just struck a global section, note the fact. */
1910 bInGlobalSection = isglobal;
1912 /* check for multiple global sections */
1913 if (bInGlobalSection)
1915 DEBUG(3,( "Processing section \"[%s]\"\n", pszSectionName));
1919 if (!bInGlobalSection && bGlobalOnly) return(True);
1921 /* if we have a current service, tidy it up before moving on */
1924 if (iServiceIndex >= 0)
1925 bRetval = service_ok(iServiceIndex);
1927 /* if all is still well, move to the next record in the services array */
1930 /* We put this here to avoid an odd message order if messages are */
1931 /* issued by the post-processing of a previous section. */
1932 DEBUG(2,( "Processing section \"[%s]\"\n", pszSectionName));
1934 if ((iServiceIndex=add_a_service(&sDefault,pszSectionName)) < 0)
1936 DEBUG(0,("Failed to add a new service\n"));
1944 /***************************************************************************
1945 Display the contents of the global structure.
1946 ***************************************************************************/
1947 static void dump_globals(FILE *f)
1950 fprintf(f, "# Global parameters\n");
1952 for (i=0;parm_table[i].label;i++)
1953 if (parm_table[i].class == P_GLOBAL &&
1954 parm_table[i].ptr &&
1955 (i == 0 || (parm_table[i].ptr != parm_table[i-1].ptr)))
1957 fprintf(f,"\t%s = ",parm_table[i].label);
1958 print_parameter(parm_table[i].type,parm_table[i].ptr, f);
1963 /***************************************************************************
1964 Display the contents of a single services record.
1965 ***************************************************************************/
1966 static void dump_a_service(service *pService, FILE *f)
1969 if (pService == &sDefault)
1970 fprintf(f,"\n\n# Default service parameters\n");
1972 fprintf(f,"\n[%s]\n",pService->szService);
1974 for (i=0;parm_table[i].label;i++)
1975 if (parm_table[i].class == P_LOCAL &&
1976 parm_table[i].ptr &&
1977 (*parm_table[i].label != '-') &&
1978 (i == 0 || (parm_table[i].ptr != parm_table[i-1].ptr)))
1980 int pdiff = PTR_DIFF(parm_table[i].ptr,&sDefault);
1982 if (pService == &sDefault || !equal_parameter(parm_table[i].type,
1983 ((char *)pService) + pdiff,
1984 ((char *)&sDefault) + pdiff))
1986 fprintf(f,"\t%s = ",parm_table[i].label);
1987 print_parameter(parm_table[i].type,
1988 ((char *)pService) + pdiff, f);
1995 /***************************************************************************
1996 return info about the next service in a service. snum==-1 gives the default
1997 serice and snum==-2 gives the globals
1999 return 0 when out of parameters
2000 ***************************************************************************/
2001 int lp_next_parameter(int snum, int *i, char *label,
2002 char *value, int allparameters)
2005 /* do the globals */
2006 for (;parm_table[*i].label;(*i)++)
2007 if (parm_table[*i].class == P_GLOBAL &&
2008 parm_table[*i].ptr &&
2009 (*parm_table[*i].label != '-') &&
2011 (parm_table[*i].ptr != parm_table[(*i)-1].ptr))) {
2012 strcpy(label, parm_table[*i].label);
2013 parameter_string(parm_table[*i].type,
2021 service *pService = (snum==-1?&sDefault:pSERVICE(snum));
2023 for (;parm_table[*i].label;(*i)++)
2024 if (parm_table[*i].class == P_LOCAL &&
2025 parm_table[*i].ptr &&
2026 (*parm_table[*i].label != '-') &&
2028 (parm_table[*i].ptr != parm_table[(*i)-1].ptr))) {
2029 int pdiff = PTR_DIFF(parm_table[*i].ptr,&sDefault);
2031 if (snum == -1 || allparameters ||
2032 !equal_parameter(parm_table[*i].type,
2033 ((char *)pService) + pdiff,
2034 ((char *)&sDefault) + pdiff)) {
2035 strcpy(label, parm_table[*i].label);
2036 parameter_string(parm_table[*i].type,
2037 ((char *)pService) + pdiff,
2050 /***************************************************************************
2051 Display the contents of a single copy structure.
2052 ***************************************************************************/
2053 static void dump_copy_map(BOOL *pcopymap)
2056 if (!pcopymap) return;
2058 printf("\n\tNon-Copied parameters:\n");
2060 for (i=0;parm_table[i].label;i++)
2061 if (parm_table[i].class == P_LOCAL &&
2062 parm_table[i].ptr && !pcopymap[i] &&
2063 (i == 0 || (parm_table[i].ptr != parm_table[i-1].ptr)))
2065 printf("\t\t%s\n",parm_table[i].label);
2070 /***************************************************************************
2071 Return TRUE if the passed service number is within range.
2072 ***************************************************************************/
2073 BOOL lp_snum_ok(int iService)
2075 return (LP_SNUM_OK(iService) && iSERVICE(iService).bAvailable);
2079 /***************************************************************************
2080 auto-load some homes and printer services
2081 ***************************************************************************/
2082 static void lp_add_auto_services(char *str)
2086 int homes = lp_servicenumber(HOMES_NAME);
2087 int printers = lp_servicenumber(PRINTERS_NAME);
2095 for (p=strtok(s,LIST_SEP);p;p=strtok(NULL,LIST_SEP))
2097 char *home = get_home_dir(p);
2099 if (lp_servicenumber(p) >= 0) continue;
2101 if (home && homes >= 0)
2103 lp_add_home(p,homes,home);
2107 if (printers >= 0 && pcap_printername_ok(p,NULL))
2108 lp_add_printer(p,printers);
2113 /***************************************************************************
2114 auto-load one printer
2115 ***************************************************************************/
2116 static void lp_add_one_printer(char *name,char *comment)
2118 int printers = lp_servicenumber(PRINTERS_NAME);
2121 if (lp_servicenumber(name) < 0)
2123 lp_add_printer(name,printers);
2124 if ((i=lp_servicenumber(name)) >= 0)
2125 string_set(&iSERVICE(i).comment,comment);
2130 /***************************************************************************
2131 auto-load printer services
2132 ***************************************************************************/
2133 static void lp_add_all_printers(void)
2135 int printers = lp_servicenumber(PRINTERS_NAME);
2137 if (printers < 0) return;
2139 pcap_printer_fn(lp_add_one_printer);
2142 /***************************************************************************
2143 have we loaded a services file yet?
2144 ***************************************************************************/
2145 BOOL lp_loaded(void)
2150 /***************************************************************************
2151 unload unused services
2152 ***************************************************************************/
2153 void lp_killunused(BOOL (*snumused)(int ))
2156 for (i=0;i<iNumServices;i++)
2157 if (VALID(i) && (!snumused || !snumused(i)))
2159 iSERVICE(i).valid = False;
2160 free_service(pSERVICE(i));
2164 /***************************************************************************
2165 Load the services array from the services file. Return True on success,
2167 ***************************************************************************/
2168 BOOL lp_load(char *pszFname,BOOL global_only)
2173 add_to_file_list(pszFname);
2177 bInGlobalSection = True;
2178 bGlobalOnly = global_only;
2182 pstrcpy(n2,pszFname);
2183 standard_sub_basic(n2);
2185 /* We get sections first, so have to start 'behind' to make up */
2187 bRetval = pm_process(n2, do_section, do_parameter);
2189 /* finish up the last section */
2190 DEBUG(3,("pm_process() returned %s\n", BOOLSTR(bRetval)));
2192 if (iServiceIndex >= 0)
2193 bRetval = service_ok(iServiceIndex);
2195 lp_add_auto_services(lp_auto_services());
2196 if (lp_load_printers())
2197 lp_add_all_printers();
2201 set_default_server_announce_type();
2209 /***************************************************************************
2210 return the max number of services
2211 ***************************************************************************/
2212 int lp_numservices(void)
2214 return(iNumServices);
2217 /***************************************************************************
2218 Display the contents of the services array in human-readable form.
2219 ***************************************************************************/
2220 void lp_dump(FILE *f)
2226 dump_a_service(&sDefault, f);
2228 for (iService = 0; iService < iNumServices; iService++)
2230 if (VALID(iService))
2232 if (iSERVICE(iService).szService[0] == '\0')
2234 dump_a_service(pSERVICE(iService), f);
2240 /***************************************************************************
2241 Return the number of the service with the given name, or -1 if it doesn't
2242 exist. Note that this is a DIFFERENT ANIMAL from the internal function
2243 getservicebyname()! This works ONLY if all services have been loaded, and
2244 does not copy the found service.
2245 ***************************************************************************/
2246 int lp_servicenumber(char *pszServiceName)
2250 for (iService = iNumServices - 1; iService >= 0; iService--)
2251 if (VALID(iService) &&
2252 strwicmp(iSERVICE(iService).szService, pszServiceName) == 0)
2256 DEBUG(7,("lp_servicenumber: couldn't find %s\n",pszServiceName));
2261 /*******************************************************************
2262 a useful volume label function
2263 ******************************************************************/
2264 char *volume_label(int snum)
2266 char *ret = lp_volume(snum);
2267 if (!*ret) return(lp_servicename(snum));
2273 * nmbd only loads the global section. There seems to be no way to
2274 * determine exactly is a service is printable by only looking at the
2275 * [global] section so for now always announce as a print server. This
2276 * will need looking at in the future. Jeremy (jallison@whistle.com).
2278 /*******************************************************************
2279 Return true if any printer services are defined.
2280 ******************************************************************/
2281 static BOOL lp_printer_services(void)
2285 for (iService = iNumServices - 1; iService >= 0; iService--)
2286 if (VALID(iService) && iSERVICE(iService).bPrint_ok)
2292 /*******************************************************************
2293 Set the server type we will announce as via nmbd.
2294 ********************************************************************/
2295 static void set_default_server_announce_type()
2297 default_server_announce = (SV_TYPE_WORKSTATION | SV_TYPE_SERVER |
2298 SV_TYPE_SERVER_UNIX | SV_TYPE_PRINTQ_SERVER);
2299 if(lp_announce_as() == ANNOUNCE_AS_NT)
2300 default_server_announce |= (SV_TYPE_SERVER_NT | SV_TYPE_NT);
2301 else if(lp_announce_as() == ANNOUNCE_AS_WIN95)
2302 default_server_announce |= SV_TYPE_WIN95_PLUS;
2303 else if(lp_announce_as() == ANNOUNCE_AS_WFW)
2304 default_server_announce |= SV_TYPE_WFW;
2305 default_server_announce |= (lp_time_server() ? SV_TYPE_TIME_SOURCE : 0);
2307 * nmbd only loads the [global] section. There seems to be no way to
2308 * determine exactly if any service is printable by only looking at the
2309 * [global] section so for now always announce as a print server. This
2310 * will need looking at in the future. Jeremy (jallison@whistle.com).
2313 default_server_announce |= (lp_printer_services() ? SV_TYPE_PRINTQ_SERVER : 0);
2318 /*******************************************************************
2320 ********************************************************************/
2321 void lp_rename_service(int snum, char *new_name)
2323 string_set(&pSERVICE(snum)->szService, new_name);
2326 /*******************************************************************
2328 ********************************************************************/
2329 void lp_remove_service(int snum)
2331 pSERVICE(snum)->valid = False;
2334 /*******************************************************************
2336 ********************************************************************/
2337 void lp_copy_service(int snum, char *new_name)
2339 char *oldname = lp_servicename(snum);
2340 do_section(new_name);
2342 snum = lp_servicenumber(new_name);
2344 lp_do_parameter(snum, "copy", oldname);
2349 /*******************************************************************
2350 Get the default server type we will announce as via nmbd.
2351 ********************************************************************/
2352 int lp_default_server_announce(void)
2354 return default_server_announce;
2357 /*******************************************************************
2358 Split the announce version into major and minor numbers.
2359 ********************************************************************/
2360 int lp_major_announce_version(void)
2362 static BOOL got_major = False;
2363 static int major_version = DEFAULT_MAJOR_VERSION;
2368 return major_version;
2371 if((vers = lp_announce_version()) == NULL)
2372 return major_version;
2374 if((p = strchr(vers, '.')) == 0)
2375 return major_version;
2378 major_version = atoi(vers);
2379 return major_version;
2382 int lp_minor_announce_version(void)
2384 static BOOL got_minor = False;
2385 static int minor_version = DEFAULT_MINOR_VERSION;
2390 return minor_version;
2393 if((vers = lp_announce_version()) == NULL)
2394 return minor_version;
2396 if((p = strchr(vers, '.')) == 0)
2397 return minor_version;
2400 minor_version = atoi(p);
2401 return minor_version;