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;
132 char *szCharacterSet;
140 char *szRemoteAnnounce;
141 char *szSocketAddress;
142 char *szNISHomeMapName;
143 char *szAnnounceVersion; /* This is initialised in init_globals */
144 char *szNetbiosAliases;
146 char *szDomainGroups;
166 int client_code_page;
167 int announce_as; /* This is initialised in init_globals */
172 BOOL bPreferredMaster;
175 BOOL bEncryptPasswords;
182 BOOL bReadPrediction;
189 BOOL bBindInterfacesOnly;
192 static global Globals;
197 * This structure describes a single service.
205 char *szGuestaccount;
206 char *szInvalidUsers;
214 char *szRootPostExec;
215 char *szPrintcommand;
218 char *szLppausecommand;
219 char *szLpresumecommand;
221 char *szPrinterDriver;
238 int iCreate_force_mode;
247 BOOL bShortCasePreserve;
273 BOOL bDeleteReadonly;
275 BOOL bDeleteVetoFiles;
277 char dummy[3]; /* for alignment */
281 /* This is a default service used to prime a services structure */
282 static service sDefault =
285 NULL, /* szService */
287 NULL, /* szUsername */
288 NULL, /* szGuestAccount - this is set in init_globals() */
289 NULL, /* szInvalidUsers */
290 NULL, /* szValidUsers */
291 NULL, /* szAdminUsers */
293 NULL, /* szInclude */
294 NULL, /* szPreExec */
295 NULL, /* szPostExec */
296 NULL, /* szRootPreExec */
297 NULL, /* szRootPostExec */
298 NULL, /* szPrintcommand */
299 NULL, /* szLpqcommand */
300 NULL, /* szLprmcommand */
301 NULL, /* szLppausecommand */
302 NULL, /* szLpresumecommand */
303 NULL, /* szPrintername */
304 NULL, /* szPrinterDriver - this is set in init_globals() */
305 NULL, /* szDontdescend */
306 NULL, /* szHostsallow */
307 NULL, /* szHostsdeny */
308 NULL, /* szMagicScript */
309 NULL, /* szMagicOutput */
310 NULL, /* szMangledMap */
311 NULL, /* szVetoFiles */
312 NULL, /* szHideFiles */
314 NULL, /* force user */
315 NULL, /* force group */
317 NULL, /* writelist */
319 0, /* iMinPrintSpace */
320 0744, /* iCreate_mask */
321 0000, /* iCreate_force_mode */
322 0755, /* iDir_mask */
323 0000, /* iDir_force_mode */
324 0, /* iMaxConnections */
325 CASE_LOWER, /* iDefaultCase */
326 False, /* bAlternatePerm */
327 False, /* revalidate */
328 False, /* case sensitive */
329 False, /* case preserve */
330 False, /* short case preserve */
331 False, /* case mangle */
333 True, /* bHideDotFiles */
334 True, /* bBrowseable */
335 True, /* bAvailable */
336 True, /* bRead_only */
337 True, /* bNo_set_dir */
338 False, /* bGuest_only */
339 False, /* bGuest_ok */
340 False, /* bPrint_ok */
341 False, /* bPostscript */
342 False, /* bMap_system */
343 False, /* bMap_hidden */
344 True, /* bMap_archive */
346 False, /* bStrictLocking */
347 True, /* bShareModes */
349 False, /* bOnlyUser */
350 True, /* bMangledNames */
351 True, /* bWidelinks */
352 True, /* bSymlinks */
353 False, /* bSyncAlways */
354 '~', /* magic char */
356 False, /* bDeleteReadonly */
357 False, /* bFakeOplocks */
358 False, /* bDeleteVetoFiles */
359 False, /* bDosFiletimes */
365 /* local variables */
366 static service **ServicePtrs = NULL;
367 static int iNumServices = 0;
368 static int iServiceIndex = 0;
369 static BOOL bInGlobalSection = True;
370 static BOOL bGlobalOnly = False;
371 static int default_server_announce;
373 #define NUMPARAMETERS (sizeof(parm_table) / sizeof(struct parm_struct))
375 /* prototypes for the special type handlers */
376 static BOOL handle_valid_chars(char *pszParmValue, char **ptr);
377 static BOOL handle_include(char *pszParmValue, char **ptr);
378 static BOOL handle_copy(char *pszParmValue, char **ptr);
379 static BOOL handle_protocol(char *pszParmValue,int *val);
380 static BOOL handle_security(char *pszParmValue,int *val);
381 static BOOL handle_case(char *pszParmValue,int *val);
382 static BOOL handle_printing(char *pszParmValue,int *val);
383 static BOOL handle_character_set(char *pszParmValue,int *val);
384 static BOOL handle_announce_as(char *pszParmValue, int *val);
385 static BOOL handle_coding_system(char *pszParmValue,int *val);
387 static void set_default_server_announce_type(void);
398 {"debuglevel", P_INTEGER, P_GLOBAL, &DEBUGLEVEL, NULL},
399 {"log level", P_INTEGER, P_GLOBAL, &DEBUGLEVEL, NULL},
400 {"syslog", P_INTEGER, P_GLOBAL, &Globals.syslog, NULL},
401 {"syslog only", P_BOOL, P_GLOBAL, &Globals.bSyslogOnly, NULL},
402 {"protocol", P_INTEGER, P_GLOBAL, &Globals.maxprotocol,handle_protocol},
403 {"security", P_INTEGER, P_GLOBAL, &Globals.security,handle_security},
404 {"printing", P_INTEGER, P_GLOBAL, &Globals.printing,handle_printing},
405 {"max disk size", P_INTEGER, P_GLOBAL, &Globals.maxdisksize, NULL},
406 {"lpq cache time", P_INTEGER, P_GLOBAL, &Globals.lpqcachetime, NULL},
407 {"announce as", P_INTEGER, P_GLOBAL, &Globals.announce_as, handle_announce_as},
408 {"encrypt passwords",P_BOOL, P_GLOBAL, &Globals.bEncryptPasswords, NULL},
409 {"getwd cache", P_BOOL, P_GLOBAL, &use_getwd_cache, NULL},
410 {"read prediction", P_BOOL, P_GLOBAL, &Globals.bReadPrediction, NULL},
411 {"read bmpx", P_BOOL, P_GLOBAL, &Globals.bReadbmpx, NULL},
412 {"read raw", P_BOOL, P_GLOBAL, &Globals.bReadRaw, NULL},
413 {"write raw", P_BOOL, P_GLOBAL, &Globals.bWriteRaw, NULL},
414 {"use rhosts", P_BOOL, P_GLOBAL, &Globals.bUseRhosts, NULL},
415 {"load printers", P_BOOL, P_GLOBAL, &Globals.bLoadPrinters, NULL},
416 {"null passwords", P_BOOL, P_GLOBAL, &Globals.bNullPasswords, NULL},
417 {"strip dot", P_BOOL, P_GLOBAL, &Globals.bStripDot, NULL},
418 {"interfaces", P_STRING, P_GLOBAL, &Globals.szInterfaces, NULL},
419 {"bind interfaces only", P_BOOL,P_GLOBAL, &Globals.bBindInterfacesOnly,NULL},
420 {"password server", P_STRING, P_GLOBAL, &Globals.szPasswordServer, NULL},
421 {"socket options", P_GSTRING, P_GLOBAL, user_socket_options, NULL},
422 {"netbios name", P_UGSTRING,P_GLOBAL, myname, NULL},
423 {"netbios aliases", P_STRING, P_GLOBAL, &Globals.szNetbiosAliases, NULL},
424 {"smbrun", P_STRING, P_GLOBAL, &Globals.szSmbrun, NULL},
425 {"log file", P_STRING, P_GLOBAL, &Globals.szLogFile, NULL},
426 {"config file", P_STRING, P_GLOBAL, &Globals.szConfigFile, NULL},
427 {"smb passwd file", P_STRING, P_GLOBAL, &Globals.szSMBPasswdFile, NULL},
428 {"hosts equiv", P_STRING, P_GLOBAL, &Globals.szHostsEquiv, NULL},
429 {"preload", P_STRING, P_GLOBAL, &Globals.szAutoServices, NULL},
430 {"auto services", P_STRING, P_GLOBAL, &Globals.szAutoServices, NULL},
431 {"server string", P_STRING, P_GLOBAL, &Globals.szServerString, NULL},
432 {"printcap name", P_STRING, P_GLOBAL, &Globals.szPrintcapname, NULL},
433 {"printcap", P_STRING, P_GLOBAL, &Globals.szPrintcapname, NULL},
434 {"lock dir", P_STRING, P_GLOBAL, &Globals.szLockDir, NULL},
435 {"lock directory", P_STRING, P_GLOBAL, &Globals.szLockDir, NULL},
436 {"root directory", P_STRING, P_GLOBAL, &Globals.szRootdir, NULL},
437 {"root dir", P_STRING, P_GLOBAL, &Globals.szRootdir, NULL},
438 {"root", P_STRING, P_GLOBAL, &Globals.szRootdir, NULL},
439 {"default service", P_STRING, P_GLOBAL, &Globals.szDefaultService, NULL},
440 {"default", P_STRING, P_GLOBAL, &Globals.szDefaultService, NULL},
441 {"message command", P_STRING, P_GLOBAL, &Globals.szMsgCommand, NULL},
442 {"dfree command", P_STRING, P_GLOBAL, &Globals.szDfree, NULL},
443 {"passwd program", P_STRING, P_GLOBAL, &Globals.szPasswdProgram, NULL},
444 {"passwd chat", P_STRING, P_GLOBAL, &Globals.szPasswdChat, NULL},
445 {"valid chars", P_STRING, P_GLOBAL, &Globals.szValidChars, handle_valid_chars},
446 {"workgroup", P_USTRING, P_GLOBAL, &Globals.szWorkGroup, NULL},
447 {"domain sid", P_USTRING, P_GLOBAL, &Globals.szDomainSID, NULL},
448 {"domain groups", P_USTRING, P_GLOBAL, &Globals.szDomainGroups, NULL},
449 {"domain controller",P_STRING, P_GLOBAL, &Globals.szDomainController,NULL},
450 {"username map", P_STRING, P_GLOBAL, &Globals.szUsernameMap, NULL},
451 {"character set", P_STRING, P_GLOBAL, &Globals.szCharacterSet, handle_character_set},
452 {"logon script", P_STRING, P_GLOBAL, &Globals.szLogonScript, NULL},
453 {"logon path", P_STRING, P_GLOBAL, &Globals.szLogonPath, NULL},
454 {"logon drive", P_STRING, P_GLOBAL, &Globals.szLogonDrive, NULL},
455 {"logon home", P_STRING, P_GLOBAL, &Globals.szLogonHome, NULL},
456 {"remote announce", P_STRING, P_GLOBAL, &Globals.szRemoteAnnounce, NULL},
457 {"socket address", P_STRING, P_GLOBAL, &Globals.szSocketAddress, NULL},
458 {"homedir map", P_STRING, P_GLOBAL, &Globals.szNISHomeMapName, NULL},
459 {"announce version", P_STRING, P_GLOBAL, &Globals.szAnnounceVersion, NULL},
460 {"max log size", P_INTEGER, P_GLOBAL, &Globals.max_log_size, NULL},
461 {"mangled stack", P_INTEGER, P_GLOBAL, &Globals.mangled_stack, NULL},
462 {"max mux", P_INTEGER, P_GLOBAL, &Globals.max_mux, NULL},
463 {"max xmit", P_INTEGER, P_GLOBAL, &Globals.max_xmit, NULL},
464 {"max packet", P_INTEGER, P_GLOBAL, &Globals.max_packet, NULL},
465 {"packet size", P_INTEGER, P_GLOBAL, &Globals.max_packet, NULL},
466 {"password level", P_INTEGER, P_GLOBAL, &Globals.pwordlevel, NULL},
467 {"username level", P_INTEGER, P_GLOBAL, &Globals.unamelevel, NULL},
468 {"keepalive", P_INTEGER, P_GLOBAL, &keepalive, NULL},
469 {"deadtime", P_INTEGER, P_GLOBAL, &Globals.deadtime, NULL},
470 {"time offset", P_INTEGER, P_GLOBAL, &extra_time_offset, NULL},
471 {"read size", P_INTEGER, P_GLOBAL, &Globals.ReadSize, NULL},
472 {"shared mem size", P_INTEGER, P_GLOBAL, &Globals.shmem_size, NULL},
473 {"shared file entries", P_INTEGER, P_GLOBAL, &Globals.shmem_hash_size, NULL},
474 {"coding system", P_INTEGER, P_GLOBAL, &coding_system, handle_coding_system},
475 {"client code page", P_INTEGER, P_GLOBAL, &Globals.client_code_page, NULL},
476 {"os level", P_INTEGER, P_GLOBAL, &Globals.os_level, NULL},
477 {"max ttl", P_INTEGER, P_GLOBAL, &Globals.max_ttl, NULL},
478 {"dns proxy", P_BOOL, P_GLOBAL, &Globals.bDNSproxy, NULL},
479 {"wins support", P_BOOL, P_GLOBAL, &Globals.bWINSsupport, NULL},
480 {"wins proxy", P_BOOL, P_GLOBAL, &Globals.bWINSproxy, NULL},
481 {"wins server", P_STRING, P_GLOBAL, &Globals.szWINSserver, NULL},
482 {"preferred master", P_BOOL, P_GLOBAL, &Globals.bPreferredMaster, NULL},
483 {"prefered master", P_BOOL, P_GLOBAL, &Globals.bPreferredMaster, NULL},
484 {"local master", P_BOOL, P_GLOBAL, &Globals.bLocalMaster, NULL},
485 {"domain master", P_BOOL, P_GLOBAL, &Globals.bDomainMaster, NULL},
486 {"domain logons", P_BOOL, P_GLOBAL, &Globals.bDomainLogons, NULL},
487 {"browse list", P_BOOL, P_GLOBAL, &Globals.bBrowseList, NULL},
488 {"unix realname", P_BOOL, P_GLOBAL, &Globals.bUnixRealname, NULL},
489 {"NIS homedir", P_BOOL, P_GLOBAL, &Globals.bNISHomeMap, NULL},
490 {"time server", P_BOOL, P_GLOBAL, &Globals.bTimeServer, NULL},
491 {"-valid", P_BOOL, P_LOCAL, &sDefault.valid, NULL},
492 {"comment", P_STRING, P_LOCAL, &sDefault.comment, NULL},
493 {"copy", P_STRING, P_LOCAL, &sDefault.szCopy, handle_copy},
494 {"include", P_STRING, P_LOCAL, &sDefault.szInclude, handle_include},
495 {"exec", P_STRING, P_LOCAL, &sDefault.szPreExec, NULL},
496 {"preexec", P_STRING, P_LOCAL, &sDefault.szPreExec, NULL},
497 {"postexec", P_STRING, P_LOCAL, &sDefault.szPostExec, NULL},
498 {"root preexec", P_STRING, P_LOCAL, &sDefault.szRootPreExec, NULL},
499 {"root postexec", P_STRING, P_LOCAL, &sDefault.szRootPostExec, NULL},
500 {"alternate permissions",P_BOOL,P_LOCAL, &sDefault.bAlternatePerm, NULL},
501 {"revalidate", P_BOOL, P_LOCAL, &sDefault.bRevalidate, NULL},
502 {"default case", P_INTEGER, P_LOCAL, &sDefault.iDefaultCase, handle_case},
503 {"case sensitive", P_BOOL, P_LOCAL, &sDefault.bCaseSensitive, NULL},
504 {"casesignames", P_BOOL, P_LOCAL, &sDefault.bCaseSensitive, NULL},
505 {"preserve case", P_BOOL, P_LOCAL, &sDefault.bCasePreserve, NULL},
506 {"short preserve case",P_BOOL, P_LOCAL, &sDefault.bShortCasePreserve,NULL},
507 {"mangle case", P_BOOL, P_LOCAL, &sDefault.bCaseMangle, NULL},
508 {"mangling char", P_CHAR, P_LOCAL, &sDefault.magic_char, NULL},
509 {"browseable", P_BOOL, P_LOCAL, &sDefault.bBrowseable, NULL},
510 {"browsable", P_BOOL, P_LOCAL, &sDefault.bBrowseable, NULL},
511 {"available", P_BOOL, P_LOCAL, &sDefault.bAvailable, NULL},
512 {"path", P_STRING, P_LOCAL, &sDefault.szPath, NULL},
513 {"directory", P_STRING, P_LOCAL, &sDefault.szPath, NULL},
514 {"username", P_STRING, P_LOCAL, &sDefault.szUsername, NULL},
515 {"user", P_STRING, P_LOCAL, &sDefault.szUsername, NULL},
516 {"users", P_STRING, P_LOCAL, &sDefault.szUsername, NULL},
517 {"guest account", P_STRING, P_LOCAL, &sDefault.szGuestaccount, NULL},
518 {"invalid users", P_STRING, P_LOCAL, &sDefault.szInvalidUsers, NULL},
519 {"valid users", P_STRING, P_LOCAL, &sDefault.szValidUsers, NULL},
520 {"admin users", P_STRING, P_LOCAL, &sDefault.szAdminUsers, NULL},
521 {"read list", P_STRING, P_LOCAL, &sDefault.readlist, NULL},
522 {"write list", P_STRING, P_LOCAL, &sDefault.writelist, NULL},
523 {"volume", P_STRING, P_LOCAL, &sDefault.volume, NULL},
524 {"force user", P_STRING, P_LOCAL, &sDefault.force_user, NULL},
525 {"force group", P_STRING, P_LOCAL, &sDefault.force_group, NULL},
526 {"group", P_STRING, P_LOCAL, &sDefault.force_group, NULL},
527 {"read only", P_BOOL, P_LOCAL, &sDefault.bRead_only, NULL},
528 {"write ok", P_BOOLREV, P_LOCAL, &sDefault.bRead_only, NULL},
529 {"writeable", P_BOOLREV, P_LOCAL, &sDefault.bRead_only, NULL},
530 {"writable", P_BOOLREV, P_LOCAL, &sDefault.bRead_only, NULL},
531 {"max connections", P_INTEGER, P_LOCAL, &sDefault.iMaxConnections, NULL},
532 {"min print space", P_INTEGER, P_LOCAL, &sDefault.iMinPrintSpace, NULL},
533 {"create mask", P_OCTAL, P_LOCAL, &sDefault.iCreate_mask, NULL},
534 {"create mode", P_OCTAL, P_LOCAL, &sDefault.iCreate_mask, NULL},
535 {"force create mode",P_OCTAL, P_LOCAL, &sDefault.iCreate_force_mode, NULL},
536 {"directory mask", P_OCTAL, P_LOCAL, &sDefault.iDir_mask, NULL},
537 {"directory mode", P_OCTAL, P_LOCAL, &sDefault.iDir_mask, NULL},
538 {"force directory mode", P_OCTAL, P_LOCAL, &sDefault.iDir_force_mode, NULL},
539 {"set directory", P_BOOLREV, P_LOCAL, &sDefault.bNo_set_dir, NULL},
540 {"status", P_BOOL, P_LOCAL, &sDefault.status, NULL},
541 {"hide dot files", P_BOOL, P_LOCAL, &sDefault.bHideDotFiles, NULL},
542 {"delete veto files",P_BOOL, P_LOCAL, &sDefault.bDeleteVetoFiles, NULL},
543 {"veto files", P_STRING, P_LOCAL, &sDefault.szVetoFiles, NULL},
544 {"hide files", P_STRING, P_LOCAL, &sDefault.szHideFiles, NULL},
545 {"guest only", P_BOOL, P_LOCAL, &sDefault.bGuest_only, NULL},
546 {"only guest", P_BOOL, P_LOCAL, &sDefault.bGuest_only, NULL},
547 {"guest ok", P_BOOL, P_LOCAL, &sDefault.bGuest_ok, NULL},
548 {"public", P_BOOL, P_LOCAL, &sDefault.bGuest_ok, NULL},
549 {"print ok", P_BOOL, P_LOCAL, &sDefault.bPrint_ok, NULL},
550 {"printable", P_BOOL, P_LOCAL, &sDefault.bPrint_ok, NULL},
551 {"postscript", P_BOOL, P_LOCAL, &sDefault.bPostscript, NULL},
552 {"map system", P_BOOL, P_LOCAL, &sDefault.bMap_system, NULL},
553 {"map hidden", P_BOOL, P_LOCAL, &sDefault.bMap_hidden, NULL},
554 {"map archive", P_BOOL, P_LOCAL, &sDefault.bMap_archive, NULL},
555 {"locking", P_BOOL, P_LOCAL, &sDefault.bLocking, NULL},
556 {"strict locking", P_BOOL, P_LOCAL, &sDefault.bStrictLocking, NULL},
557 {"share modes", P_BOOL, P_LOCAL, &sDefault.bShareModes, NULL},
558 {"oplocks", P_BOOL, P_LOCAL, &sDefault.bOpLocks, NULL},
559 {"only user", P_BOOL, P_LOCAL, &sDefault.bOnlyUser, NULL},
560 {"wide links", P_BOOL, P_LOCAL, &sDefault.bWidelinks, NULL},
561 {"follow symlinks", P_BOOL, P_LOCAL, &sDefault.bSymlinks, NULL},
562 {"sync always", P_BOOL, P_LOCAL, &sDefault.bSyncAlways, NULL},
563 {"mangled names", P_BOOL, P_LOCAL, &sDefault.bMangledNames, NULL},
564 {"fake oplocks", P_BOOL, P_LOCAL, &sDefault.bFakeOplocks, NULL},
565 {"print command", P_STRING, P_LOCAL, &sDefault.szPrintcommand, NULL},
566 {"lpq command", P_STRING, P_LOCAL, &sDefault.szLpqcommand, NULL},
567 {"lprm command", P_STRING, P_LOCAL, &sDefault.szLprmcommand, NULL},
568 {"lppause command", P_STRING, P_LOCAL, &sDefault.szLppausecommand, NULL},
569 {"lpresume command", P_STRING, P_LOCAL, &sDefault.szLpresumecommand,NULL},
570 {"printer", P_STRING, P_LOCAL, &sDefault.szPrintername, NULL},
571 {"printer name", P_STRING, P_LOCAL, &sDefault.szPrintername, NULL},
572 {"printer driver", P_STRING, P_LOCAL, &sDefault.szPrinterDriver, NULL},
573 {"hosts allow", P_STRING, P_LOCAL, &sDefault.szHostsallow, NULL},
574 {"allow hosts", P_STRING, P_LOCAL, &sDefault.szHostsallow, NULL},
575 {"hosts deny", P_STRING, P_LOCAL, &sDefault.szHostsdeny, NULL},
576 {"deny hosts", P_STRING, P_LOCAL, &sDefault.szHostsdeny, NULL},
577 {"dont descend", P_STRING, P_LOCAL, &sDefault.szDontdescend, NULL},
578 {"magic script", P_STRING, P_LOCAL, &sDefault.szMagicScript, NULL},
579 {"magic output", P_STRING, P_LOCAL, &sDefault.szMagicOutput, NULL},
580 {"mangled map", P_STRING, P_LOCAL, &sDefault.szMangledMap, NULL},
581 {"delete readonly", P_BOOL, P_LOCAL, &sDefault.bDeleteReadonly, NULL},
582 {"dos filetimes", P_BOOL, P_LOCAL, &sDefault.bDosFiletimes, NULL},
584 {NULL, P_BOOL, P_NONE, NULL, NULL}
589 /***************************************************************************
590 Initialise the global parameter structure.
591 ***************************************************************************/
592 static void init_globals(void)
594 static BOOL done_init = False;
600 bzero((void *)&Globals,sizeof(Globals));
602 for (i = 0; parm_table[i].label; i++)
603 if ((parm_table[i].type == P_STRING ||
604 parm_table[i].type == P_USTRING) &&
606 string_init(parm_table[i].ptr,"");
608 string_set(&sDefault.szGuestaccount, GUEST_ACCOUNT);
609 string_set(&sDefault.szPrinterDriver, "NULL");
615 DEBUG(3,("Initialising global parameters\n"));
617 #ifdef SMB_PASSWD_FILE
618 string_set(&Globals.szSMBPasswdFile, SMB_PASSWD_FILE);
620 string_set(&Globals.szPasswdChat,"*old*password* %o\\n *new*password* %n\\n *new*password* %n\\n *changed*");
621 string_set(&Globals.szWorkGroup, WORKGROUP);
622 string_set(&Globals.szPasswdProgram, SMB_PASSWD);
623 string_set(&Globals.szPrintcapname, PRINTCAP_NAME);
624 string_set(&Globals.szLockDir, LOCKDIR);
625 string_set(&Globals.szRootdir, "/");
626 string_set(&Globals.szSmbrun, SMBRUN);
627 string_set(&Globals.szSocketAddress, "0.0.0.0");
628 sprintf(s,"Samba %s",VERSION);
629 string_set(&Globals.szServerString,s);
630 sprintf(s,"%d.%d", DEFAULT_MAJOR_VERSION, DEFAULT_MINOR_VERSION);
631 string_set(&Globals.szAnnounceVersion,s);
633 string_set(&Globals.szLogonDrive, "");
634 /* %N is the NIS auto.home server if -DAUTOHOME is used, else same as %L */
635 string_set(&Globals.szLogonHome, "\\\\%N\\%U");
636 string_set(&Globals.szLogonPath, "\\\\%N\\%U\\profile");
637 string_set(&Globals.szDomainGroups, "776/7");
638 Globals.bLoadPrinters = True;
639 Globals.bUseRhosts = False;
640 Globals.max_packet = 65535;
641 Globals.mangled_stack = 50;
642 Globals.max_xmit = 65535;
643 Globals.max_mux = 50; /* This is *needed* for profile support. */
644 Globals.lpqcachetime = 10;
645 Globals.pwordlevel = 0;
646 Globals.unamelevel = 0;
647 Globals.deadtime = 0;
648 Globals.max_log_size = 5000;
649 Globals.maxprotocol = PROTOCOL_NT1;
650 Globals.security = SEC_SHARE;
651 Globals.bEncryptPasswords = False;
652 Globals.printing = DEFAULT_PRINTING;
653 Globals.bReadRaw = True;
654 Globals.bWriteRaw = True;
655 Globals.bReadPrediction = False;
656 Globals.bReadbmpx = True;
657 Globals.bNullPasswords = False;
658 Globals.bStripDot = False;
660 Globals.bSyslogOnly = False;
661 Globals.os_level = 0;
662 Globals.max_ttl = 60*60*4; /* 2 hours default */
663 Globals.ReadSize = 16*1024;
664 Globals.shmem_size = SHMEM_SIZE;
665 Globals.shmem_hash_size = SHMEM_HASH_SIZE;
666 Globals.announce_as = ANNOUNCE_AS_NT;
667 Globals.bUnixRealname = False;
668 #if (defined(NETGROUP) && defined(AUTOMOUNT))
669 Globals.bNISHomeMap = False;
670 string_set(&Globals.szNISHomeMapName, "auto.home");
672 coding_system = interpret_coding_system (KANJI, SJIS_CODE);
673 Globals.client_code_page = DEFAULT_CLIENT_CODE_PAGE;
674 Globals.bTimeServer = False;
675 Globals.bBindInterfacesOnly = False;
677 /* these parameters are set to defaults that are more appropriate
678 for the increasing samba install base:
680 as a member of the workgroup, that will possibly become a
681 _local_ master browser (lm = True). this is opposed to a forced
682 local master browser startup (pm = True).
684 doesn't provide WINS server service by default (wsupp = False),
685 and doesn't provide domain master browser services by default, either.
689 Globals.bPreferredMaster = False;
690 Globals.bLocalMaster = True;
691 Globals.bDomainMaster = False;
692 Globals.bDomainLogons = False;
693 Globals.bBrowseList = True;
694 Globals.bWINSsupport = False;
695 Globals.bWINSproxy = False;
697 /* this parameter is currently set to the default functionality
698 in samba. given that w95 and NT is starting to use DNS for
699 server resolution, i expect that at some point it would be
700 sensible to default this to False.
702 this parameter is added because nmbd is a single process, and
703 gethostbyname is a blocking call, which can take out nmbd for
704 several seconds while a dns lookup is performed.
708 Globals.bDNSproxy = True;
711 /***************************************************************************
712 check if a string is initialised and if not then initialise it
713 ***************************************************************************/
714 static void string_initial(char **s,char *v)
721 /***************************************************************************
722 Initialise the sDefault parameter structure.
723 ***************************************************************************/
724 static void init_locals(void)
726 /* choose defaults depending on the type of printing */
727 switch (Globals.printing)
733 string_initial(&sDefault.szLpqcommand,"lpq -P%p");
734 string_initial(&sDefault.szLprmcommand,"lprm -P%p %j");
735 string_initial(&sDefault.szPrintcommand,"lpr -r -P%p %s");
740 string_initial(&sDefault.szLpqcommand,"lpstat -o%p");
741 string_initial(&sDefault.szLprmcommand,"cancel %p-%j");
742 string_initial(&sDefault.szPrintcommand,"lp -c -d%p %s; rm %s");
744 string_initial(&sDefault.szLppausecommand,"lp -i %p-%j -H hold");
745 string_initial(&sDefault.szLpresumecommand,"lp -i %p-%j -H resume");
750 string_initial(&sDefault.szLpqcommand,"lpq -P%p");
751 string_initial(&sDefault.szLprmcommand,"lprm -P%p %j");
752 string_initial(&sDefault.szPrintcommand,"lp -r -P%p %s");
760 /******************************************************************* a
761 convenience routine to grab string parameters into a rotating buffer,
762 and run standard_sub_basic on them. The buffers can be written to by
763 callers without affecting the source string.
764 ********************************************************************/
765 char *lp_string(char *s)
767 static char *bufs[10];
768 static int buflen[10];
769 static int next = -1;
772 int len = s?strlen(s):0;
783 len = MAX(len+100,sizeof(pstring)); /* the +100 is for some
786 if (buflen[next] != len) {
788 if (bufs[next]) free(bufs[next]);
789 bufs[next] = (char *)malloc(len);
791 DEBUG(0,("out of memory in lp_string()"));
796 ret = &bufs[next][0];
804 trim_string(ret, "\"", "\"");
806 standard_sub_basic(ret);
812 In this section all the functions that are used to access the
813 parameters from the rest of the program are defined
816 #define FN_GLOBAL_STRING(fn_name,ptr) \
817 char *fn_name(void) {return(lp_string(*(char **)(ptr) ? *(char **)(ptr) : ""));}
818 #define FN_GLOBAL_BOOL(fn_name,ptr) \
819 BOOL fn_name(void) {return(*(BOOL *)(ptr));}
820 #define FN_GLOBAL_CHAR(fn_name,ptr) \
821 char fn_name(void) {return(*(char *)(ptr));}
822 #define FN_GLOBAL_INTEGER(fn_name,ptr) \
823 int fn_name(void) {return(*(int *)(ptr));}
825 #define FN_LOCAL_STRING(fn_name,val) \
826 char *fn_name(int i) {return(lp_string((LP_SNUM_OK(i)&&pSERVICE(i)->val)?pSERVICE(i)->val : sDefault.val));}
827 #define FN_LOCAL_BOOL(fn_name,val) \
828 BOOL fn_name(int i) {return(LP_SNUM_OK(i)? pSERVICE(i)->val : sDefault.val);}
829 #define FN_LOCAL_CHAR(fn_name,val) \
830 char fn_name(int i) {return(LP_SNUM_OK(i)? pSERVICE(i)->val : sDefault.val);}
831 #define FN_LOCAL_INTEGER(fn_name,val) \
832 int fn_name(int i) {return(LP_SNUM_OK(i)? pSERVICE(i)->val : sDefault.val);}
834 FN_GLOBAL_STRING(lp_logfile,&Globals.szLogFile)
835 FN_GLOBAL_STRING(lp_smbrun,&Globals.szSmbrun)
836 FN_GLOBAL_STRING(lp_configfile,&Globals.szConfigFile)
837 FN_GLOBAL_STRING(lp_smb_passwd_file,&Globals.szSMBPasswdFile)
838 FN_GLOBAL_STRING(lp_serverstring,&Globals.szServerString)
839 FN_GLOBAL_STRING(lp_printcapname,&Globals.szPrintcapname)
840 FN_GLOBAL_STRING(lp_lockdir,&Globals.szLockDir)
841 FN_GLOBAL_STRING(lp_rootdir,&Globals.szRootdir)
842 FN_GLOBAL_STRING(lp_defaultservice,&Globals.szDefaultService)
843 FN_GLOBAL_STRING(lp_msg_command,&Globals.szMsgCommand)
844 FN_GLOBAL_STRING(lp_dfree_command,&Globals.szDfree)
845 FN_GLOBAL_STRING(lp_hosts_equiv,&Globals.szHostsEquiv)
846 FN_GLOBAL_STRING(lp_auto_services,&Globals.szAutoServices)
847 FN_GLOBAL_STRING(lp_passwd_program,&Globals.szPasswdProgram)
848 FN_GLOBAL_STRING(lp_passwd_chat,&Globals.szPasswdChat)
849 FN_GLOBAL_STRING(lp_passwordserver,&Globals.szPasswordServer)
850 FN_GLOBAL_STRING(lp_workgroup,&Globals.szWorkGroup)
851 FN_GLOBAL_STRING(lp_domain_controller,&Globals.szDomainController)
852 FN_GLOBAL_STRING(lp_username_map,&Globals.szUsernameMap)
853 FN_GLOBAL_STRING(lp_character_set,&Globals.szCharacterSet)
854 FN_GLOBAL_STRING(lp_logon_script,&Globals.szLogonScript)
855 FN_GLOBAL_STRING(lp_logon_path,&Globals.szLogonPath)
856 FN_GLOBAL_STRING(lp_logon_drive,&Globals.szLogonDrive)
857 FN_GLOBAL_STRING(lp_logon_home,&Globals.szLogonHome)
858 FN_GLOBAL_STRING(lp_remote_announce,&Globals.szRemoteAnnounce)
859 FN_GLOBAL_STRING(lp_wins_server,&Globals.szWINSserver)
860 FN_GLOBAL_STRING(lp_interfaces,&Globals.szInterfaces)
861 FN_GLOBAL_STRING(lp_socket_address,&Globals.szSocketAddress)
862 FN_GLOBAL_STRING(lp_nis_home_map_name,&Globals.szNISHomeMapName)
863 FN_GLOBAL_STRING(lp_announce_version,&Globals.szAnnounceVersion)
864 FN_GLOBAL_STRING(lp_netbios_aliases,&Globals.szNetbiosAliases)
866 FN_GLOBAL_STRING(lp_domainsid,&Globals.szDomainSID)
867 FN_GLOBAL_STRING(lp_domain_groups,&Globals.szDomainGroups)
869 FN_GLOBAL_BOOL(lp_dns_proxy,&Globals.bDNSproxy)
870 FN_GLOBAL_BOOL(lp_wins_support,&Globals.bWINSsupport)
871 FN_GLOBAL_BOOL(lp_wins_proxy,&Globals.bWINSproxy)
872 FN_GLOBAL_BOOL(lp_local_master,&Globals.bLocalMaster)
873 FN_GLOBAL_BOOL(lp_domain_master,&Globals.bDomainMaster)
874 FN_GLOBAL_BOOL(lp_domain_logons,&Globals.bDomainLogons)
875 FN_GLOBAL_BOOL(lp_preferred_master,&Globals.bPreferredMaster)
876 FN_GLOBAL_BOOL(lp_load_printers,&Globals.bLoadPrinters)
877 FN_GLOBAL_BOOL(lp_use_rhosts,&Globals.bUseRhosts)
878 FN_GLOBAL_BOOL(lp_getwdcache,&use_getwd_cache)
879 FN_GLOBAL_BOOL(lp_readprediction,&Globals.bReadPrediction)
880 FN_GLOBAL_BOOL(lp_readbmpx,&Globals.bReadbmpx)
881 FN_GLOBAL_BOOL(lp_readraw,&Globals.bReadRaw)
882 FN_GLOBAL_BOOL(lp_writeraw,&Globals.bWriteRaw)
883 FN_GLOBAL_BOOL(lp_null_passwords,&Globals.bNullPasswords)
884 FN_GLOBAL_BOOL(lp_strip_dot,&Globals.bStripDot)
885 FN_GLOBAL_BOOL(lp_encrypted_passwords,&Globals.bEncryptPasswords)
886 FN_GLOBAL_BOOL(lp_syslog_only,&Globals.bSyslogOnly)
887 FN_GLOBAL_BOOL(lp_browse_list,&Globals.bBrowseList)
888 FN_GLOBAL_BOOL(lp_unix_realname,&Globals.bUnixRealname)
889 FN_GLOBAL_BOOL(lp_nis_home_map,&Globals.bNISHomeMap)
890 FN_GLOBAL_BOOL(lp_time_server,&Globals.bTimeServer)
891 FN_GLOBAL_BOOL(lp_bind_interfaces_only,&Globals.bBindInterfacesOnly)
893 FN_GLOBAL_INTEGER(lp_os_level,&Globals.os_level)
894 FN_GLOBAL_INTEGER(lp_max_ttl,&Globals.max_ttl)
895 FN_GLOBAL_INTEGER(lp_max_log_size,&Globals.max_log_size)
896 FN_GLOBAL_INTEGER(lp_mangledstack,&Globals.mangled_stack)
897 FN_GLOBAL_INTEGER(lp_maxxmit,&Globals.max_xmit)
898 FN_GLOBAL_INTEGER(lp_maxmux,&Globals.max_mux)
899 FN_GLOBAL_INTEGER(lp_maxpacket,&Globals.max_packet)
900 FN_GLOBAL_INTEGER(lp_keepalive,&keepalive)
901 FN_GLOBAL_INTEGER(lp_passwordlevel,&Globals.pwordlevel)
902 FN_GLOBAL_INTEGER(lp_usernamelevel,&Globals.unamelevel)
903 FN_GLOBAL_INTEGER(lp_readsize,&Globals.ReadSize)
904 FN_GLOBAL_INTEGER(lp_shmem_size,&Globals.shmem_size)
905 FN_GLOBAL_INTEGER(lp_shmem_hash_size,&Globals.shmem_hash_size)
906 FN_GLOBAL_INTEGER(lp_deadtime,&Globals.deadtime)
907 FN_GLOBAL_INTEGER(lp_maxprotocol,&Globals.maxprotocol)
908 FN_GLOBAL_INTEGER(lp_security,&Globals.security)
909 FN_GLOBAL_INTEGER(lp_printing,&Globals.printing)
910 FN_GLOBAL_INTEGER(lp_maxdisksize,&Globals.maxdisksize)
911 FN_GLOBAL_INTEGER(lp_lpqcachetime,&Globals.lpqcachetime)
912 FN_GLOBAL_INTEGER(lp_syslog,&Globals.syslog)
913 FN_GLOBAL_INTEGER(lp_client_code_page,&Globals.client_code_page)
914 FN_GLOBAL_INTEGER(lp_announce_as,&Globals.announce_as)
916 FN_LOCAL_STRING(lp_preexec,szPreExec)
917 FN_LOCAL_STRING(lp_postexec,szPostExec)
918 FN_LOCAL_STRING(lp_rootpreexec,szRootPreExec)
919 FN_LOCAL_STRING(lp_rootpostexec,szRootPostExec)
920 FN_LOCAL_STRING(lp_servicename,szService)
921 FN_LOCAL_STRING(lp_pathname,szPath)
922 FN_LOCAL_STRING(lp_dontdescend,szDontdescend)
923 FN_LOCAL_STRING(lp_username,szUsername)
924 FN_LOCAL_STRING(lp_guestaccount,szGuestaccount)
925 FN_LOCAL_STRING(lp_invalid_users,szInvalidUsers)
926 FN_LOCAL_STRING(lp_valid_users,szValidUsers)
927 FN_LOCAL_STRING(lp_admin_users,szAdminUsers)
928 FN_LOCAL_STRING(lp_printcommand,szPrintcommand)
929 FN_LOCAL_STRING(lp_lpqcommand,szLpqcommand)
930 FN_LOCAL_STRING(lp_lprmcommand,szLprmcommand)
931 FN_LOCAL_STRING(lp_lppausecommand,szLppausecommand)
932 FN_LOCAL_STRING(lp_lpresumecommand,szLpresumecommand)
933 FN_LOCAL_STRING(lp_printername,szPrintername)
934 FN_LOCAL_STRING(lp_printerdriver,szPrinterDriver)
935 FN_LOCAL_STRING(lp_hostsallow,szHostsallow)
936 FN_LOCAL_STRING(lp_hostsdeny,szHostsdeny)
937 FN_LOCAL_STRING(lp_magicscript,szMagicScript)
938 FN_LOCAL_STRING(lp_magicoutput,szMagicOutput)
939 FN_LOCAL_STRING(lp_comment,comment)
940 FN_LOCAL_STRING(lp_force_user,force_user)
941 FN_LOCAL_STRING(lp_force_group,force_group)
942 FN_LOCAL_STRING(lp_readlist,readlist)
943 FN_LOCAL_STRING(lp_writelist,writelist)
944 FN_LOCAL_STRING(lp_volume,volume)
945 FN_LOCAL_STRING(lp_mangled_map,szMangledMap)
946 FN_LOCAL_STRING(lp_veto_files,szVetoFiles)
947 FN_LOCAL_STRING(lp_hide_files,szHideFiles)
949 FN_LOCAL_BOOL(lp_alternate_permissions,bAlternatePerm)
950 FN_LOCAL_BOOL(lp_revalidate,bRevalidate)
951 FN_LOCAL_BOOL(lp_casesensitive,bCaseSensitive)
952 FN_LOCAL_BOOL(lp_preservecase,bCasePreserve)
953 FN_LOCAL_BOOL(lp_shortpreservecase,bShortCasePreserve)
954 FN_LOCAL_BOOL(lp_casemangle,bCaseMangle)
955 FN_LOCAL_BOOL(lp_status,status)
956 FN_LOCAL_BOOL(lp_hide_dot_files,bHideDotFiles)
957 FN_LOCAL_BOOL(lp_browseable,bBrowseable)
958 FN_LOCAL_BOOL(lp_readonly,bRead_only)
959 FN_LOCAL_BOOL(lp_no_set_dir,bNo_set_dir)
960 FN_LOCAL_BOOL(lp_guest_ok,bGuest_ok)
961 FN_LOCAL_BOOL(lp_guest_only,bGuest_only)
962 FN_LOCAL_BOOL(lp_print_ok,bPrint_ok)
963 FN_LOCAL_BOOL(lp_postscript,bPostscript)
964 FN_LOCAL_BOOL(lp_map_hidden,bMap_hidden)
965 FN_LOCAL_BOOL(lp_map_archive,bMap_archive)
966 FN_LOCAL_BOOL(lp_locking,bLocking)
967 FN_LOCAL_BOOL(lp_strict_locking,bStrictLocking)
968 FN_LOCAL_BOOL(lp_share_modes,bShareModes)
969 FN_LOCAL_BOOL(lp_oplocks,bOpLocks)
970 FN_LOCAL_BOOL(lp_onlyuser,bOnlyUser)
971 FN_LOCAL_BOOL(lp_manglednames,bMangledNames)
972 FN_LOCAL_BOOL(lp_widelinks,bWidelinks)
973 FN_LOCAL_BOOL(lp_symlinks,bSymlinks)
974 FN_LOCAL_BOOL(lp_syncalways,bSyncAlways)
975 FN_LOCAL_BOOL(lp_map_system,bMap_system)
976 FN_LOCAL_BOOL(lp_delete_readonly,bDeleteReadonly)
977 FN_LOCAL_BOOL(lp_fake_oplocks,bFakeOplocks)
978 FN_LOCAL_BOOL(lp_recursive_veto_delete,bDeleteVetoFiles)
979 FN_LOCAL_BOOL(lp_dos_filetimes,bDosFiletimes)
981 FN_LOCAL_INTEGER(lp_create_mode,iCreate_mask)
982 FN_LOCAL_INTEGER(lp_force_create_mode,iCreate_force_mode)
983 FN_LOCAL_INTEGER(lp_dir_mode,iDir_mask)
984 FN_LOCAL_INTEGER(lp_force_dir_mode,iDir_force_mode)
985 FN_LOCAL_INTEGER(lp_max_connections,iMaxConnections)
986 FN_LOCAL_INTEGER(lp_defaultcase,iDefaultCase)
987 FN_LOCAL_INTEGER(lp_minprintspace,iMinPrintSpace)
989 FN_LOCAL_CHAR(lp_magicchar,magic_char)
993 /* local prototypes */
994 static int strwicmp( char *psz1, char *psz2 );
995 static int map_parameter( char *pszParmName);
996 static BOOL set_boolean( BOOL *pb, char *pszParmValue );
997 static int getservicebyname(char *pszServiceName, service *pserviceDest);
998 static void copy_service( service *pserviceDest,
999 service *pserviceSource,
1000 BOOL *pcopymapDest );
1001 static BOOL service_ok(int iService);
1002 static BOOL do_parameter(char *pszParmName, char *pszParmValue);
1003 static BOOL do_section(char *pszSectionName);
1004 static void init_copymap(service *pservice);
1007 /***************************************************************************
1008 initialise a service to the defaults
1009 ***************************************************************************/
1010 static void init_service(service *pservice)
1012 bzero((char *)pservice,sizeof(service));
1013 copy_service(pservice,&sDefault,NULL);
1017 /***************************************************************************
1018 free the dynamically allocated parts of a service struct
1019 ***************************************************************************/
1020 static void free_service(service *pservice)
1026 for (i=0;parm_table[i].label;i++)
1027 if ((parm_table[i].type == P_STRING ||
1028 parm_table[i].type == P_STRING) &&
1029 parm_table[i].class == P_LOCAL)
1030 string_free((char **)(((char *)pservice) + PTR_DIFF(parm_table[i].ptr,&sDefault)));
1033 /***************************************************************************
1034 add a new service to the services array initialising it with the given
1036 ***************************************************************************/
1037 static int add_a_service(service *pservice, char *name)
1041 int num_to_alloc = iNumServices+1;
1043 tservice = *pservice;
1045 /* it might already exist */
1048 i = getservicebyname(name,NULL);
1053 /* find an invalid one */
1054 for (i=0;i<iNumServices;i++)
1055 if (!pSERVICE(i)->valid)
1058 /* if not, then create one */
1059 if (i == iNumServices)
1061 ServicePtrs = (service **)Realloc(ServicePtrs,sizeof(service *)*num_to_alloc);
1063 pSERVICE(iNumServices) = (service *)malloc(sizeof(service));
1065 if (!ServicePtrs || !pSERVICE(iNumServices))
1071 free_service(pSERVICE(i));
1073 pSERVICE(i)->valid = True;
1075 init_service(pSERVICE(i));
1076 copy_service(pSERVICE(i),&tservice,NULL);
1078 string_set(&iSERVICE(i).szService,name);
1083 /***************************************************************************
1084 add a new home service, with the specified home directory, defaults coming
1086 ***************************************************************************/
1087 BOOL lp_add_home(char *pszHomename, int iDefaultService, char *pszHomedir)
1089 int i = add_a_service(pSERVICE(iDefaultService),pszHomename);
1094 if (!(*(iSERVICE(i).szPath)) || strequal(iSERVICE(i).szPath,lp_pathname(-1)))
1095 string_set(&iSERVICE(i).szPath,pszHomedir);
1096 if (!(*(iSERVICE(i).comment)))
1099 sprintf(comment,"Home directory of %s",pszHomename);
1100 string_set(&iSERVICE(i).comment,comment);
1102 iSERVICE(i).bAvailable = sDefault.bAvailable;
1103 iSERVICE(i).bBrowseable = sDefault.bBrowseable;
1105 DEBUG(3,("adding home directory %s at %s\n", pszHomename, pszHomedir));
1110 /***************************************************************************
1111 add a new service, based on an old one
1112 ***************************************************************************/
1113 int lp_add_service(char *pszService, int iDefaultService)
1115 return(add_a_service(pSERVICE(iDefaultService),pszService));
1119 /***************************************************************************
1121 ***************************************************************************/
1122 static BOOL lp_add_ipc(void)
1125 int i = add_a_service(&sDefault,"IPC$");
1130 sprintf(comment,"IPC Service (%s)",lp_serverstring());
1132 string_set(&iSERVICE(i).szPath,tmpdir());
1133 string_set(&iSERVICE(i).szUsername,"");
1134 string_set(&iSERVICE(i).comment,comment);
1135 iSERVICE(i).status = False;
1136 iSERVICE(i).iMaxConnections = 0;
1137 iSERVICE(i).bAvailable = True;
1138 iSERVICE(i).bRead_only = True;
1139 iSERVICE(i).bGuest_only = False;
1140 iSERVICE(i).bGuest_ok = True;
1141 iSERVICE(i).bPrint_ok = False;
1142 iSERVICE(i).bBrowseable = sDefault.bBrowseable;
1144 DEBUG(3,("adding IPC service\n"));
1150 /***************************************************************************
1151 add a new printer service, with defaults coming from service iFrom
1152 ***************************************************************************/
1153 BOOL lp_add_printer(char *pszPrintername, int iDefaultService)
1155 char *comment = "From Printcap";
1156 int i = add_a_service(pSERVICE(iDefaultService),pszPrintername);
1161 /* note that we do NOT default the availability flag to True - */
1162 /* we take it from the default service passed. This allows all */
1163 /* dynamic printers to be disabled by disabling the [printers] */
1164 /* entry (if/when the 'available' keyword is implemented!). */
1166 /* the printer name is set to the service name. */
1167 string_set(&iSERVICE(i).szPrintername,pszPrintername);
1168 string_set(&iSERVICE(i).comment,comment);
1169 iSERVICE(i).bBrowseable = sDefault.bBrowseable;
1170 /* Printers cannot be read_only. */
1171 iSERVICE(i).bRead_only = False;
1172 /* No share modes on printer services. */
1173 iSERVICE(i).bShareModes = False;
1174 /* No oplocks on printer services. */
1175 iSERVICE(i).bOpLocks = False;
1176 /* Printer services must be printable. */
1177 iSERVICE(i).bPrint_ok = True;
1179 DEBUG(3,("adding printer service %s\n",pszPrintername));
1185 /***************************************************************************
1186 Do a case-insensitive, whitespace-ignoring string compare.
1187 ***************************************************************************/
1188 static int strwicmp(char *psz1, char *psz2)
1190 /* if BOTH strings are NULL, return TRUE, if ONE is NULL return */
1191 /* appropriate value. */
1201 /* sync the strings on first non-whitespace */
1204 while (isspace(*psz1))
1206 while (isspace(*psz2))
1208 if (toupper(*psz1) != toupper(*psz2) || *psz1 == '\0' || *psz2 == '\0')
1213 return (*psz1 - *psz2);
1216 /***************************************************************************
1217 Map a parameter's string representation to something we can use.
1218 Returns False if the parameter string is not recognised, else TRUE.
1219 ***************************************************************************/
1220 static int map_parameter(char *pszParmName)
1224 if (*pszParmName == '-')
1227 for (iIndex = 0; parm_table[iIndex].label; iIndex++)
1228 if (strwicmp(parm_table[iIndex].label, pszParmName) == 0)
1231 DEBUG(0,( "Unknown parameter encountered: \"%s\"\n", pszParmName));
1236 /***************************************************************************
1237 Set a boolean variable from the text value stored in the passed string.
1238 Returns True in success, False if the passed string does not correctly
1239 represent a boolean.
1240 ***************************************************************************/
1241 static BOOL set_boolean(BOOL *pb, char *pszParmValue)
1246 if (strwicmp(pszParmValue, "yes") == 0 ||
1247 strwicmp(pszParmValue, "true") == 0 ||
1248 strwicmp(pszParmValue, "1") == 0)
1251 if (strwicmp(pszParmValue, "no") == 0 ||
1252 strwicmp(pszParmValue, "False") == 0 ||
1253 strwicmp(pszParmValue, "0") == 0)
1257 DEBUG(0,( "Badly formed boolean in configuration file: \"%s\".\n",
1264 /***************************************************************************
1265 Find a service by name. Otherwise works like get_service.
1266 ***************************************************************************/
1267 static int getservicebyname(char *pszServiceName, service *pserviceDest)
1271 for (iService = iNumServices - 1; iService >= 0; iService--)
1272 if (VALID(iService) &&
1273 strwicmp(iSERVICE(iService).szService, pszServiceName) == 0)
1275 if (pserviceDest != NULL)
1276 copy_service(pserviceDest, pSERVICE(iService), NULL);
1285 /***************************************************************************
1286 Copy a service structure to another
1288 If pcopymapDest is NULL then copy all fields
1289 ***************************************************************************/
1290 static void copy_service(service *pserviceDest,
1291 service *pserviceSource,
1295 BOOL bcopyall = (pcopymapDest == NULL);
1297 for (i=0;parm_table[i].label;i++)
1298 if (parm_table[i].ptr && parm_table[i].class == P_LOCAL &&
1299 (bcopyall || pcopymapDest[i]))
1301 void *def_ptr = parm_table[i].ptr;
1303 ((char *)pserviceSource) + PTR_DIFF(def_ptr,&sDefault);
1305 ((char *)pserviceDest) + PTR_DIFF(def_ptr,&sDefault);
1307 switch (parm_table[i].type)
1311 *(BOOL *)dest_ptr = *(BOOL *)src_ptr;
1316 *(int *)dest_ptr = *(int *)src_ptr;
1320 *(char *)dest_ptr = *(char *)src_ptr;
1324 string_set(dest_ptr,*(char **)src_ptr);
1328 string_set(dest_ptr,*(char **)src_ptr);
1329 strupper(*(char **)dest_ptr);
1338 init_copymap(pserviceDest);
1339 if (pserviceSource->copymap)
1340 memcpy((void *)pserviceDest->copymap,
1341 (void *)pserviceSource->copymap,sizeof(BOOL)*NUMPARAMETERS);
1345 /***************************************************************************
1346 Check a service for consistency. Return False if the service is in any way
1347 incomplete or faulty, else True.
1348 ***************************************************************************/
1349 static BOOL service_ok(int iService)
1354 if (iSERVICE(iService).szService[0] == '\0')
1356 DEBUG(0,( "The following message indicates an internal error:\n"));
1357 DEBUG(0,( "No service name in service entry.\n"));
1361 /* The [printers] entry MUST be printable. I'm all for flexibility, but */
1362 /* I can't see why you'd want a non-printable printer service... */
1363 if (strwicmp(iSERVICE(iService).szService,PRINTERS_NAME) == 0)
1364 if (!iSERVICE(iService).bPrint_ok)
1366 DEBUG(0,( "WARNING: [%s] service MUST be printable!\n",
1367 iSERVICE(iService).szService));
1368 iSERVICE(iService).bPrint_ok = True;
1371 if (iSERVICE(iService).szPath[0] == '\0' &&
1372 strwicmp(iSERVICE(iService).szService,HOMES_NAME) != 0)
1374 DEBUG(0,("No path in service %s - using %s\n",iSERVICE(iService).szService,tmpdir()));
1375 string_set(&iSERVICE(iService).szPath,tmpdir());
1378 /* If a service is flagged unavailable, log the fact at level 0. */
1379 if (!iSERVICE(iService).bAvailable)
1380 DEBUG(1,( "NOTE: Service %s is flagged unavailable.\n",
1381 iSERVICE(iService).szService));
1386 static struct file_lists {
1387 struct file_lists *next;
1390 } *file_lists = NULL;
1392 /*******************************************************************
1393 keep a linked list of all config files so we know when one has changed
1394 it's date and needs to be reloaded
1395 ********************************************************************/
1396 static void add_to_file_list(char *fname)
1398 struct file_lists *f=file_lists;
1401 if (f->name && !strcmp(f->name,fname)) break;
1406 f = (struct file_lists *)malloc(sizeof(file_lists[0]));
1408 f->next = file_lists;
1409 f->name = strdup(fname);
1420 standard_sub_basic(n2);
1421 f->modtime = file_modtime(n2);
1426 /*******************************************************************
1427 check if a config file has changed date
1428 ********************************************************************/
1429 BOOL lp_file_list_changed(void)
1431 struct file_lists *f = file_lists;
1432 DEBUG(6,("lp_file_list_changed()\n"));
1439 pstrcpy(n2,f->name);
1440 standard_sub_basic(n2);
1442 DEBUG(6,("file %s -> %s last mod_time: %s\n",
1443 f->name, n2, ctime(&f->modtime)));
1445 mod_time = file_modtime(n2);
1447 if (f->modtime != mod_time) {
1448 DEBUG(6,("file %s modified: %s\n", n2, ctime(&mod_time)));
1449 f->modtime = mod_time;
1457 /***************************************************************************
1458 handle the interpretation of the coding system parameter
1459 *************************************************************************/
1460 static BOOL handle_coding_system(char *pszParmValue,int *val)
1462 *val = interpret_coding_system(pszParmValue,*val);
1466 /***************************************************************************
1467 handle the interpretation of the character set system parameter
1468 ***************************************************************************/
1469 static BOOL handle_character_set(char *pszParmValue,int *val)
1471 string_set(&Globals.szCharacterSet,pszParmValue);
1472 *val = interpret_character_set(pszParmValue,*val);
1477 /***************************************************************************
1478 handle the interpretation of the protocol parameter
1479 ***************************************************************************/
1480 static BOOL handle_protocol(char *pszParmValue,int *val)
1482 *val = interpret_protocol(pszParmValue,*val);
1486 /***************************************************************************
1487 handle the interpretation of the security parameter
1488 ***************************************************************************/
1489 static BOOL handle_security(char *pszParmValue,int *val)
1491 *val = interpret_security(pszParmValue,*val);
1495 /***************************************************************************
1496 handle the interpretation of the default case
1497 ***************************************************************************/
1498 static BOOL handle_case(char *pszParmValue,int *val)
1500 if (strnequal(pszParmValue,"LOWER", 5))
1502 else if (strnequal(pszParmValue,"UPPER", 5))
1507 /***************************************************************************
1508 handle the interpretation of the printing system
1509 ***************************************************************************/
1510 static BOOL handle_printing(char *pszParmValue,int *val)
1512 if (strnequal(pszParmValue,"sysv", 4))
1514 else if (strnequal(pszParmValue,"aix", 3))
1516 else if (strnequal(pszParmValue,"hpux", 4))
1518 else if (strnequal(pszParmValue,"bsd", 3))
1520 else if (strnequal(pszParmValue,"qnx",3))
1522 else if (strnequal(pszParmValue,"plp", 3))
1524 else if (strnequal(pszParmValue,"lprng", 5))
1529 /***************************************************************************
1530 handle the announce as parameter
1531 ***************************************************************************/
1532 static BOOL handle_announce_as(char *pszParmValue,int *val)
1534 if (strnequal(pszParmValue,"NT", 2))
1535 *val = ANNOUNCE_AS_NT;
1536 else if (strnequal(pszParmValue,"win95", 5))
1537 *val = ANNOUNCE_AS_WIN95;
1538 else if (strnequal(pszParmValue,"WfW", 3))
1539 *val = ANNOUNCE_AS_WFW;
1543 /***************************************************************************
1544 handle the valid chars lines
1545 ***************************************************************************/
1546 static BOOL handle_valid_chars(char *pszParmValue,char **ptr)
1548 string_set(ptr,pszParmValue);
1550 /* A dependency here is that the parameter client code page must be
1551 set before this is called - as calling codepage_initialise()
1552 would overwrite the valid char lines.
1554 codepage_initialise(lp_client_code_page());
1556 add_char_string(pszParmValue);
1561 /***************************************************************************
1562 handle the include operation
1563 ***************************************************************************/
1564 static BOOL handle_include(char *pszParmValue,char **ptr)
1567 pstrcpy(fname,pszParmValue);
1569 add_to_file_list(fname);
1571 standard_sub_basic(fname);
1573 string_set(ptr,fname);
1575 if (file_exist(fname,NULL))
1576 return(pm_process(fname, do_section, do_parameter));
1578 DEBUG(2,("Can't find include file %s\n",fname));
1584 /***************************************************************************
1585 handle the interpretation of the copy parameter
1586 ***************************************************************************/
1587 static BOOL handle_copy(char *pszParmValue,char **ptr)
1591 service serviceTemp;
1593 string_set(ptr,pszParmValue);
1595 init_service(&serviceTemp);
1599 DEBUG(3,("Copying service from service %s\n",pszParmValue));
1601 if ((iTemp = getservicebyname(pszParmValue, &serviceTemp)) >= 0)
1603 if (iTemp == iServiceIndex)
1605 DEBUG(0,("Can't copy service %s - unable to copy self!\n",
1610 copy_service(pSERVICE(iServiceIndex),
1612 iSERVICE(iServiceIndex).copymap);
1618 DEBUG(0,( "Unable to copy service - source not found: %s\n",
1623 free_service(&serviceTemp);
1628 /***************************************************************************
1629 initialise a copymap
1630 ***************************************************************************/
1631 static void init_copymap(service *pservice)
1634 if (pservice->copymap) free(pservice->copymap);
1635 pservice->copymap = (BOOL *)malloc(sizeof(BOOL)*NUMPARAMETERS);
1636 if (!pservice->copymap)
1637 DEBUG(0,("Couldn't allocate copymap!! (size %d)\n",NUMPARAMETERS));
1639 for (i=0;i<NUMPARAMETERS;i++)
1640 pservice->copymap[i] = True;
1644 /***************************************************************************
1645 Process a parameter for a particular service number. If snum < 0
1646 then assume we are in the globals
1647 ***************************************************************************/
1648 BOOL lp_do_parameter(int snum, char *pszParmName, char *pszParmValue)
1651 void *parm_ptr=NULL; /* where we are going to store the result */
1654 parmnum = map_parameter(pszParmName);
1658 DEBUG(0,( "Ignoring unknown parameter \"%s\"\n", pszParmName));
1662 def_ptr = parm_table[parmnum].ptr;
1664 /* we might point at a service, the default service or a global */
1668 if (parm_table[parmnum].class == P_GLOBAL) {
1669 DEBUG(0,( "Global parameter %s found in service section!\n",pszParmName));
1672 parm_ptr = ((char *)pSERVICE(snum)) + PTR_DIFF(def_ptr,&sDefault);
1677 if (!iSERVICE(snum).copymap)
1678 init_copymap(pSERVICE(snum));
1680 /* this handles the aliases - set the copymap for other entries with
1681 the same data pointer */
1682 for (i=0;parm_table[i].label;i++)
1683 if (parm_table[i].ptr == parm_table[parmnum].ptr)
1684 iSERVICE(snum).copymap[i] = False;
1687 /* if it is a special case then go ahead */
1688 if (parm_table[parmnum].special) {
1689 parm_table[parmnum].special(pszParmValue,parm_ptr);
1693 /* now switch on the type of variable it is */
1694 switch (parm_table[parmnum].type)
1697 set_boolean(parm_ptr,pszParmValue);
1701 set_boolean(parm_ptr,pszParmValue);
1702 *(BOOL *)parm_ptr = ! *(BOOL *)parm_ptr;
1706 *(int *)parm_ptr = atoi(pszParmValue);
1710 *(char *)parm_ptr = *pszParmValue;
1714 sscanf(pszParmValue,"%o",(int *)parm_ptr);
1718 string_set(parm_ptr,pszParmValue);
1722 string_set(parm_ptr,pszParmValue);
1723 strupper(*(char **)parm_ptr);
1727 strcpy((char *)parm_ptr,pszParmValue);
1731 strcpy((char *)parm_ptr,pszParmValue);
1732 strupper((char *)parm_ptr);
1739 /***************************************************************************
1740 Process a parameter.
1741 ***************************************************************************/
1742 static BOOL do_parameter(char *pszParmName, char *pszParmValue)
1744 if (!bInGlobalSection && bGlobalOnly) return(True);
1746 DEBUG(3,("doing parameter %s = %s\n",pszParmName,pszParmValue));
1748 return lp_do_parameter(bInGlobalSection?-2:iServiceIndex, pszParmName, pszParmValue);
1752 /***************************************************************************
1753 print a parameter of the specified type
1754 ***************************************************************************/
1755 static void print_parameter(parm_type type,void *ptr, FILE *f)
1760 fprintf(f,"%s",BOOLSTR(*(BOOL *)ptr));
1764 fprintf(f,"%s",BOOLSTR(! *(BOOL *)ptr));
1768 fprintf(f,"%d",*(int *)ptr);
1772 fprintf(f,"%c",*(char *)ptr);
1776 fprintf(f,"0%o",*(int *)ptr);
1782 fprintf(f,"%s",(char *)ptr);
1788 fprintf(f,"%s",*(char **)ptr);
1794 /***************************************************************************
1795 print a parameter of the specified type
1796 ***************************************************************************/
1797 static void parameter_string(parm_type type,void *ptr,char *s)
1804 sprintf(s, "%s",BOOLSTR(*(BOOL *)ptr));
1808 sprintf(s, "%s",BOOLSTR(! *(BOOL *)ptr));
1812 sprintf(s, "%d",*(int *)ptr);
1816 sprintf(s, "%c",*(char *)ptr);
1820 sprintf(s, "0%o",*(int *)ptr);
1826 sprintf(s, "%s",(char *)ptr);
1832 sprintf(s, "%s",*(char **)ptr);
1838 /***************************************************************************
1839 check if two parameters are equal
1840 ***************************************************************************/
1841 static BOOL equal_parameter(parm_type type,void *ptr1,void *ptr2)
1847 return(*((BOOL *)ptr1) == *((BOOL *)ptr2));
1851 return(*((int *)ptr1) == *((int *)ptr2));
1854 return(*((char *)ptr1) == *((char *)ptr2));
1859 char *p1 = (char *)ptr1, *p2 = (char *)ptr2;
1860 if (p1 && !*p1) p1 = NULL;
1861 if (p2 && !*p2) p2 = NULL;
1862 return(p1==p2 || strequal(p1,p2));
1867 char *p1 = *(char **)ptr1, *p2 = *(char **)ptr2;
1868 if (p1 && !*p1) p1 = NULL;
1869 if (p2 && !*p2) p2 = NULL;
1870 return(p1==p2 || strequal(p1,p2));
1876 /***************************************************************************
1877 Process a new section (service). At this stage all sections are services.
1878 Later we'll have special sections that permit server parameters to be set.
1879 Returns True on success, False on failure.
1880 ***************************************************************************/
1881 static BOOL do_section(char *pszSectionName)
1884 BOOL isglobal = ((strwicmp(pszSectionName, GLOBAL_NAME) == 0) ||
1885 (strwicmp(pszSectionName, GLOBAL_NAME2) == 0));
1888 /* if we were in a global section then do the local inits */
1889 if (bInGlobalSection && !isglobal)
1892 /* if we've just struck a global section, note the fact. */
1893 bInGlobalSection = isglobal;
1895 /* check for multiple global sections */
1896 if (bInGlobalSection)
1898 DEBUG(3,( "Processing section \"[%s]\"\n", pszSectionName));
1902 if (!bInGlobalSection && bGlobalOnly) return(True);
1904 /* if we have a current service, tidy it up before moving on */
1907 if (iServiceIndex >= 0)
1908 bRetval = service_ok(iServiceIndex);
1910 /* if all is still well, move to the next record in the services array */
1913 /* We put this here to avoid an odd message order if messages are */
1914 /* issued by the post-processing of a previous section. */
1915 DEBUG(2,( "Processing section \"[%s]\"\n", pszSectionName));
1917 if ((iServiceIndex=add_a_service(&sDefault,pszSectionName)) < 0)
1919 DEBUG(0,("Failed to add a new service\n"));
1927 /***************************************************************************
1928 Display the contents of the global structure.
1929 ***************************************************************************/
1930 static void dump_globals(FILE *f)
1933 fprintf(f, "# Global parameters\n");
1935 for (i=0;parm_table[i].label;i++)
1936 if (parm_table[i].class == P_GLOBAL &&
1937 parm_table[i].ptr &&
1938 (i == 0 || (parm_table[i].ptr != parm_table[i-1].ptr)))
1940 fprintf(f,"\t%s = ",parm_table[i].label);
1941 print_parameter(parm_table[i].type,parm_table[i].ptr, f);
1946 /***************************************************************************
1947 Display the contents of a single services record.
1948 ***************************************************************************/
1949 static void dump_a_service(service *pService, FILE *f)
1952 if (pService == &sDefault)
1953 fprintf(f,"\n\n# Default service parameters\n");
1955 fprintf(f,"\n[%s]\n",pService->szService);
1957 for (i=0;parm_table[i].label;i++)
1958 if (parm_table[i].class == P_LOCAL &&
1959 parm_table[i].ptr &&
1960 (*parm_table[i].label != '-') &&
1961 (i == 0 || (parm_table[i].ptr != parm_table[i-1].ptr)))
1963 int pdiff = PTR_DIFF(parm_table[i].ptr,&sDefault);
1965 if (pService == &sDefault || !equal_parameter(parm_table[i].type,
1966 ((char *)pService) + pdiff,
1967 ((char *)&sDefault) + pdiff))
1969 fprintf(f,"\t%s = ",parm_table[i].label);
1970 print_parameter(parm_table[i].type,
1971 ((char *)pService) + pdiff, f);
1978 /***************************************************************************
1979 return info about the next service in a service. snum==-1 gives the default
1980 serice and snum==-2 gives the globals
1982 return 0 when out of parameters
1983 ***************************************************************************/
1984 int lp_next_parameter(int snum, int *i, char *label,
1985 char *value, int allparameters)
1988 /* do the globals */
1989 for (;parm_table[*i].label;(*i)++)
1990 if (parm_table[*i].class == P_GLOBAL &&
1991 parm_table[*i].ptr &&
1992 (*parm_table[*i].label != '-') &&
1994 (parm_table[*i].ptr != parm_table[(*i)-1].ptr))) {
1995 strcpy(label, parm_table[*i].label);
1996 parameter_string(parm_table[*i].type,
2004 service *pService = (snum==-1?&sDefault:pSERVICE(snum));
2006 for (;parm_table[*i].label;(*i)++)
2007 if (parm_table[*i].class == P_LOCAL &&
2008 parm_table[*i].ptr &&
2009 (*parm_table[*i].label != '-') &&
2011 (parm_table[*i].ptr != parm_table[(*i)-1].ptr))) {
2012 int pdiff = PTR_DIFF(parm_table[*i].ptr,&sDefault);
2014 if (snum == -1 || allparameters ||
2015 !equal_parameter(parm_table[*i].type,
2016 ((char *)pService) + pdiff,
2017 ((char *)&sDefault) + pdiff)) {
2018 strcpy(label, parm_table[*i].label);
2019 parameter_string(parm_table[*i].type,
2020 ((char *)pService) + pdiff,
2033 /***************************************************************************
2034 Display the contents of a single copy structure.
2035 ***************************************************************************/
2036 static void dump_copy_map(BOOL *pcopymap)
2039 if (!pcopymap) return;
2041 printf("\n\tNon-Copied parameters:\n");
2043 for (i=0;parm_table[i].label;i++)
2044 if (parm_table[i].class == P_LOCAL &&
2045 parm_table[i].ptr && !pcopymap[i] &&
2046 (i == 0 || (parm_table[i].ptr != parm_table[i-1].ptr)))
2048 printf("\t\t%s\n",parm_table[i].label);
2053 /***************************************************************************
2054 Return TRUE if the passed service number is within range.
2055 ***************************************************************************/
2056 BOOL lp_snum_ok(int iService)
2058 return (LP_SNUM_OK(iService) && iSERVICE(iService).bAvailable);
2062 /***************************************************************************
2063 auto-load some homes and printer services
2064 ***************************************************************************/
2065 static void lp_add_auto_services(char *str)
2069 int homes = lp_servicenumber(HOMES_NAME);
2070 int printers = lp_servicenumber(PRINTERS_NAME);
2078 for (p=strtok(s,LIST_SEP);p;p=strtok(NULL,LIST_SEP))
2080 char *home = get_home_dir(p);
2082 if (lp_servicenumber(p) >= 0) continue;
2084 if (home && homes >= 0)
2086 lp_add_home(p,homes,home);
2090 if (printers >= 0 && pcap_printername_ok(p,NULL))
2091 lp_add_printer(p,printers);
2096 /***************************************************************************
2097 auto-load one printer
2098 ***************************************************************************/
2099 static void lp_add_one_printer(char *name,char *comment)
2101 int printers = lp_servicenumber(PRINTERS_NAME);
2104 if (lp_servicenumber(name) < 0)
2106 lp_add_printer(name,printers);
2107 if ((i=lp_servicenumber(name)) >= 0)
2108 string_set(&iSERVICE(i).comment,comment);
2113 /***************************************************************************
2114 auto-load printer services
2115 ***************************************************************************/
2116 static void lp_add_all_printers(void)
2118 int printers = lp_servicenumber(PRINTERS_NAME);
2120 if (printers < 0) return;
2122 pcap_printer_fn(lp_add_one_printer);
2125 /***************************************************************************
2126 have we loaded a services file yet?
2127 ***************************************************************************/
2128 BOOL lp_loaded(void)
2133 /***************************************************************************
2134 unload unused services
2135 ***************************************************************************/
2136 void lp_killunused(BOOL (*snumused)(int ))
2139 for (i=0;i<iNumServices;i++)
2140 if (VALID(i) && (!snumused || !snumused(i)))
2142 iSERVICE(i).valid = False;
2143 free_service(pSERVICE(i));
2147 /***************************************************************************
2148 Load the services array from the services file. Return True on success,
2150 ***************************************************************************/
2151 BOOL lp_load(char *pszFname,BOOL global_only)
2156 add_to_file_list(pszFname);
2160 bInGlobalSection = True;
2161 bGlobalOnly = global_only;
2165 pstrcpy(n2,pszFname);
2166 standard_sub_basic(n2);
2168 /* We get sections first, so have to start 'behind' to make up */
2170 bRetval = pm_process(n2, do_section, do_parameter);
2172 /* finish up the last section */
2173 DEBUG(3,("pm_process() returned %s\n", BOOLSTR(bRetval)));
2175 if (iServiceIndex >= 0)
2176 bRetval = service_ok(iServiceIndex);
2178 lp_add_auto_services(lp_auto_services());
2179 if (lp_load_printers())
2180 lp_add_all_printers();
2184 set_default_server_announce_type();
2192 /***************************************************************************
2193 return the max number of services
2194 ***************************************************************************/
2195 int lp_numservices(void)
2197 return(iNumServices);
2200 /***************************************************************************
2201 Display the contents of the services array in human-readable form.
2202 ***************************************************************************/
2203 void lp_dump(FILE *f)
2209 dump_a_service(&sDefault, f);
2211 for (iService = 0; iService < iNumServices; iService++)
2213 if (VALID(iService))
2215 if (iSERVICE(iService).szService[0] == '\0')
2217 dump_a_service(pSERVICE(iService), f);
2223 /***************************************************************************
2224 Return the number of the service with the given name, or -1 if it doesn't
2225 exist. Note that this is a DIFFERENT ANIMAL from the internal function
2226 getservicebyname()! This works ONLY if all services have been loaded, and
2227 does not copy the found service.
2228 ***************************************************************************/
2229 int lp_servicenumber(char *pszServiceName)
2233 for (iService = iNumServices - 1; iService >= 0; iService--)
2234 if (VALID(iService) &&
2235 strwicmp(iSERVICE(iService).szService, pszServiceName) == 0)
2239 DEBUG(7,("lp_servicenumber: couldn't find %s\n",pszServiceName));
2244 /*******************************************************************
2245 a useful volume label function
2246 ******************************************************************/
2247 char *volume_label(int snum)
2249 char *ret = lp_volume(snum);
2250 if (!*ret) return(lp_servicename(snum));
2256 * nmbd only loads the global section. There seems to be no way to
2257 * determine exactly is a service is printable by only looking at the
2258 * [global] section so for now always announce as a print server. This
2259 * will need looking at in the future. Jeremy (jallison@whistle.com).
2261 /*******************************************************************
2262 Return true if any printer services are defined.
2263 ******************************************************************/
2264 static BOOL lp_printer_services(void)
2268 for (iService = iNumServices - 1; iService >= 0; iService--)
2269 if (VALID(iService) && iSERVICE(iService).bPrint_ok)
2275 /*******************************************************************
2276 Set the server type we will announce as via nmbd.
2277 ********************************************************************/
2278 static void set_default_server_announce_type()
2280 default_server_announce = (SV_TYPE_WORKSTATION | SV_TYPE_SERVER |
2281 SV_TYPE_SERVER_UNIX | SV_TYPE_PRINTQ_SERVER);
2282 if(lp_announce_as() == ANNOUNCE_AS_NT)
2283 default_server_announce |= (SV_TYPE_SERVER_NT | SV_TYPE_NT);
2284 else if(lp_announce_as() == ANNOUNCE_AS_WIN95)
2285 default_server_announce |= SV_TYPE_WIN95_PLUS;
2286 else if(lp_announce_as() == ANNOUNCE_AS_WFW)
2287 default_server_announce |= SV_TYPE_WFW;
2288 default_server_announce |= (lp_time_server() ? SV_TYPE_TIME_SOURCE : 0);
2290 * nmbd only loads the [global] section. There seems to be no way to
2291 * determine exactly if any service is printable by only looking at the
2292 * [global] section so for now always announce as a print server. This
2293 * will need looking at in the future. Jeremy (jallison@whistle.com).
2296 default_server_announce |= (lp_printer_services() ? SV_TYPE_PRINTQ_SERVER : 0);
2301 /*******************************************************************
2303 ********************************************************************/
2304 void lp_rename_service(int snum, char *new_name)
2306 string_set(&pSERVICE(snum)->szService, new_name);
2309 /*******************************************************************
2311 ********************************************************************/
2312 void lp_remove_service(int snum)
2314 pSERVICE(snum)->valid = False;
2317 /*******************************************************************
2319 ********************************************************************/
2320 void lp_copy_service(int snum, char *new_name)
2322 char *oldname = lp_servicename(snum);
2323 do_section(new_name);
2325 snum = lp_servicenumber(new_name);
2327 lp_do_parameter(snum, "copy", oldname);
2332 /*******************************************************************
2333 Get the default server type we will announce as via nmbd.
2334 ********************************************************************/
2335 int lp_default_server_announce(void)
2337 return default_server_announce;
2340 /*******************************************************************
2341 Split the announce version into major and minor numbers.
2342 ********************************************************************/
2343 int lp_major_announce_version(void)
2345 static BOOL got_major = False;
2346 static int major_version = DEFAULT_MAJOR_VERSION;
2351 return major_version;
2354 if((vers = lp_announce_version()) == NULL)
2355 return major_version;
2357 if((p = strchr(vers, '.')) == 0)
2358 return major_version;
2361 major_version = atoi(vers);
2362 return major_version;
2365 int lp_minor_announce_version(void)
2367 static BOOL got_minor = False;
2368 static int minor_version = DEFAULT_MINOR_VERSION;
2373 return minor_version;
2376 if((vers = lp_announce_version()) == NULL)
2377 return minor_version;
2379 if((p = strchr(vers, '.')) == 0)
2380 return minor_version;
2383 minor_version = atoi(p);
2384 return minor_version;