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;
138 char *szRemoteAnnounce;
139 char *szSocketAddress;
140 char *szNISHomeMapName;
141 char *szAnnounceVersion; /* This is initialised in init_globals */
142 char *szNetbiosAliases;
162 int client_code_page;
163 int announce_as; /* This is initialised in init_globals */
168 BOOL bPreferredMaster;
171 BOOL bEncryptPasswords;
178 BOOL bReadPrediction;
187 static global Globals;
192 * This structure describes a single service.
200 char *szGuestaccount;
201 char *szInvalidUsers;
209 char *szRootPostExec;
210 char *szPrintcommand;
213 char *szLppausecommand;
214 char *szLpresumecommand;
216 char *szPrinterDriver;
233 int iCreate_force_mode;
242 BOOL bShortCasePreserve;
267 BOOL bDeleteReadonly;
269 BOOL bDeleteVetoFiles;
270 char dummy[3]; /* for alignment */
274 /* This is a default service used to prime a services structure */
275 static service sDefault =
278 NULL, /* szService */
280 NULL, /* szUsername */
281 NULL, /* szGuestAccount - this is set in init_globals() */
282 NULL, /* szInvalidUsers */
283 NULL, /* szValidUsers */
284 NULL, /* szAdminUsers */
286 NULL, /* szInclude */
287 NULL, /* szPreExec */
288 NULL, /* szPostExec */
289 NULL, /* szRootPreExec */
290 NULL, /* szRootPostExec */
291 NULL, /* szPrintcommand */
292 NULL, /* szLpqcommand */
293 NULL, /* szLprmcommand */
294 NULL, /* szLppausecommand */
295 NULL, /* szLpresumecommand */
296 NULL, /* szPrintername */
297 NULL, /* szPrinterDriver - this is set in init_globals() */
298 NULL, /* szDontdescend */
299 NULL, /* szHostsallow */
300 NULL, /* szHostsdeny */
301 NULL, /* szMagicScript */
302 NULL, /* szMagicOutput */
303 NULL, /* szMangledMap */
304 NULL, /* szVetoFiles */
305 NULL, /* szHideFiles */
307 NULL, /* force user */
308 NULL, /* force group */
310 NULL, /* writelist */
312 0, /* iMinPrintSpace */
313 0744, /* iCreate_mask */
314 0000, /* iCreate_force_mode */
315 0755, /* iDir_mask */
316 0000, /* iDir_force_mode */
317 0, /* iMaxConnections */
318 CASE_LOWER, /* iDefaultCase */
319 False, /* bAlternatePerm */
320 False, /* revalidate */
321 False, /* case sensitive */
322 False, /* case preserve */
323 False, /* short case preserve */
324 False, /* case mangle */
326 True, /* bHideDotFiles */
327 True, /* bBrowseable */
328 True, /* bAvailable */
329 True, /* bRead_only */
330 True, /* bNo_set_dir */
331 False, /* bGuest_only */
332 False, /* bGuest_ok */
333 False, /* bPrint_ok */
334 False, /* bPostscript */
335 False, /* bMap_system */
336 False, /* bMap_hidden */
337 True, /* bMap_archive */
339 False, /* bStrictLocking */
340 True, /* bShareModes */
341 False, /* bOnlyUser */
342 True, /* bMangledNames */
343 True, /* bWidelinks */
344 True, /* bSymlinks */
345 False, /* bSyncAlways */
346 '~', /* magic char */
348 False, /* bDeleteReadonly */
349 False, /* bFakeOplocks */
350 False, /* bDeleteVetoFiles */
356 /* local variables */
357 static service **ServicePtrs = NULL;
358 static int iNumServices = 0;
359 static int iServiceIndex = 0;
360 static BOOL bInGlobalSection = True;
361 static BOOL bGlobalOnly = False;
362 static int default_server_announce;
364 #define NUMPARAMETERS (sizeof(parm_table) / sizeof(struct parm_struct))
366 /* prototypes for the special type handlers */
367 static BOOL handle_valid_chars(char *pszParmValue, char **ptr);
368 static BOOL handle_include(char *pszParmValue, char **ptr);
369 static BOOL handle_copy(char *pszParmValue, char **ptr);
370 static BOOL handle_protocol(char *pszParmValue,int *val);
371 static BOOL handle_security(char *pszParmValue,int *val);
372 static BOOL handle_case(char *pszParmValue,int *val);
373 static BOOL handle_printing(char *pszParmValue,int *val);
374 static BOOL handle_character_set(char *pszParmValue,int *val);
375 static BOOL handle_announce_as(char *pszParmValue, int *val);
376 static BOOL handle_coding_system(char *pszParmValue,int *val);
378 static void set_default_server_announce_type(void);
389 {"debuglevel", P_INTEGER, P_GLOBAL, &DEBUGLEVEL, NULL},
390 {"log level", P_INTEGER, P_GLOBAL, &DEBUGLEVEL, NULL},
391 {"syslog", P_INTEGER, P_GLOBAL, &Globals.syslog, NULL},
392 {"syslog only", P_BOOL, P_GLOBAL, &Globals.bSyslogOnly, NULL},
393 {"protocol", P_INTEGER, P_GLOBAL, &Globals.maxprotocol,handle_protocol},
394 {"security", P_INTEGER, P_GLOBAL, &Globals.security,handle_security},
395 {"printing", P_INTEGER, P_GLOBAL, &Globals.printing,handle_printing},
396 {"max disk size", P_INTEGER, P_GLOBAL, &Globals.maxdisksize, NULL},
397 {"lpq cache time", P_INTEGER, P_GLOBAL, &Globals.lpqcachetime, NULL},
398 {"announce as", P_INTEGER, P_GLOBAL, &Globals.announce_as, handle_announce_as},
399 {"encrypt passwords",P_BOOL, P_GLOBAL, &Globals.bEncryptPasswords, NULL},
400 {"getwd cache", P_BOOL, P_GLOBAL, &use_getwd_cache, NULL},
401 {"read prediction", P_BOOL, P_GLOBAL, &Globals.bReadPrediction, NULL},
402 {"read bmpx", P_BOOL, P_GLOBAL, &Globals.bReadbmpx, NULL},
403 {"read raw", P_BOOL, P_GLOBAL, &Globals.bReadRaw, NULL},
404 {"write raw", P_BOOL, P_GLOBAL, &Globals.bWriteRaw, NULL},
405 {"use rhosts", P_BOOL, P_GLOBAL, &Globals.bUseRhosts, NULL},
406 {"load printers", P_BOOL, P_GLOBAL, &Globals.bLoadPrinters, NULL},
407 {"null passwords", P_BOOL, P_GLOBAL, &Globals.bNullPasswords, NULL},
408 {"strip dot", P_BOOL, P_GLOBAL, &Globals.bStripDot, NULL},
409 {"interfaces", P_STRING, P_GLOBAL, &Globals.szInterfaces, NULL},
410 {"password server", P_STRING, P_GLOBAL, &Globals.szPasswordServer, NULL},
411 {"socket options", P_GSTRING, P_GLOBAL, user_socket_options, NULL},
412 {"netbios name", P_UGSTRING,P_GLOBAL, myname, NULL},
413 {"netbios aliases", P_STRING, P_GLOBAL, &Globals.szNetbiosAliases, NULL},
414 {"smbrun", P_STRING, P_GLOBAL, &Globals.szSmbrun, NULL},
415 {"log file", P_STRING, P_GLOBAL, &Globals.szLogFile, NULL},
416 {"config file", P_STRING, P_GLOBAL, &Globals.szConfigFile, NULL},
417 {"smb passwd file", P_STRING, P_GLOBAL, &Globals.szSMBPasswdFile, NULL},
418 {"hosts equiv", P_STRING, P_GLOBAL, &Globals.szHostsEquiv, NULL},
419 {"preload", P_STRING, P_GLOBAL, &Globals.szAutoServices, NULL},
420 {"auto services", P_STRING, P_GLOBAL, &Globals.szAutoServices, NULL},
421 {"server string", P_STRING, P_GLOBAL, &Globals.szServerString, NULL},
422 {"printcap name", P_STRING, P_GLOBAL, &Globals.szPrintcapname, NULL},
423 {"printcap", P_STRING, P_GLOBAL, &Globals.szPrintcapname, NULL},
424 {"lock dir", P_STRING, P_GLOBAL, &Globals.szLockDir, NULL},
425 {"lock directory", P_STRING, P_GLOBAL, &Globals.szLockDir, NULL},
426 {"root directory", P_STRING, P_GLOBAL, &Globals.szRootdir, NULL},
427 {"root dir", P_STRING, P_GLOBAL, &Globals.szRootdir, NULL},
428 {"root", P_STRING, P_GLOBAL, &Globals.szRootdir, NULL},
429 {"default service", P_STRING, P_GLOBAL, &Globals.szDefaultService, NULL},
430 {"default", P_STRING, P_GLOBAL, &Globals.szDefaultService, NULL},
431 {"message command", P_STRING, P_GLOBAL, &Globals.szMsgCommand, NULL},
432 {"dfree command", P_STRING, P_GLOBAL, &Globals.szDfree, NULL},
433 {"passwd program", P_STRING, P_GLOBAL, &Globals.szPasswdProgram, NULL},
434 {"passwd chat", P_STRING, P_GLOBAL, &Globals.szPasswdChat, NULL},
435 {"valid chars", P_STRING, P_GLOBAL, &Globals.szValidChars, handle_valid_chars},
436 {"workgroup", P_USTRING, P_GLOBAL, &Globals.szWorkGroup, NULL},
437 {"domain controller",P_STRING, P_GLOBAL, &Globals.szDomainController,NULL},
438 {"username map", P_STRING, P_GLOBAL, &Globals.szUsernameMap, NULL},
439 {"character set", P_STRING, P_GLOBAL, &Globals.szCharacterSet, handle_character_set},
440 {"logon script", P_STRING, P_GLOBAL, &Globals.szLogonScript, NULL},
441 {"logon path", P_STRING, P_GLOBAL, &Globals.szLogonPath, NULL},
442 {"remote announce", P_STRING, P_GLOBAL, &Globals.szRemoteAnnounce, NULL},
443 {"socket address", P_STRING, P_GLOBAL, &Globals.szSocketAddress, NULL},
444 {"homedir map", P_STRING, P_GLOBAL, &Globals.szNISHomeMapName, NULL},
445 {"announce version", P_STRING, P_GLOBAL, &Globals.szAnnounceVersion, NULL},
446 {"max log size", P_INTEGER, P_GLOBAL, &Globals.max_log_size, NULL},
447 {"mangled stack", P_INTEGER, P_GLOBAL, &Globals.mangled_stack, NULL},
448 {"max mux", P_INTEGER, P_GLOBAL, &Globals.max_mux, NULL},
449 {"max xmit", P_INTEGER, P_GLOBAL, &Globals.max_xmit, NULL},
450 {"max packet", P_INTEGER, P_GLOBAL, &Globals.max_packet, NULL},
451 {"packet size", P_INTEGER, P_GLOBAL, &Globals.max_packet, NULL},
452 {"password level", P_INTEGER, P_GLOBAL, &Globals.pwordlevel, NULL},
453 {"username level", P_INTEGER, P_GLOBAL, &Globals.unamelevel, NULL},
454 {"keepalive", P_INTEGER, P_GLOBAL, &keepalive, NULL},
455 {"deadtime", P_INTEGER, P_GLOBAL, &Globals.deadtime, NULL},
456 {"time offset", P_INTEGER, P_GLOBAL, &extra_time_offset, NULL},
457 {"read size", P_INTEGER, P_GLOBAL, &Globals.ReadSize, NULL},
458 {"shared mem size", P_INTEGER, P_GLOBAL, &Globals.shmem_size, NULL},
459 {"shared file entries", P_INTEGER, P_GLOBAL, &Globals.shmem_hash_size, NULL},
460 {"coding system", P_INTEGER, P_GLOBAL, &coding_system, handle_coding_system},
461 {"client code page", P_INTEGER, P_GLOBAL, &Globals.client_code_page, NULL},
462 {"os level", P_INTEGER, P_GLOBAL, &Globals.os_level, NULL},
463 {"max ttl", P_INTEGER, P_GLOBAL, &Globals.max_ttl, NULL},
464 {"dns proxy", P_BOOL, P_GLOBAL, &Globals.bDNSproxy, NULL},
465 {"wins support", P_BOOL, P_GLOBAL, &Globals.bWINSsupport, NULL},
466 {"wins proxy", P_BOOL, P_GLOBAL, &Globals.bWINSproxy, NULL},
467 {"wins server", P_STRING, P_GLOBAL, &Globals.szWINSserver, NULL},
468 {"preferred master", P_BOOL, P_GLOBAL, &Globals.bPreferredMaster, NULL},
469 {"prefered master", P_BOOL, P_GLOBAL, &Globals.bPreferredMaster, NULL},
470 {"local master", P_BOOL, P_GLOBAL, &Globals.bLocalMaster, NULL},
471 {"domain master", P_BOOL, P_GLOBAL, &Globals.bDomainMaster, NULL},
472 {"domain logons", P_BOOL, P_GLOBAL, &Globals.bDomainLogons, NULL},
473 {"browse list", P_BOOL, P_GLOBAL, &Globals.bBrowseList, NULL},
474 {"unix realname", P_BOOL, P_GLOBAL, &Globals.bUnixRealname, NULL},
475 {"NIS homedir", P_BOOL, P_GLOBAL, &Globals.bNISHomeMap, NULL},
476 {"time server", P_BOOL, P_GLOBAL, &Globals.bTimeServer, NULL},
477 {"-valid", P_BOOL, P_LOCAL, &sDefault.valid, NULL},
478 {"comment", P_STRING, P_LOCAL, &sDefault.comment, NULL},
479 {"copy", P_STRING, P_LOCAL, &sDefault.szCopy, handle_copy},
480 {"include", P_STRING, P_LOCAL, &sDefault.szInclude, handle_include},
481 {"exec", P_STRING, P_LOCAL, &sDefault.szPreExec, NULL},
482 {"preexec", P_STRING, P_LOCAL, &sDefault.szPreExec, NULL},
483 {"postexec", P_STRING, P_LOCAL, &sDefault.szPostExec, NULL},
484 {"root preexec", P_STRING, P_LOCAL, &sDefault.szRootPreExec, NULL},
485 {"root postexec", P_STRING, P_LOCAL, &sDefault.szRootPostExec, NULL},
486 {"alternate permissions",P_BOOL,P_LOCAL, &sDefault.bAlternatePerm, NULL},
487 {"revalidate", P_BOOL, P_LOCAL, &sDefault.bRevalidate, NULL},
488 {"default case", P_INTEGER, P_LOCAL, &sDefault.iDefaultCase, handle_case},
489 {"case sensitive", P_BOOL, P_LOCAL, &sDefault.bCaseSensitive, NULL},
490 {"casesignames", P_BOOL, P_LOCAL, &sDefault.bCaseSensitive, NULL},
491 {"preserve case", P_BOOL, P_LOCAL, &sDefault.bCasePreserve, NULL},
492 {"short preserve case",P_BOOL, P_LOCAL, &sDefault.bShortCasePreserve,NULL},
493 {"mangle case", P_BOOL, P_LOCAL, &sDefault.bCaseMangle, NULL},
494 {"mangling char", P_CHAR, P_LOCAL, &sDefault.magic_char, NULL},
495 {"browseable", P_BOOL, P_LOCAL, &sDefault.bBrowseable, NULL},
496 {"browsable", P_BOOL, P_LOCAL, &sDefault.bBrowseable, NULL},
497 {"available", P_BOOL, P_LOCAL, &sDefault.bAvailable, NULL},
498 {"path", P_STRING, P_LOCAL, &sDefault.szPath, NULL},
499 {"directory", P_STRING, P_LOCAL, &sDefault.szPath, NULL},
500 {"username", P_STRING, P_LOCAL, &sDefault.szUsername, NULL},
501 {"user", P_STRING, P_LOCAL, &sDefault.szUsername, NULL},
502 {"users", P_STRING, P_LOCAL, &sDefault.szUsername, NULL},
503 {"guest account", P_STRING, P_LOCAL, &sDefault.szGuestaccount, NULL},
504 {"invalid users", P_STRING, P_LOCAL, &sDefault.szInvalidUsers, NULL},
505 {"valid users", P_STRING, P_LOCAL, &sDefault.szValidUsers, NULL},
506 {"admin users", P_STRING, P_LOCAL, &sDefault.szAdminUsers, NULL},
507 {"read list", P_STRING, P_LOCAL, &sDefault.readlist, NULL},
508 {"write list", P_STRING, P_LOCAL, &sDefault.writelist, NULL},
509 {"volume", P_STRING, P_LOCAL, &sDefault.volume, NULL},
510 {"force user", P_STRING, P_LOCAL, &sDefault.force_user, NULL},
511 {"force group", P_STRING, P_LOCAL, &sDefault.force_group, NULL},
512 {"group", P_STRING, P_LOCAL, &sDefault.force_group, NULL},
513 {"read only", P_BOOL, P_LOCAL, &sDefault.bRead_only, NULL},
514 {"write ok", P_BOOLREV, P_LOCAL, &sDefault.bRead_only, NULL},
515 {"writeable", P_BOOLREV, P_LOCAL, &sDefault.bRead_only, NULL},
516 {"writable", P_BOOLREV, P_LOCAL, &sDefault.bRead_only, NULL},
517 {"max connections", P_INTEGER, P_LOCAL, &sDefault.iMaxConnections, NULL},
518 {"min print space", P_INTEGER, P_LOCAL, &sDefault.iMinPrintSpace, NULL},
519 {"create mask", P_OCTAL, P_LOCAL, &sDefault.iCreate_mask, NULL},
520 {"create mode", P_OCTAL, P_LOCAL, &sDefault.iCreate_mask, NULL},
521 {"force create mode",P_OCTAL, P_LOCAL, &sDefault.iCreate_force_mode, NULL},
522 {"directory mask", P_OCTAL, P_LOCAL, &sDefault.iDir_mask, NULL},
523 {"directory mode", P_OCTAL, P_LOCAL, &sDefault.iDir_mask, NULL},
524 {"force directory mode", P_OCTAL, P_LOCAL, &sDefault.iDir_force_mode, NULL},
525 {"set directory", P_BOOLREV, P_LOCAL, &sDefault.bNo_set_dir, NULL},
526 {"status", P_BOOL, P_LOCAL, &sDefault.status, NULL},
527 {"hide dot files", P_BOOL, P_LOCAL, &sDefault.bHideDotFiles, NULL},
528 {"delete veto files",P_BOOL, P_LOCAL, &sDefault.bDeleteVetoFiles, NULL},
529 {"veto files", P_STRING, P_LOCAL, &sDefault.szVetoFiles, NULL},
530 {"hide files", P_STRING, P_LOCAL, &sDefault.szHideFiles, NULL},
531 {"guest only", P_BOOL, P_LOCAL, &sDefault.bGuest_only, NULL},
532 {"only guest", P_BOOL, P_LOCAL, &sDefault.bGuest_only, NULL},
533 {"guest ok", P_BOOL, P_LOCAL, &sDefault.bGuest_ok, NULL},
534 {"public", P_BOOL, P_LOCAL, &sDefault.bGuest_ok, NULL},
535 {"print ok", P_BOOL, P_LOCAL, &sDefault.bPrint_ok, NULL},
536 {"printable", P_BOOL, P_LOCAL, &sDefault.bPrint_ok, NULL},
537 {"postscript", P_BOOL, P_LOCAL, &sDefault.bPostscript, NULL},
538 {"map system", P_BOOL, P_LOCAL, &sDefault.bMap_system, NULL},
539 {"map hidden", P_BOOL, P_LOCAL, &sDefault.bMap_hidden, NULL},
540 {"map archive", P_BOOL, P_LOCAL, &sDefault.bMap_archive, NULL},
541 {"locking", P_BOOL, P_LOCAL, &sDefault.bLocking, NULL},
542 {"strict locking", P_BOOL, P_LOCAL, &sDefault.bStrictLocking, NULL},
543 {"share modes", P_BOOL, P_LOCAL, &sDefault.bShareModes, NULL},
544 {"only user", P_BOOL, P_LOCAL, &sDefault.bOnlyUser, NULL},
545 {"wide links", P_BOOL, P_LOCAL, &sDefault.bWidelinks, NULL},
546 {"follow symlinks", P_BOOL, P_LOCAL, &sDefault.bSymlinks, NULL},
547 {"sync always", P_BOOL, P_LOCAL, &sDefault.bSyncAlways, NULL},
548 {"mangled names", P_BOOL, P_LOCAL, &sDefault.bMangledNames, NULL},
549 {"fake oplocks", P_BOOL, P_LOCAL, &sDefault.bFakeOplocks, NULL},
550 {"print command", P_STRING, P_LOCAL, &sDefault.szPrintcommand, NULL},
551 {"lpq command", P_STRING, P_LOCAL, &sDefault.szLpqcommand, NULL},
552 {"lprm command", P_STRING, P_LOCAL, &sDefault.szLprmcommand, NULL},
553 {"lppause command", P_STRING, P_LOCAL, &sDefault.szLppausecommand, NULL},
554 {"lpresume command", P_STRING, P_LOCAL, &sDefault.szLpresumecommand,NULL},
555 {"printer", P_STRING, P_LOCAL, &sDefault.szPrintername, NULL},
556 {"printer name", P_STRING, P_LOCAL, &sDefault.szPrintername, NULL},
557 {"printer driver", P_STRING, P_LOCAL, &sDefault.szPrinterDriver, NULL},
558 {"hosts allow", P_STRING, P_LOCAL, &sDefault.szHostsallow, NULL},
559 {"allow hosts", P_STRING, P_LOCAL, &sDefault.szHostsallow, NULL},
560 {"hosts deny", P_STRING, P_LOCAL, &sDefault.szHostsdeny, NULL},
561 {"deny hosts", P_STRING, P_LOCAL, &sDefault.szHostsdeny, NULL},
562 {"dont descend", P_STRING, P_LOCAL, &sDefault.szDontdescend, NULL},
563 {"magic script", P_STRING, P_LOCAL, &sDefault.szMagicScript, NULL},
564 {"magic output", P_STRING, P_LOCAL, &sDefault.szMagicOutput, NULL},
565 {"mangled map", P_STRING, P_LOCAL, &sDefault.szMangledMap, NULL},
566 {"delete readonly", P_BOOL, P_LOCAL, &sDefault.bDeleteReadonly, NULL},
568 {NULL, P_BOOL, P_NONE, NULL, NULL}
573 /***************************************************************************
574 Initialise the global parameter structure.
575 ***************************************************************************/
576 static void init_globals(void)
578 static BOOL done_init = False;
584 bzero((void *)&Globals,sizeof(Globals));
586 for (i = 0; parm_table[i].label; i++)
587 if ((parm_table[i].type == P_STRING ||
588 parm_table[i].type == P_USTRING) &&
590 string_init(parm_table[i].ptr,"");
592 string_set(&sDefault.szGuestaccount, GUEST_ACCOUNT);
593 string_set(&sDefault.szPrinterDriver, "NULL");
599 DEBUG(3,("Initialising global parameters\n"));
601 #ifdef SMB_PASSWD_FILE
602 string_set(&Globals.szSMBPasswdFile, SMB_PASSWD_FILE);
604 string_set(&Globals.szPasswdChat,"*old*password* %o\\n *new*password* %n\\n *new*password* %n\\n *changed*");
605 string_set(&Globals.szWorkGroup, WORKGROUP);
606 string_set(&Globals.szPasswdProgram, SMB_PASSWD);
607 string_set(&Globals.szPrintcapname, PRINTCAP_NAME);
608 string_set(&Globals.szLockDir, LOCKDIR);
609 string_set(&Globals.szRootdir, "/");
610 string_set(&Globals.szSmbrun, SMBRUN);
611 string_set(&Globals.szSocketAddress, "0.0.0.0");
612 sprintf(s,"Samba %s",VERSION);
613 string_set(&Globals.szServerString,s);
614 sprintf(s,"%d.%d", DEFAULT_MAJOR_VERSION, DEFAULT_MINOR_VERSION);
615 string_set(&Globals.szAnnounceVersion,s);
616 Globals.bLoadPrinters = True;
617 Globals.bUseRhosts = False;
618 Globals.max_packet = 65535;
619 Globals.mangled_stack = 50;
620 Globals.max_xmit = 65535;
621 Globals.max_mux = 50; /* This is *needed* for profile support. */
622 Globals.lpqcachetime = 10;
623 Globals.pwordlevel = 0;
624 Globals.unamelevel = 0;
625 Globals.deadtime = 0;
626 Globals.max_log_size = 5000;
627 Globals.maxprotocol = PROTOCOL_NT1;
628 Globals.security = SEC_SHARE;
629 Globals.bEncryptPasswords = False;
630 Globals.printing = DEFAULT_PRINTING;
631 Globals.bReadRaw = True;
632 Globals.bWriteRaw = True;
633 Globals.bReadPrediction = False;
634 Globals.bReadbmpx = True;
635 Globals.bNullPasswords = False;
636 Globals.bStripDot = False;
638 Globals.bSyslogOnly = False;
639 Globals.os_level = 0;
640 Globals.max_ttl = 60*60*4; /* 2 hours default */
641 Globals.ReadSize = 16*1024;
642 Globals.shmem_size = SHMEM_SIZE;
643 Globals.shmem_hash_size = SHMEM_HASH_SIZE;
644 Globals.announce_as = ANNOUNCE_AS_NT;
645 Globals.bUnixRealname = False;
646 #if (defined(NETGROUP) && defined(AUTOMOUNT))
647 Globals.bNISHomeMap = False;
648 string_set(&Globals.szNISHomeMapName, "auto.home");
650 coding_system = interpret_coding_system (KANJI, SJIS_CODE);
651 Globals.client_code_page = DEFAULT_CLIENT_CODE_PAGE;
652 Globals.bTimeServer = False;
654 /* these parameters are set to defaults that are more appropriate
655 for the increasing samba install base:
657 as a member of the workgroup, that will possibly become a
658 _local_ master browser (lm = True). this is opposed to a forced
659 local master browser startup (pm = True).
661 doesn't provide WINS server service by default (wsupp = False),
662 and doesn't provide domain master browser services by default, either.
666 Globals.bPreferredMaster = False;
667 Globals.bLocalMaster = True;
668 Globals.bDomainMaster = False;
669 Globals.bDomainLogons = False;
670 Globals.bBrowseList = True;
671 Globals.bWINSsupport = False;
672 Globals.bWINSproxy = False;
674 /* this parameter is currently set to the default functionality
675 in samba. given that w95 and NT is starting to use DNS for
676 server resolution, i expect that at some point it would be
677 sensible to default this to False.
679 this parameter is added because nmbd is a single process, and
680 gethostbyname is a blocking call, which can take out nmbd for
681 several seconds while a dns lookup is performed.
685 Globals.bDNSproxy = True;
688 /***************************************************************************
689 check if a string is initialised and if not then initialise it
690 ***************************************************************************/
691 static void string_initial(char **s,char *v)
698 /***************************************************************************
699 Initialise the sDefault parameter structure.
700 ***************************************************************************/
701 static void init_locals(void)
703 /* choose defaults depending on the type of printing */
704 switch (Globals.printing)
710 string_initial(&sDefault.szLpqcommand,"lpq -P%p");
711 string_initial(&sDefault.szLprmcommand,"lprm -P%p %j");
712 string_initial(&sDefault.szPrintcommand,"lpr -r -P%p %s");
717 string_initial(&sDefault.szLpqcommand,"lpstat -o%p");
718 string_initial(&sDefault.szLprmcommand,"cancel %p-%j");
719 string_initial(&sDefault.szPrintcommand,"lp -c -d%p %s; rm %s");
721 string_initial(&sDefault.szLppausecommand,"lp -i %p-%j -H hold");
722 string_initial(&sDefault.szLpresumecommand,"lp -i %p-%j -H resume");
727 string_initial(&sDefault.szLpqcommand,"lpq -P%p");
728 string_initial(&sDefault.szLprmcommand,"lprm -P%p %j");
729 string_initial(&sDefault.szPrintcommand,"lp -r -P%p %s");
737 /******************************************************************* a
738 convenience routine to grab string parameters into a rotating buffer,
739 and run standard_sub_basic on them. The buffers can be written to by
740 callers without affecting the source string.
741 ********************************************************************/
742 char *lp_string(char *s)
744 static char *bufs[10];
745 static int buflen[10];
746 static int next = -1;
749 int len = s?strlen(s):0;
760 len = MAX(len+100,sizeof(pstring)); /* the +100 is for some
763 if (buflen[next] != len) {
765 if (bufs[next]) free(bufs[next]);
766 bufs[next] = (char *)malloc(len);
768 DEBUG(0,("out of memory in lp_string()"));
773 ret = &bufs[next][0];
781 standard_sub_basic(ret);
787 In this section all the functions that are used to access the
788 parameters from the rest of the program are defined
791 #define FN_GLOBAL_STRING(fn_name,ptr) \
792 char *fn_name(void) {return(lp_string(*(char **)(ptr) ? *(char **)(ptr) : ""));}
793 #define FN_GLOBAL_BOOL(fn_name,ptr) \
794 BOOL fn_name(void) {return(*(BOOL *)(ptr));}
795 #define FN_GLOBAL_CHAR(fn_name,ptr) \
796 char fn_name(void) {return(*(char *)(ptr));}
797 #define FN_GLOBAL_INTEGER(fn_name,ptr) \
798 int fn_name(void) {return(*(int *)(ptr));}
800 #define FN_LOCAL_STRING(fn_name,val) \
801 char *fn_name(int i) {return(lp_string((LP_SNUM_OK(i)&&pSERVICE(i)->val)?pSERVICE(i)->val : sDefault.val));}
802 #define FN_LOCAL_BOOL(fn_name,val) \
803 BOOL fn_name(int i) {return(LP_SNUM_OK(i)? pSERVICE(i)->val : sDefault.val);}
804 #define FN_LOCAL_CHAR(fn_name,val) \
805 char fn_name(int i) {return(LP_SNUM_OK(i)? pSERVICE(i)->val : sDefault.val);}
806 #define FN_LOCAL_INTEGER(fn_name,val) \
807 int fn_name(int i) {return(LP_SNUM_OK(i)? pSERVICE(i)->val : sDefault.val);}
809 FN_GLOBAL_STRING(lp_logfile,&Globals.szLogFile)
810 FN_GLOBAL_STRING(lp_smbrun,&Globals.szSmbrun)
811 FN_GLOBAL_STRING(lp_configfile,&Globals.szConfigFile)
812 FN_GLOBAL_STRING(lp_smb_passwd_file,&Globals.szSMBPasswdFile)
813 FN_GLOBAL_STRING(lp_serverstring,&Globals.szServerString)
814 FN_GLOBAL_STRING(lp_printcapname,&Globals.szPrintcapname)
815 FN_GLOBAL_STRING(lp_lockdir,&Globals.szLockDir)
816 FN_GLOBAL_STRING(lp_rootdir,&Globals.szRootdir)
817 FN_GLOBAL_STRING(lp_defaultservice,&Globals.szDefaultService)
818 FN_GLOBAL_STRING(lp_msg_command,&Globals.szMsgCommand)
819 FN_GLOBAL_STRING(lp_dfree_command,&Globals.szDfree)
820 FN_GLOBAL_STRING(lp_hosts_equiv,&Globals.szHostsEquiv)
821 FN_GLOBAL_STRING(lp_auto_services,&Globals.szAutoServices)
822 FN_GLOBAL_STRING(lp_passwd_program,&Globals.szPasswdProgram)
823 FN_GLOBAL_STRING(lp_passwd_chat,&Globals.szPasswdChat)
824 FN_GLOBAL_STRING(lp_passwordserver,&Globals.szPasswordServer)
825 FN_GLOBAL_STRING(lp_workgroup,&Globals.szWorkGroup)
826 FN_GLOBAL_STRING(lp_domain_controller,&Globals.szDomainController)
827 FN_GLOBAL_STRING(lp_username_map,&Globals.szUsernameMap)
828 FN_GLOBAL_STRING(lp_character_set,&Globals.szCharacterSet)
829 FN_GLOBAL_STRING(lp_logon_script,&Globals.szLogonScript)
830 FN_GLOBAL_STRING(lp_logon_path,&Globals.szLogonPath)
831 FN_GLOBAL_STRING(lp_remote_announce,&Globals.szRemoteAnnounce)
832 FN_GLOBAL_STRING(lp_wins_server,&Globals.szWINSserver)
833 FN_GLOBAL_STRING(lp_interfaces,&Globals.szInterfaces)
834 FN_GLOBAL_STRING(lp_socket_address,&Globals.szSocketAddress)
835 FN_GLOBAL_STRING(lp_nis_home_map_name,&Globals.szNISHomeMapName)
836 FN_GLOBAL_STRING(lp_announce_version,&Globals.szAnnounceVersion)
837 FN_GLOBAL_STRING(lp_netbios_aliases,&Globals.szNetbiosAliases)
839 FN_GLOBAL_BOOL(lp_dns_proxy,&Globals.bDNSproxy)
840 FN_GLOBAL_BOOL(lp_wins_support,&Globals.bWINSsupport)
841 FN_GLOBAL_BOOL(lp_wins_proxy,&Globals.bWINSproxy)
842 FN_GLOBAL_BOOL(lp_local_master,&Globals.bLocalMaster)
843 FN_GLOBAL_BOOL(lp_domain_master,&Globals.bDomainMaster)
844 FN_GLOBAL_BOOL(lp_domain_logons,&Globals.bDomainLogons)
845 FN_GLOBAL_BOOL(lp_preferred_master,&Globals.bPreferredMaster)
846 FN_GLOBAL_BOOL(lp_load_printers,&Globals.bLoadPrinters)
847 FN_GLOBAL_BOOL(lp_use_rhosts,&Globals.bUseRhosts)
848 FN_GLOBAL_BOOL(lp_getwdcache,&use_getwd_cache)
849 FN_GLOBAL_BOOL(lp_readprediction,&Globals.bReadPrediction)
850 FN_GLOBAL_BOOL(lp_readbmpx,&Globals.bReadbmpx)
851 FN_GLOBAL_BOOL(lp_readraw,&Globals.bReadRaw)
852 FN_GLOBAL_BOOL(lp_writeraw,&Globals.bWriteRaw)
853 FN_GLOBAL_BOOL(lp_null_passwords,&Globals.bNullPasswords)
854 FN_GLOBAL_BOOL(lp_strip_dot,&Globals.bStripDot)
855 FN_GLOBAL_BOOL(lp_encrypted_passwords,&Globals.bEncryptPasswords)
856 FN_GLOBAL_BOOL(lp_syslog_only,&Globals.bSyslogOnly)
857 FN_GLOBAL_BOOL(lp_browse_list,&Globals.bBrowseList)
858 FN_GLOBAL_BOOL(lp_unix_realname,&Globals.bUnixRealname)
859 FN_GLOBAL_BOOL(lp_nis_home_map,&Globals.bNISHomeMap)
860 FN_GLOBAL_BOOL(lp_time_server,&Globals.bTimeServer)
862 FN_GLOBAL_INTEGER(lp_os_level,&Globals.os_level)
863 FN_GLOBAL_INTEGER(lp_max_ttl,&Globals.max_ttl)
864 FN_GLOBAL_INTEGER(lp_max_log_size,&Globals.max_log_size)
865 FN_GLOBAL_INTEGER(lp_mangledstack,&Globals.mangled_stack)
866 FN_GLOBAL_INTEGER(lp_maxxmit,&Globals.max_xmit)
867 FN_GLOBAL_INTEGER(lp_maxmux,&Globals.max_mux)
868 FN_GLOBAL_INTEGER(lp_maxpacket,&Globals.max_packet)
869 FN_GLOBAL_INTEGER(lp_keepalive,&keepalive)
870 FN_GLOBAL_INTEGER(lp_passwordlevel,&Globals.pwordlevel)
871 FN_GLOBAL_INTEGER(lp_usernamelevel,&Globals.unamelevel)
872 FN_GLOBAL_INTEGER(lp_readsize,&Globals.ReadSize)
873 FN_GLOBAL_INTEGER(lp_shmem_size,&Globals.shmem_size)
874 FN_GLOBAL_INTEGER(lp_shmem_hash_size,&Globals.shmem_hash_size)
875 FN_GLOBAL_INTEGER(lp_deadtime,&Globals.deadtime)
876 FN_GLOBAL_INTEGER(lp_maxprotocol,&Globals.maxprotocol)
877 FN_GLOBAL_INTEGER(lp_security,&Globals.security)
878 FN_GLOBAL_INTEGER(lp_printing,&Globals.printing)
879 FN_GLOBAL_INTEGER(lp_maxdisksize,&Globals.maxdisksize)
880 FN_GLOBAL_INTEGER(lp_lpqcachetime,&Globals.lpqcachetime)
881 FN_GLOBAL_INTEGER(lp_syslog,&Globals.syslog)
882 FN_GLOBAL_INTEGER(lp_client_code_page,&Globals.client_code_page)
883 FN_GLOBAL_INTEGER(lp_announce_as,&Globals.announce_as)
885 FN_LOCAL_STRING(lp_preexec,szPreExec)
886 FN_LOCAL_STRING(lp_postexec,szPostExec)
887 FN_LOCAL_STRING(lp_rootpreexec,szRootPreExec)
888 FN_LOCAL_STRING(lp_rootpostexec,szRootPostExec)
889 FN_LOCAL_STRING(lp_servicename,szService)
890 FN_LOCAL_STRING(lp_pathname,szPath)
891 FN_LOCAL_STRING(lp_dontdescend,szDontdescend)
892 FN_LOCAL_STRING(lp_username,szUsername)
893 FN_LOCAL_STRING(lp_guestaccount,szGuestaccount)
894 FN_LOCAL_STRING(lp_invalid_users,szInvalidUsers)
895 FN_LOCAL_STRING(lp_valid_users,szValidUsers)
896 FN_LOCAL_STRING(lp_admin_users,szAdminUsers)
897 FN_LOCAL_STRING(lp_printcommand,szPrintcommand)
898 FN_LOCAL_STRING(lp_lpqcommand,szLpqcommand)
899 FN_LOCAL_STRING(lp_lprmcommand,szLprmcommand)
900 FN_LOCAL_STRING(lp_lppausecommand,szLppausecommand)
901 FN_LOCAL_STRING(lp_lpresumecommand,szLpresumecommand)
902 FN_LOCAL_STRING(lp_printername,szPrintername)
903 FN_LOCAL_STRING(lp_printerdriver,szPrinterDriver)
904 FN_LOCAL_STRING(lp_hostsallow,szHostsallow)
905 FN_LOCAL_STRING(lp_hostsdeny,szHostsdeny)
906 FN_LOCAL_STRING(lp_magicscript,szMagicScript)
907 FN_LOCAL_STRING(lp_magicoutput,szMagicOutput)
908 FN_LOCAL_STRING(lp_comment,comment)
909 FN_LOCAL_STRING(lp_force_user,force_user)
910 FN_LOCAL_STRING(lp_force_group,force_group)
911 FN_LOCAL_STRING(lp_readlist,readlist)
912 FN_LOCAL_STRING(lp_writelist,writelist)
913 FN_LOCAL_STRING(lp_volume,volume)
914 FN_LOCAL_STRING(lp_mangled_map,szMangledMap)
915 FN_LOCAL_STRING(lp_veto_files,szVetoFiles)
916 FN_LOCAL_STRING(lp_hide_files,szHideFiles)
918 FN_LOCAL_BOOL(lp_alternate_permissions,bAlternatePerm)
919 FN_LOCAL_BOOL(lp_revalidate,bRevalidate)
920 FN_LOCAL_BOOL(lp_casesensitive,bCaseSensitive)
921 FN_LOCAL_BOOL(lp_preservecase,bCasePreserve)
922 FN_LOCAL_BOOL(lp_shortpreservecase,bShortCasePreserve)
923 FN_LOCAL_BOOL(lp_casemangle,bCaseMangle)
924 FN_LOCAL_BOOL(lp_status,status)
925 FN_LOCAL_BOOL(lp_hide_dot_files,bHideDotFiles)
926 FN_LOCAL_BOOL(lp_browseable,bBrowseable)
927 FN_LOCAL_BOOL(lp_readonly,bRead_only)
928 FN_LOCAL_BOOL(lp_no_set_dir,bNo_set_dir)
929 FN_LOCAL_BOOL(lp_guest_ok,bGuest_ok)
930 FN_LOCAL_BOOL(lp_guest_only,bGuest_only)
931 FN_LOCAL_BOOL(lp_print_ok,bPrint_ok)
932 FN_LOCAL_BOOL(lp_postscript,bPostscript)
933 FN_LOCAL_BOOL(lp_map_hidden,bMap_hidden)
934 FN_LOCAL_BOOL(lp_map_archive,bMap_archive)
935 FN_LOCAL_BOOL(lp_locking,bLocking)
936 FN_LOCAL_BOOL(lp_strict_locking,bStrictLocking)
937 FN_LOCAL_BOOL(lp_share_modes,bShareModes)
938 FN_LOCAL_BOOL(lp_onlyuser,bOnlyUser)
939 FN_LOCAL_BOOL(lp_manglednames,bMangledNames)
940 FN_LOCAL_BOOL(lp_widelinks,bWidelinks)
941 FN_LOCAL_BOOL(lp_symlinks,bSymlinks)
942 FN_LOCAL_BOOL(lp_syncalways,bSyncAlways)
943 FN_LOCAL_BOOL(lp_map_system,bMap_system)
944 FN_LOCAL_BOOL(lp_delete_readonly,bDeleteReadonly)
945 FN_LOCAL_BOOL(lp_fake_oplocks,bFakeOplocks)
946 FN_LOCAL_BOOL(lp_recursive_veto_delete,bDeleteVetoFiles)
948 FN_LOCAL_INTEGER(lp_create_mode,iCreate_mask)
949 FN_LOCAL_INTEGER(lp_force_create_mode,iCreate_force_mode)
950 FN_LOCAL_INTEGER(lp_dir_mode,iDir_mask)
951 FN_LOCAL_INTEGER(lp_force_dir_mode,iDir_force_mode)
952 FN_LOCAL_INTEGER(lp_max_connections,iMaxConnections)
953 FN_LOCAL_INTEGER(lp_defaultcase,iDefaultCase)
954 FN_LOCAL_INTEGER(lp_minprintspace,iMinPrintSpace)
956 FN_LOCAL_CHAR(lp_magicchar,magic_char)
960 /* local prototypes */
961 static int strwicmp( char *psz1, char *psz2 );
962 static int map_parameter( char *pszParmName);
963 static BOOL set_boolean( BOOL *pb, char *pszParmValue );
964 static int getservicebyname(char *pszServiceName, service *pserviceDest);
965 static void copy_service( service *pserviceDest,
966 service *pserviceSource,
967 BOOL *pcopymapDest );
968 static BOOL service_ok(int iService);
969 static BOOL do_parameter(char *pszParmName, char *pszParmValue);
970 static BOOL do_section(char *pszSectionName);
971 static void init_copymap(service *pservice);
974 /***************************************************************************
975 initialise a service to the defaults
976 ***************************************************************************/
977 static void init_service(service *pservice)
979 bzero((char *)pservice,sizeof(service));
980 copy_service(pservice,&sDefault,NULL);
984 /***************************************************************************
985 free the dynamically allocated parts of a service struct
986 ***************************************************************************/
987 static void free_service(service *pservice)
993 for (i=0;parm_table[i].label;i++)
994 if ((parm_table[i].type == P_STRING ||
995 parm_table[i].type == P_STRING) &&
996 parm_table[i].class == P_LOCAL)
997 string_free((char **)(((char *)pservice) + PTR_DIFF(parm_table[i].ptr,&sDefault)));
1000 /***************************************************************************
1001 add a new service to the services array initialising it with the given
1003 ***************************************************************************/
1004 static int add_a_service(service *pservice, char *name)
1008 int num_to_alloc = iNumServices+1;
1010 tservice = *pservice;
1012 /* it might already exist */
1015 i = getservicebyname(name,NULL);
1020 /* find an invalid one */
1021 for (i=0;i<iNumServices;i++)
1022 if (!pSERVICE(i)->valid)
1025 /* if not, then create one */
1026 if (i == iNumServices)
1028 ServicePtrs = (service **)Realloc(ServicePtrs,sizeof(service *)*num_to_alloc);
1030 pSERVICE(iNumServices) = (service *)malloc(sizeof(service));
1032 if (!ServicePtrs || !pSERVICE(iNumServices))
1038 free_service(pSERVICE(i));
1040 pSERVICE(i)->valid = True;
1042 init_service(pSERVICE(i));
1043 copy_service(pSERVICE(i),&tservice,NULL);
1045 string_set(&iSERVICE(i).szService,name);
1050 /***************************************************************************
1051 add a new home service, with the specified home directory, defaults coming
1053 ***************************************************************************/
1054 BOOL lp_add_home(char *pszHomename, int iDefaultService, char *pszHomedir)
1056 int i = add_a_service(pSERVICE(iDefaultService),pszHomename);
1061 if (!(*(iSERVICE(i).szPath)) || strequal(iSERVICE(i).szPath,lp_pathname(-1)))
1062 string_set(&iSERVICE(i).szPath,pszHomedir);
1063 if (!(*(iSERVICE(i).comment)))
1066 sprintf(comment,"Home directory of %s",pszHomename);
1067 string_set(&iSERVICE(i).comment,comment);
1069 iSERVICE(i).bAvailable = sDefault.bAvailable;
1070 iSERVICE(i).bBrowseable = sDefault.bBrowseable;
1072 DEBUG(3,("adding home directory %s at %s\n", pszHomename, pszHomedir));
1077 /***************************************************************************
1078 add a new service, based on an old one
1079 ***************************************************************************/
1080 int lp_add_service(char *pszService, int iDefaultService)
1082 return(add_a_service(pSERVICE(iDefaultService),pszService));
1086 /***************************************************************************
1088 ***************************************************************************/
1089 static BOOL lp_add_ipc(void)
1092 int i = add_a_service(&sDefault,"IPC$");
1097 sprintf(comment,"IPC Service (%s)",lp_serverstring());
1099 string_set(&iSERVICE(i).szPath,tmpdir());
1100 string_set(&iSERVICE(i).szUsername,"");
1101 string_set(&iSERVICE(i).comment,comment);
1102 iSERVICE(i).status = False;
1103 iSERVICE(i).iMaxConnections = 0;
1104 iSERVICE(i).bAvailable = True;
1105 iSERVICE(i).bRead_only = True;
1106 iSERVICE(i).bGuest_only = False;
1107 iSERVICE(i).bGuest_ok = True;
1108 iSERVICE(i).bPrint_ok = False;
1109 iSERVICE(i).bBrowseable = sDefault.bBrowseable;
1111 DEBUG(3,("adding IPC service\n"));
1117 /***************************************************************************
1118 add a new printer service, with defaults coming from service iFrom
1119 ***************************************************************************/
1120 BOOL lp_add_printer(char *pszPrintername, int iDefaultService)
1122 char *comment = "From Printcap";
1123 int i = add_a_service(pSERVICE(iDefaultService),pszPrintername);
1128 /* note that we do NOT default the availability flag to True - */
1129 /* we take it from the default service passed. This allows all */
1130 /* dynamic printers to be disabled by disabling the [printers] */
1131 /* entry (if/when the 'available' keyword is implemented!). */
1133 /* the printer name is set to the service name. */
1134 string_set(&iSERVICE(i).szPrintername,pszPrintername);
1135 string_set(&iSERVICE(i).comment,comment);
1136 iSERVICE(i).bBrowseable = sDefault.bBrowseable;
1137 /* Printers cannot be read_only. */
1138 iSERVICE(i).bRead_only = False;
1139 /* No share modes on printer services. */
1140 iSERVICE(i).bShareModes = False;
1141 /* Printer services must be printable. */
1142 iSERVICE(i).bPrint_ok = True;
1144 DEBUG(3,("adding printer service %s\n",pszPrintername));
1150 /***************************************************************************
1151 Do a case-insensitive, whitespace-ignoring string compare.
1152 ***************************************************************************/
1153 static int strwicmp(char *psz1, char *psz2)
1155 /* if BOTH strings are NULL, return TRUE, if ONE is NULL return */
1156 /* appropriate value. */
1166 /* sync the strings on first non-whitespace */
1169 while (isspace(*psz1))
1171 while (isspace(*psz2))
1173 if (toupper(*psz1) != toupper(*psz2) || *psz1 == '\0' || *psz2 == '\0')
1178 return (*psz1 - *psz2);
1181 /***************************************************************************
1182 Map a parameter's string representation to something we can use.
1183 Returns False if the parameter string is not recognised, else TRUE.
1184 ***************************************************************************/
1185 static int map_parameter(char *pszParmName)
1189 if (*pszParmName == '-')
1192 for (iIndex = 0; parm_table[iIndex].label; iIndex++)
1193 if (strwicmp(parm_table[iIndex].label, pszParmName) == 0)
1196 DEBUG(0,( "Unknown parameter encountered: \"%s\"\n", pszParmName));
1201 /***************************************************************************
1202 Set a boolean variable from the text value stored in the passed string.
1203 Returns True in success, False if the passed string does not correctly
1204 represent a boolean.
1205 ***************************************************************************/
1206 static BOOL set_boolean(BOOL *pb, char *pszParmValue)
1211 if (strwicmp(pszParmValue, "yes") == 0 ||
1212 strwicmp(pszParmValue, "true") == 0 ||
1213 strwicmp(pszParmValue, "1") == 0)
1216 if (strwicmp(pszParmValue, "no") == 0 ||
1217 strwicmp(pszParmValue, "False") == 0 ||
1218 strwicmp(pszParmValue, "0") == 0)
1222 DEBUG(0,( "Badly formed boolean in configuration file: \"%s\".\n",
1229 /***************************************************************************
1230 Find a service by name. Otherwise works like get_service.
1231 ***************************************************************************/
1232 static int getservicebyname(char *pszServiceName, service *pserviceDest)
1236 for (iService = iNumServices - 1; iService >= 0; iService--)
1237 if (VALID(iService) &&
1238 strwicmp(iSERVICE(iService).szService, pszServiceName) == 0)
1240 if (pserviceDest != NULL)
1241 copy_service(pserviceDest, pSERVICE(iService), NULL);
1250 /***************************************************************************
1251 Copy a service structure to another
1253 If pcopymapDest is NULL then copy all fields
1254 ***************************************************************************/
1255 static void copy_service(service *pserviceDest,
1256 service *pserviceSource,
1260 BOOL bcopyall = (pcopymapDest == NULL);
1262 for (i=0;parm_table[i].label;i++)
1263 if (parm_table[i].ptr && parm_table[i].class == P_LOCAL &&
1264 (bcopyall || pcopymapDest[i]))
1266 void *def_ptr = parm_table[i].ptr;
1268 ((char *)pserviceSource) + PTR_DIFF(def_ptr,&sDefault);
1270 ((char *)pserviceDest) + PTR_DIFF(def_ptr,&sDefault);
1272 switch (parm_table[i].type)
1276 *(BOOL *)dest_ptr = *(BOOL *)src_ptr;
1281 *(int *)dest_ptr = *(int *)src_ptr;
1285 *(char *)dest_ptr = *(char *)src_ptr;
1289 string_set(dest_ptr,*(char **)src_ptr);
1293 string_set(dest_ptr,*(char **)src_ptr);
1294 strupper(*(char **)dest_ptr);
1303 init_copymap(pserviceDest);
1304 if (pserviceSource->copymap)
1305 memcpy((void *)pserviceDest->copymap,
1306 (void *)pserviceSource->copymap,sizeof(BOOL)*NUMPARAMETERS);
1310 /***************************************************************************
1311 Check a service for consistency. Return False if the service is in any way
1312 incomplete or faulty, else True.
1313 ***************************************************************************/
1314 static BOOL service_ok(int iService)
1319 if (iSERVICE(iService).szService[0] == '\0')
1321 DEBUG(0,( "The following message indicates an internal error:\n"));
1322 DEBUG(0,( "No service name in service entry.\n"));
1326 /* The [printers] entry MUST be printable. I'm all for flexibility, but */
1327 /* I can't see why you'd want a non-printable printer service... */
1328 if (strwicmp(iSERVICE(iService).szService,PRINTERS_NAME) == 0)
1329 if (!iSERVICE(iService).bPrint_ok)
1331 DEBUG(0,( "WARNING: [%s] service MUST be printable!\n",
1332 iSERVICE(iService).szService));
1333 iSERVICE(iService).bPrint_ok = True;
1336 if (iSERVICE(iService).szPath[0] == '\0' &&
1337 strwicmp(iSERVICE(iService).szService,HOMES_NAME) != 0)
1339 DEBUG(0,("No path in service %s - using %s\n",iSERVICE(iService).szService,tmpdir()));
1340 string_set(&iSERVICE(iService).szPath,tmpdir());
1343 /* If a service is flagged unavailable, log the fact at level 0. */
1344 if (!iSERVICE(iService).bAvailable)
1345 DEBUG(1,( "NOTE: Service %s is flagged unavailable.\n",
1346 iSERVICE(iService).szService));
1351 static struct file_lists {
1352 struct file_lists *next;
1355 } *file_lists = NULL;
1357 /*******************************************************************
1358 keep a linked list of all config files so we know when one has changed
1359 it's date and needs to be reloaded
1360 ********************************************************************/
1361 static void add_to_file_list(char *fname)
1363 struct file_lists *f=file_lists;
1366 if (f->name && !strcmp(f->name,fname)) break;
1371 f = (struct file_lists *)malloc(sizeof(file_lists[0]));
1373 f->next = file_lists;
1374 f->name = strdup(fname);
1385 standard_sub_basic(n2);
1386 f->modtime = file_modtime(n2);
1391 /*******************************************************************
1392 check if a config file has changed date
1393 ********************************************************************/
1394 BOOL lp_file_list_changed(void)
1396 struct file_lists *f = file_lists;
1397 DEBUG(6,("lp_file_list_changed()\n"));
1404 pstrcpy(n2,f->name);
1405 standard_sub_basic(n2);
1407 DEBUG(6,("file %s -> %s last mod_time: %s\n",
1408 f->name, n2, ctime(&f->modtime)));
1410 mod_time = file_modtime(n2);
1412 if (f->modtime != mod_time)
1414 DEBUG(6,("file %s modified: %s\n", n2, ctime(&mod_time)));
1422 /***************************************************************************
1423 handle the interpretation of the coding system parameter
1424 *************************************************************************/
1425 static BOOL handle_coding_system(char *pszParmValue,int *val)
1427 *val = interpret_coding_system(pszParmValue,*val);
1431 /***************************************************************************
1432 handle the interpretation of the character set system parameter
1433 ***************************************************************************/
1434 static BOOL handle_character_set(char *pszParmValue,int *val)
1436 string_set(&Globals.szCharacterSet,pszParmValue);
1437 *val = interpret_character_set(pszParmValue,*val);
1442 /***************************************************************************
1443 handle the interpretation of the protocol parameter
1444 ***************************************************************************/
1445 static BOOL handle_protocol(char *pszParmValue,int *val)
1447 *val = interpret_protocol(pszParmValue,*val);
1451 /***************************************************************************
1452 handle the interpretation of the security parameter
1453 ***************************************************************************/
1454 static BOOL handle_security(char *pszParmValue,int *val)
1456 *val = interpret_security(pszParmValue,*val);
1460 /***************************************************************************
1461 handle the interpretation of the default case
1462 ***************************************************************************/
1463 static BOOL handle_case(char *pszParmValue,int *val)
1465 if (strnequal(pszParmValue,"LOWER", 5))
1467 else if (strnequal(pszParmValue,"UPPER", 5))
1472 /***************************************************************************
1473 handle the interpretation of the printing system
1474 ***************************************************************************/
1475 static BOOL handle_printing(char *pszParmValue,int *val)
1477 if (strnequal(pszParmValue,"sysv", 4))
1479 else if (strnequal(pszParmValue,"aix", 3))
1481 else if (strnequal(pszParmValue,"hpux", 4))
1483 else if (strnequal(pszParmValue,"bsd", 3))
1485 else if (strnequal(pszParmValue,"qnx",3))
1487 else if (strnequal(pszParmValue,"plp", 3))
1489 else if (strnequal(pszParmValue,"lprng", 5))
1494 /***************************************************************************
1495 handle the announce as parameter
1496 ***************************************************************************/
1497 static BOOL handle_announce_as(char *pszParmValue,int *val)
1499 if (strnequal(pszParmValue,"NT", 2))
1500 *val = ANNOUNCE_AS_NT;
1501 else if (strnequal(pszParmValue,"win95", 5))
1502 *val = ANNOUNCE_AS_WIN95;
1503 else if (strnequal(pszParmValue,"WfW", 3))
1504 *val = ANNOUNCE_AS_WFW;
1508 /***************************************************************************
1509 handle the valid chars lines
1510 ***************************************************************************/
1511 static BOOL handle_valid_chars(char *pszParmValue,char **ptr)
1513 string_set(ptr,pszParmValue);
1515 /* A dependency here is that the parameter client code page must be
1516 set before this is called - as calling codepage_initialise()
1517 would overwrite the valid char lines.
1519 codepage_initialise(lp_client_code_page());
1521 add_char_string(pszParmValue);
1526 /***************************************************************************
1527 handle the include operation
1528 ***************************************************************************/
1529 static BOOL handle_include(char *pszParmValue,char **ptr)
1532 pstrcpy(fname,pszParmValue);
1534 add_to_file_list(fname);
1536 standard_sub_basic(fname);
1538 string_set(ptr,fname);
1540 if (file_exist(fname,NULL))
1541 return(pm_process(fname, do_section, do_parameter));
1543 DEBUG(2,("Can't find include file %s\n",fname));
1549 /***************************************************************************
1550 handle the interpretation of the copy parameter
1551 ***************************************************************************/
1552 static BOOL handle_copy(char *pszParmValue,char **ptr)
1556 service serviceTemp;
1558 string_set(ptr,pszParmValue);
1560 init_service(&serviceTemp);
1564 DEBUG(3,("Copying service from service %s\n",pszParmValue));
1566 if ((iTemp = getservicebyname(pszParmValue, &serviceTemp)) >= 0)
1568 if (iTemp == iServiceIndex)
1570 DEBUG(0,("Can't copy service %s - unable to copy self!\n",
1575 copy_service(pSERVICE(iServiceIndex),
1577 iSERVICE(iServiceIndex).copymap);
1583 DEBUG(0,( "Unable to copy service - source not found: %s\n",
1588 free_service(&serviceTemp);
1593 /***************************************************************************
1594 initialise a copymap
1595 ***************************************************************************/
1596 static void init_copymap(service *pservice)
1599 if (pservice->copymap) free(pservice->copymap);
1600 pservice->copymap = (BOOL *)malloc(sizeof(BOOL)*NUMPARAMETERS);
1601 if (!pservice->copymap)
1602 DEBUG(0,("Couldn't allocate copymap!! (size %d)\n",NUMPARAMETERS));
1604 for (i=0;i<NUMPARAMETERS;i++)
1605 pservice->copymap[i] = True;
1609 /***************************************************************************
1610 Process a parameter for a particular service number. If snum < 0
1611 then assume we are in the globals
1612 ***************************************************************************/
1613 BOOL lp_do_parameter(int snum, char *pszParmName, char *pszParmValue)
1616 void *parm_ptr=NULL; /* where we are going to store the result */
1619 parmnum = map_parameter(pszParmName);
1623 DEBUG(0,( "Ignoring unknown parameter \"%s\"\n", pszParmName));
1627 def_ptr = parm_table[parmnum].ptr;
1629 /* we might point at a service, the default service or a global */
1633 if (parm_table[parmnum].class == P_GLOBAL) {
1634 DEBUG(0,( "Global parameter %s found in service section!\n",pszParmName));
1637 parm_ptr = ((char *)pSERVICE(snum)) + PTR_DIFF(def_ptr,&sDefault);
1642 if (!iSERVICE(snum).copymap)
1643 init_copymap(pSERVICE(snum));
1645 /* this handles the aliases - set the copymap for other entries with
1646 the same data pointer */
1647 for (i=0;parm_table[i].label;i++)
1648 if (parm_table[i].ptr == parm_table[parmnum].ptr)
1649 iSERVICE(snum).copymap[i] = False;
1652 /* if it is a special case then go ahead */
1653 if (parm_table[parmnum].special) {
1654 parm_table[parmnum].special(pszParmValue,parm_ptr);
1658 /* now switch on the type of variable it is */
1659 switch (parm_table[parmnum].type)
1662 set_boolean(parm_ptr,pszParmValue);
1666 set_boolean(parm_ptr,pszParmValue);
1667 *(BOOL *)parm_ptr = ! *(BOOL *)parm_ptr;
1671 *(int *)parm_ptr = atoi(pszParmValue);
1675 *(char *)parm_ptr = *pszParmValue;
1679 sscanf(pszParmValue,"%o",(int *)parm_ptr);
1683 string_set(parm_ptr,pszParmValue);
1687 string_set(parm_ptr,pszParmValue);
1688 strupper(*(char **)parm_ptr);
1692 strcpy((char *)parm_ptr,pszParmValue);
1696 strcpy((char *)parm_ptr,pszParmValue);
1697 strupper((char *)parm_ptr);
1704 /***************************************************************************
1705 Process a parameter.
1706 ***************************************************************************/
1707 static BOOL do_parameter(char *pszParmName, char *pszParmValue)
1709 if (!bInGlobalSection && bGlobalOnly) return(True);
1711 DEBUG(3,("doing parameter %s = %s\n",pszParmName,pszParmValue));
1713 return lp_do_parameter(bInGlobalSection?-2:iServiceIndex, pszParmName, pszParmValue);
1717 /***************************************************************************
1718 print a parameter of the specified type
1719 ***************************************************************************/
1720 static void print_parameter(parm_type type,void *ptr, FILE *f)
1725 fprintf(f,"%s",BOOLSTR(*(BOOL *)ptr));
1729 fprintf(f,"%s",BOOLSTR(! *(BOOL *)ptr));
1733 fprintf(f,"%d",*(int *)ptr);
1737 fprintf(f,"%c",*(char *)ptr);
1741 fprintf(f,"0%o",*(int *)ptr);
1747 fprintf(f,"%s",(char *)ptr);
1753 fprintf(f,"%s",*(char **)ptr);
1759 /***************************************************************************
1760 print a parameter of the specified type
1761 ***************************************************************************/
1762 static void parameter_string(parm_type type,void *ptr,char *s)
1769 sprintf(s, "%s",BOOLSTR(*(BOOL *)ptr));
1773 sprintf(s, "%s",BOOLSTR(! *(BOOL *)ptr));
1777 sprintf(s, "%d",*(int *)ptr);
1781 sprintf(s, "%c",*(char *)ptr);
1785 sprintf(s, "0%o",*(int *)ptr);
1791 sprintf(s, "%s",(char *)ptr);
1797 sprintf(s, "%s",*(char **)ptr);
1803 /***************************************************************************
1804 check if two parameters are equal
1805 ***************************************************************************/
1806 static BOOL equal_parameter(parm_type type,void *ptr1,void *ptr2)
1812 return(*((BOOL *)ptr1) == *((BOOL *)ptr2));
1816 return(*((int *)ptr1) == *((int *)ptr2));
1819 return(*((char *)ptr1) == *((char *)ptr2));
1824 char *p1 = (char *)ptr1, *p2 = (char *)ptr2;
1825 if (p1 && !*p1) p1 = NULL;
1826 if (p2 && !*p2) p2 = NULL;
1827 return(p1==p2 || strequal(p1,p2));
1832 char *p1 = *(char **)ptr1, *p2 = *(char **)ptr2;
1833 if (p1 && !*p1) p1 = NULL;
1834 if (p2 && !*p2) p2 = NULL;
1835 return(p1==p2 || strequal(p1,p2));
1841 /***************************************************************************
1842 Process a new section (service). At this stage all sections are services.
1843 Later we'll have special sections that permit server parameters to be set.
1844 Returns True on success, False on failure.
1845 ***************************************************************************/
1846 static BOOL do_section(char *pszSectionName)
1849 BOOL isglobal = ((strwicmp(pszSectionName, GLOBAL_NAME) == 0) ||
1850 (strwicmp(pszSectionName, GLOBAL_NAME2) == 0));
1853 /* if we were in a global section then do the local inits */
1854 if (bInGlobalSection && !isglobal)
1857 /* if we've just struck a global section, note the fact. */
1858 bInGlobalSection = isglobal;
1860 /* check for multiple global sections */
1861 if (bInGlobalSection)
1863 DEBUG(3,( "Processing section \"[%s]\"\n", pszSectionName));
1867 if (!bInGlobalSection && bGlobalOnly) return(True);
1869 /* if we have a current service, tidy it up before moving on */
1872 if (iServiceIndex >= 0)
1873 bRetval = service_ok(iServiceIndex);
1875 /* if all is still well, move to the next record in the services array */
1878 /* We put this here to avoid an odd message order if messages are */
1879 /* issued by the post-processing of a previous section. */
1880 DEBUG(2,( "Processing section \"[%s]\"\n", pszSectionName));
1882 if ((iServiceIndex=add_a_service(&sDefault,pszSectionName)) < 0)
1884 DEBUG(0,("Failed to add a new service\n"));
1892 /***************************************************************************
1893 Display the contents of the global structure.
1894 ***************************************************************************/
1895 static void dump_globals(FILE *f)
1898 fprintf(f, "# Global parameters\n");
1900 for (i=0;parm_table[i].label;i++)
1901 if (parm_table[i].class == P_GLOBAL &&
1902 parm_table[i].ptr &&
1903 (i == 0 || (parm_table[i].ptr != parm_table[i-1].ptr)))
1905 fprintf(f,"\t%s = ",parm_table[i].label);
1906 print_parameter(parm_table[i].type,parm_table[i].ptr, f);
1911 /***************************************************************************
1912 Display the contents of a single services record.
1913 ***************************************************************************/
1914 static void dump_a_service(service *pService, FILE *f)
1917 if (pService == &sDefault)
1918 fprintf(f,"\n\n# Default service parameters\n");
1920 fprintf(f,"\n[%s]\n",pService->szService);
1922 for (i=0;parm_table[i].label;i++)
1923 if (parm_table[i].class == P_LOCAL &&
1924 parm_table[i].ptr &&
1925 (*parm_table[i].label != '-') &&
1926 (i == 0 || (parm_table[i].ptr != parm_table[i-1].ptr)))
1928 int pdiff = PTR_DIFF(parm_table[i].ptr,&sDefault);
1930 if (pService == &sDefault || !equal_parameter(parm_table[i].type,
1931 ((char *)pService) + pdiff,
1932 ((char *)&sDefault) + pdiff))
1934 fprintf(f,"\t%s = ",parm_table[i].label);
1935 print_parameter(parm_table[i].type,
1936 ((char *)pService) + pdiff, f);
1943 /***************************************************************************
1944 return info about the next service in a service. snum==-1 gives the default
1945 serice and snum==-2 gives the globals
1947 return 0 when out of parameters
1948 ***************************************************************************/
1949 int lp_next_parameter(int snum, int *i, char *label,
1950 char *value, int allparameters)
1953 /* do the globals */
1954 for (;parm_table[*i].label;(*i)++)
1955 if (parm_table[*i].class == P_GLOBAL &&
1956 parm_table[*i].ptr &&
1957 (*parm_table[*i].label != '-') &&
1959 (parm_table[*i].ptr != parm_table[(*i)-1].ptr))) {
1960 strcpy(label, parm_table[*i].label);
1961 parameter_string(parm_table[*i].type,
1969 service *pService = (snum==-1?&sDefault:pSERVICE(snum));
1971 for (;parm_table[*i].label;(*i)++)
1972 if (parm_table[*i].class == P_LOCAL &&
1973 parm_table[*i].ptr &&
1974 (*parm_table[*i].label != '-') &&
1976 (parm_table[*i].ptr != parm_table[(*i)-1].ptr))) {
1977 int pdiff = PTR_DIFF(parm_table[*i].ptr,&sDefault);
1979 if (snum == -1 || allparameters ||
1980 !equal_parameter(parm_table[*i].type,
1981 ((char *)pService) + pdiff,
1982 ((char *)&sDefault) + pdiff)) {
1983 strcpy(label, parm_table[*i].label);
1984 parameter_string(parm_table[*i].type,
1985 ((char *)pService) + pdiff,
1998 /***************************************************************************
1999 Display the contents of a single copy structure.
2000 ***************************************************************************/
2001 static void dump_copy_map(BOOL *pcopymap)
2004 if (!pcopymap) return;
2006 printf("\n\tNon-Copied parameters:\n");
2008 for (i=0;parm_table[i].label;i++)
2009 if (parm_table[i].class == P_LOCAL &&
2010 parm_table[i].ptr && !pcopymap[i] &&
2011 (i == 0 || (parm_table[i].ptr != parm_table[i-1].ptr)))
2013 printf("\t\t%s\n",parm_table[i].label);
2018 /***************************************************************************
2019 Return TRUE if the passed service number is within range.
2020 ***************************************************************************/
2021 BOOL lp_snum_ok(int iService)
2023 return (LP_SNUM_OK(iService) && iSERVICE(iService).bAvailable);
2027 /***************************************************************************
2028 auto-load some homes and printer services
2029 ***************************************************************************/
2030 static void lp_add_auto_services(char *str)
2034 int homes = lp_servicenumber(HOMES_NAME);
2035 int printers = lp_servicenumber(PRINTERS_NAME);
2043 for (p=strtok(s,LIST_SEP);p;p=strtok(NULL,LIST_SEP))
2045 char *home = get_home_dir(p);
2047 if (lp_servicenumber(p) >= 0) continue;
2049 if (home && homes >= 0)
2051 lp_add_home(p,homes,home);
2055 if (printers >= 0 && pcap_printername_ok(p,NULL))
2056 lp_add_printer(p,printers);
2061 /***************************************************************************
2062 auto-load one printer
2063 ***************************************************************************/
2064 static void lp_add_one_printer(char *name,char *comment)
2066 int printers = lp_servicenumber(PRINTERS_NAME);
2069 if (lp_servicenumber(name) < 0)
2071 lp_add_printer(name,printers);
2072 if ((i=lp_servicenumber(name)) >= 0)
2073 string_set(&iSERVICE(i).comment,comment);
2078 /***************************************************************************
2079 auto-load printer services
2080 ***************************************************************************/
2081 static void lp_add_all_printers(void)
2083 int printers = lp_servicenumber(PRINTERS_NAME);
2085 if (printers < 0) return;
2087 pcap_printer_fn(lp_add_one_printer);
2090 /***************************************************************************
2091 have we loaded a services file yet?
2092 ***************************************************************************/
2093 BOOL lp_loaded(void)
2098 /***************************************************************************
2099 unload unused services
2100 ***************************************************************************/
2101 void lp_killunused(BOOL (*snumused)(int ))
2104 for (i=0;i<iNumServices;i++)
2105 if (VALID(i) && (!snumused || !snumused(i)))
2107 iSERVICE(i).valid = False;
2108 free_service(pSERVICE(i));
2112 /***************************************************************************
2113 Load the services array from the services file. Return True on success,
2115 ***************************************************************************/
2116 BOOL lp_load(char *pszFname,BOOL global_only)
2121 add_to_file_list(pszFname);
2125 bInGlobalSection = True;
2126 bGlobalOnly = global_only;
2130 pstrcpy(n2,pszFname);
2131 standard_sub_basic(n2);
2133 /* We get sections first, so have to start 'behind' to make up */
2135 bRetval = pm_process(n2, do_section, do_parameter);
2137 /* finish up the last section */
2138 DEBUG(3,("pm_process() returned %s\n", BOOLSTR(bRetval)));
2140 if (iServiceIndex >= 0)
2141 bRetval = service_ok(iServiceIndex);
2143 lp_add_auto_services(lp_auto_services());
2144 if (lp_load_printers())
2145 lp_add_all_printers();
2149 set_default_server_announce_type();
2157 /***************************************************************************
2158 return the max number of services
2159 ***************************************************************************/
2160 int lp_numservices(void)
2162 return(iNumServices);
2165 /***************************************************************************
2166 Display the contents of the services array in human-readable form.
2167 ***************************************************************************/
2168 void lp_dump(FILE *f)
2174 dump_a_service(&sDefault, f);
2176 for (iService = 0; iService < iNumServices; iService++)
2178 if (VALID(iService))
2180 if (iSERVICE(iService).szService[0] == '\0')
2182 dump_a_service(pSERVICE(iService), f);
2188 /***************************************************************************
2189 Return the number of the service with the given name, or -1 if it doesn't
2190 exist. Note that this is a DIFFERENT ANIMAL from the internal function
2191 getservicebyname()! This works ONLY if all services have been loaded, and
2192 does not copy the found service.
2193 ***************************************************************************/
2194 int lp_servicenumber(char *pszServiceName)
2198 for (iService = iNumServices - 1; iService >= 0; iService--)
2199 if (VALID(iService) &&
2200 strwicmp(iSERVICE(iService).szService, pszServiceName) == 0)
2204 DEBUG(7,("lp_servicenumber: couldn't find %s\n",pszServiceName));
2209 /*******************************************************************
2210 a useful volume label function
2211 ******************************************************************/
2212 char *volume_label(int snum)
2214 char *ret = lp_volume(snum);
2215 if (!*ret) return(lp_servicename(snum));
2221 * nmbd only loads the global section. There seems to be no way to
2222 * determine exactly is a service is printable by only looking at the
2223 * [global] section so for now always announce as a print server. This
2224 * will need looking at in the future. Jeremy (jallison@whistle.com).
2226 /*******************************************************************
2227 Return true if any printer services are defined.
2228 ******************************************************************/
2229 static BOOL lp_printer_services(void)
2233 for (iService = iNumServices - 1; iService >= 0; iService--)
2234 if (VALID(iService) && iSERVICE(iService).bPrint_ok)
2240 /*******************************************************************
2241 Set the server type we will announce as via nmbd.
2242 ********************************************************************/
2243 static void set_default_server_announce_type()
2245 default_server_announce = (SV_TYPE_WORKSTATION | SV_TYPE_SERVER |
2246 SV_TYPE_SERVER_UNIX | SV_TYPE_PRINTQ_SERVER);
2247 if(lp_announce_as() == ANNOUNCE_AS_NT)
2248 default_server_announce |= (SV_TYPE_SERVER_NT | SV_TYPE_NT);
2249 else if(lp_announce_as() == ANNOUNCE_AS_WIN95)
2250 default_server_announce |= SV_TYPE_WIN95_PLUS;
2251 else if(lp_announce_as() == ANNOUNCE_AS_WFW)
2252 default_server_announce |= SV_TYPE_WFW;
2253 default_server_announce |= (lp_time_server() ? SV_TYPE_TIME_SOURCE : 0);
2255 * nmbd only loads the [global] section. There seems to be no way to
2256 * determine exactly if any service is printable by only looking at the
2257 * [global] section so for now always announce as a print server. This
2258 * will need looking at in the future. Jeremy (jallison@whistle.com).
2261 default_server_announce |= (lp_printer_services() ? SV_TYPE_PRINTQ_SERVER : 0);
2266 /*******************************************************************
2268 ********************************************************************/
2269 void lp_rename_service(int snum, char *new_name)
2271 string_set(&pSERVICE(snum)->szService, new_name);
2274 /*******************************************************************
2276 ********************************************************************/
2277 void lp_remove_service(int snum)
2279 pSERVICE(snum)->valid = False;
2282 /*******************************************************************
2284 ********************************************************************/
2285 void lp_copy_service(int snum, char *new_name)
2287 char *oldname = lp_servicename(snum);
2288 do_section(new_name);
2290 snum = lp_servicenumber(new_name);
2292 lp_do_parameter(snum, "copy", oldname);
2297 /*******************************************************************
2298 Get the default server type we will announce as via nmbd.
2299 ********************************************************************/
2300 int lp_default_server_announce(void)
2302 return default_server_announce;
2305 /*******************************************************************
2306 Split the announce version into major and minor numbers.
2307 ********************************************************************/
2308 int lp_major_announce_version(void)
2310 static BOOL got_major = False;
2311 static int major_version = DEFAULT_MAJOR_VERSION;
2316 return major_version;
2319 if((vers = lp_announce_version()) == NULL)
2320 return major_version;
2322 if((p = strchr(vers, '.')) == 0)
2323 return major_version;
2326 major_version = atoi(vers);
2327 return major_version;
2330 int lp_minor_announce_version(void)
2332 static BOOL got_minor = False;
2333 static int minor_version = DEFAULT_MINOR_VERSION;
2338 return minor_version;
2341 if((vers = lp_announce_version()) == NULL)
2342 return minor_version;
2344 if((p = strchr(vers, '.')) == 0)
2345 return minor_version;
2348 minor_version = atoi(p);
2349 return minor_version;