Large changes from jra@cygnus.com. Mainly browser updates.
[Samba.git] / source / param / loadparm.c
blob64dd01eeafa94c6d656ca7ac048de2bfd10685d7
1 /*
2 Unix SMB/Netbios implementation.
3 Version 1.9.
4 Parameter loading functions
5 Copyright (C) Karl Auer 1993,1994
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.
25 * Load parameters.
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.
31 * To add a parameter:
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
40 * Notes:
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
46 * careful!
50 #include "includes.h"
52 BOOL bLoaded = False;
54 extern int DEBUGLEVEL;
55 extern pstring user_socket_options;
56 extern pstring myname;
58 #ifndef GLOBAL_NAME
59 #define GLOBAL_NAME "global"
60 #endif
62 #ifndef PRINTCAP_NAME
63 #ifdef AIX
64 #define PRINTCAP_NAME "/etc/qconfig"
65 #else
66 #define PRINTCAP_NAME "/etc/printcap"
67 #endif
68 #endif
70 #ifndef PRINTERS_NAME
71 #define PRINTERS_NAME "printers"
72 #endif
74 #ifndef HOMES_NAME
75 #define HOMES_NAME "homes"
76 #endif
78 /* some helpful bits */
79 #define pSERVICE(i) ServicePtrs[i]
80 #define iSERVICE(i) (*pSERVICE(i))
81 #define LP_SNUM_OK(iService) (((iService) >= 0) && ((iService) < iNumServices) && iSERVICE(iService).valid)
82 #define VALID(i) iSERVICE(i).valid
84 /* these are the types of parameter we have */
85 typedef enum
87 P_BOOL,P_BOOLREV,P_CHAR,P_INTEGER,P_OCTAL,
88 P_STRING,P_USTRING,P_GSTRING,P_UGSTRING
89 } parm_type;
91 typedef enum
93 P_LOCAL,P_GLOBAL,P_NONE
94 } parm_class;
96 int keepalive=0;
97 extern BOOL use_getwd_cache;
99 extern int extra_time_offset;
100 #ifdef KANJI
101 extern int coding_system;
102 #endif
105 * This structure describes global (ie., server-wide) parameters.
107 typedef struct
109 char *szPrintcapname;
110 char *szLockDir;
111 char *szRootdir;
112 char *szDefaultService;
113 char *szDfree;
114 char *szMsgCommand;
115 char *szHostsEquiv;
116 char *szServerString;
117 char *szAutoServices;
118 char *szPasswdProgram;
119 char *szPasswdChat;
120 char *szLogFile;
121 char *szConfigFile;
122 char *szSMBPasswdFile;
123 char *szPasswordServer;
124 char *szSocketOptions;
125 char *szValidChars;
126 char *szWorkGroup;
127 char *szDomainController;
128 char *szUsernameMap;
129 char *szCharacterSet;
130 char *szLogonScript;
131 char *szLogonPath;
132 char *szVetoFiles;
133 char *szSmbrun;
134 char *szWINSserver;
135 char *szInterfaces;
136 char *szRemoteAnnounce;
137 char *szSocketAddress;
138 int max_log_size;
139 int mangled_stack;
140 int max_xmit;
141 int max_mux;
142 int max_packet;
143 int pwordlevel;
144 int deadtime;
145 int maxprotocol;
146 int security;
147 int printing;
148 int maxdisksize;
149 int lpqcachetime;
150 int syslog;
151 int os_level;
152 int max_ttl;
153 int ReadSize;
154 BOOL bWINSsupport;
155 BOOL bWINSproxy;
156 BOOL bPreferredMaster;
157 BOOL bDomainMaster;
158 BOOL bDomainLogons;
159 BOOL bEncryptPasswords;
160 BOOL bStripDot;
161 BOOL bNullPasswords;
162 BOOL bLoadPrinters;
163 BOOL bUseRhosts;
164 BOOL bReadRaw;
165 BOOL bWriteRaw;
166 BOOL bReadPrediction;
167 BOOL bReadbmpx;
168 BOOL bSyslogOnly;
169 BOOL bBrowseList;
170 } global;
172 static global Globals;
177 * This structure describes a single service.
179 typedef struct
181 BOOL valid;
182 char *szService;
183 char *szPath;
184 char *szUsername;
185 char *szGuestaccount;
186 char *szInvalidUsers;
187 char *szValidUsers;
188 char *szAdminUsers;
189 char *szCopy;
190 char *szInclude;
191 char *szPreExec;
192 char *szPostExec;
193 char *szRootPreExec;
194 char *szRootPostExec;
195 char *szPrintcommand;
196 char *szLpqcommand;
197 char *szLprmcommand;
198 char *szLppausecommand;
199 char *szLpresumecommand;
200 char *szPrintername;
201 char *szPrinterDriver;
202 char *szDontdescend;
203 char *szHostsallow;
204 char *szHostsdeny;
205 char *szMagicScript;
206 char *szMagicOutput;
207 char *szMangledMap;
208 char *comment;
209 char *force_user;
210 char *force_group;
211 char *readlist;
212 char *writelist;
213 char *volume;
214 int iMinPrintSpace;
215 int iCreate_mode;
216 int iDir_mode;
217 int iMaxConnections;
218 int iDefaultCase;
219 BOOL bAlternatePerm;
220 BOOL bRevalidate;
221 BOOL bCaseSensitive;
222 BOOL bCasePreserve;
223 BOOL bShortCasePreserve;
224 BOOL bCaseMangle;
225 BOOL status;
226 BOOL bHideDotFiles;
227 BOOL bBrowseable;
228 BOOL bAvailable;
229 BOOL bRead_only;
230 BOOL bNo_set_dir;
231 BOOL bGuest_only;
232 BOOL bGuest_ok;
233 BOOL bPrint_ok;
234 BOOL bPostscript;
235 BOOL bMap_system;
236 BOOL bMap_hidden;
237 BOOL bMap_archive;
238 BOOL bLocking;
239 BOOL bStrictLocking;
240 BOOL bShareModes;
241 BOOL bOnlyUser;
242 BOOL bMangledNames;
243 BOOL bWidelinks;
244 BOOL bSyncAlways;
245 char magic_char;
246 BOOL *copymap;
247 BOOL bDeleteReadonly;
248 BOOL bFakeOplocks;
249 char dummy[3]; /* for alignment */
250 } service;
253 /* This is a default service used to prime a services structure */
254 static service sDefault =
256 True, /* valid */
257 NULL, /* szService */
258 NULL, /* szPath */
259 NULL, /* szUsername */
260 NULL, /* szGuestAccount */
261 NULL, /* szInvalidUsers */
262 NULL, /* szValidUsers */
263 NULL, /* szAdminUsers */
264 NULL, /* szCopy */
265 NULL, /* szInclude */
266 NULL, /* szPreExec */
267 NULL, /* szPostExec */
268 NULL, /* szRootPreExec */
269 NULL, /* szRootPostExec */
270 NULL, /* szPrintcommand */
271 NULL, /* szLpqcommand */
272 NULL, /* szLprmcommand */
273 NULL, /* szLppausecommand */
274 NULL, /* szLpresumecommand */
275 NULL, /* szPrintername */
276 NULL, /* szPrinterDriver */
277 NULL, /* szDontdescend */
278 NULL, /* szHostsallow */
279 NULL, /* szHostsdeny */
280 NULL, /* szMagicScript */
281 NULL, /* szMagicOutput */
282 NULL, /* szMangledMap */
283 NULL, /* comment */
284 NULL, /* force user */
285 NULL, /* force group */
286 NULL, /* readlist */
287 NULL, /* writelist */
288 NULL, /* volume */
289 0, /* iMinPrintSpace */
290 0644, /* iCreate_mode */
291 0755, /* iDir_mode */
292 0, /* iMaxConnections */
293 CASE_LOWER, /* iDefaultCase */
294 False, /* bAlternatePerm */
295 False, /* revalidate */
296 False, /* case sensitive */
297 False, /* case preserve */
298 False, /* short case preserve */
299 False, /* case mangle */
300 True, /* status */
301 True, /* bHideDotFiles */
302 True, /* bBrowseable */
303 True, /* bAvailable */
304 True, /* bRead_only */
305 True, /* bNo_set_dir */
306 False, /* bGuest_only */
307 False, /* bGuest_ok */
308 False, /* bPrint_ok */
309 False, /* bPostscript */
310 False, /* bMap_system */
311 False, /* bMap_hidden */
312 True, /* bMap_archive */
313 True, /* bLocking */
314 False, /* bStrictLocking */
315 True, /* bShareModes */
316 False, /* bOnlyUser */
317 True, /* bMangledNames */
318 True, /* bWidelinks */
319 False, /* bSyncAlways */
320 '~', /* magic char */
321 NULL, /* copymap */
322 False, /* bDeleteReadonly */
323 False, /* bFakeOplocks */
324 "" /* dummy */
329 /* local variables */
330 static service **ServicePtrs = NULL;
331 static int iNumServices = 0;
332 static int iServiceIndex = 0;
333 static BOOL bInGlobalSection = True;
334 static BOOL bGlobalOnly = False;
337 #define NUMPARAMETERS (sizeof(parm_table) / sizeof(struct parm_struct))
339 /* prototypes for the special type handlers */
340 static BOOL handle_valid_chars(char *pszParmValue, char **ptr);
341 static BOOL handle_include(char *pszParmValue, char **ptr);
342 static BOOL handle_copy(char *pszParmValue, char **ptr);
343 static BOOL handle_protocol(char *pszParmValue,int *val);
344 static BOOL handle_security(char *pszParmValue,int *val);
345 static BOOL handle_case(char *pszParmValue,int *val);
346 static BOOL handle_printing(char *pszParmValue,int *val);
347 static BOOL handle_character_set(char *pszParmValue,int *val);
348 #ifdef KANJI
349 static BOOL handle_coding_system(char *pszParmValue,int *val);
350 #endif /* KANJI */
352 struct parm_struct
354 char *label;
355 parm_type type;
356 parm_class class;
357 void *ptr;
358 BOOL (*special)();
359 } parm_table[] =
361 {"debuglevel", P_INTEGER, P_GLOBAL, &DEBUGLEVEL, NULL},
362 {"log level", P_INTEGER, P_GLOBAL, &DEBUGLEVEL, NULL},
363 {"syslog", P_INTEGER, P_GLOBAL, &Globals.syslog, NULL},
364 {"syslog only", P_BOOL, P_GLOBAL, &Globals.bSyslogOnly, NULL},
365 {"protocol", P_INTEGER, P_GLOBAL, &Globals.maxprotocol,handle_protocol},
366 {"security", P_INTEGER, P_GLOBAL, &Globals.security,handle_security},
367 {"printing", P_INTEGER, P_GLOBAL, &Globals.printing,handle_printing},
368 {"max disk size", P_INTEGER, P_GLOBAL, &Globals.maxdisksize, NULL},
369 {"lpq cache time", P_INTEGER, P_GLOBAL, &Globals.lpqcachetime, NULL},
370 {"encrypt passwords",P_BOOL, P_GLOBAL, &Globals.bEncryptPasswords, NULL},
371 {"getwd cache", P_BOOL, P_GLOBAL, &use_getwd_cache, NULL},
372 {"read prediction", P_BOOL, P_GLOBAL, &Globals.bReadPrediction, NULL},
373 {"read bmpx", P_BOOL, P_GLOBAL, &Globals.bReadbmpx, NULL},
374 {"read raw", P_BOOL, P_GLOBAL, &Globals.bReadRaw, NULL},
375 {"write raw", P_BOOL, P_GLOBAL, &Globals.bWriteRaw, NULL},
376 {"use rhosts", P_BOOL, P_GLOBAL, &Globals.bUseRhosts, NULL},
377 {"load printers", P_BOOL, P_GLOBAL, &Globals.bLoadPrinters, NULL},
378 {"null passwords", P_BOOL, P_GLOBAL, &Globals.bNullPasswords, NULL},
379 {"strip dot", P_BOOL, P_GLOBAL, &Globals.bStripDot, NULL},
380 {"interfaces", P_STRING, P_GLOBAL, &Globals.szInterfaces, NULL},
381 {"password server", P_STRING, P_GLOBAL, &Globals.szPasswordServer, NULL},
382 {"socket options", P_GSTRING, P_GLOBAL, user_socket_options, NULL},
383 {"netbios name", P_UGSTRING,P_GLOBAL, myname, NULL},
384 {"smbrun", P_STRING, P_GLOBAL, &Globals.szSmbrun, NULL},
385 {"veto files", P_STRING, P_GLOBAL, &Globals.szVetoFiles, NULL},
386 {"log file", P_STRING, P_GLOBAL, &Globals.szLogFile, NULL},
387 {"config file", P_STRING, P_GLOBAL, &Globals.szConfigFile, NULL},
388 {"smb passwd file", P_STRING, P_GLOBAL, &Globals.szSMBPasswdFile, NULL},
389 {"hosts equiv", P_STRING, P_GLOBAL, &Globals.szHostsEquiv, NULL},
390 {"preload", P_STRING, P_GLOBAL, &Globals.szAutoServices, NULL},
391 {"auto services", P_STRING, P_GLOBAL, &Globals.szAutoServices, NULL},
392 {"server string", P_STRING, P_GLOBAL, &Globals.szServerString, NULL},
393 {"printcap name", P_STRING, P_GLOBAL, &Globals.szPrintcapname, NULL},
394 {"printcap", P_STRING, P_GLOBAL, &Globals.szPrintcapname, NULL},
395 {"lock dir", P_STRING, P_GLOBAL, &Globals.szLockDir, NULL},
396 {"lock directory", P_STRING, P_GLOBAL, &Globals.szLockDir, NULL},
397 {"root directory", P_STRING, P_GLOBAL, &Globals.szRootdir, NULL},
398 {"root dir", P_STRING, P_GLOBAL, &Globals.szRootdir, NULL},
399 {"root", P_STRING, P_GLOBAL, &Globals.szRootdir, NULL},
400 {"default service", P_STRING, P_GLOBAL, &Globals.szDefaultService, NULL},
401 {"default", P_STRING, P_GLOBAL, &Globals.szDefaultService, NULL},
402 {"message command", P_STRING, P_GLOBAL, &Globals.szMsgCommand, NULL},
403 {"dfree command", P_STRING, P_GLOBAL, &Globals.szDfree, NULL},
404 {"passwd program", P_STRING, P_GLOBAL, &Globals.szPasswdProgram, NULL},
405 {"passwd chat", P_STRING, P_GLOBAL, &Globals.szPasswdChat, NULL},
406 {"valid chars", P_STRING, P_GLOBAL, &Globals.szValidChars, handle_valid_chars},
407 {"workgroup", P_USTRING, P_GLOBAL, &Globals.szWorkGroup, NULL},
408 {"domain controller",P_STRING, P_GLOBAL, &Globals.szDomainController,NULL},
409 {"username map", P_STRING, P_GLOBAL, &Globals.szUsernameMap, NULL},
410 {"character set", P_STRING, P_GLOBAL, &Globals.szCharacterSet, handle_character_set},
411 {"logon script", P_STRING, P_GLOBAL, &Globals.szLogonScript, NULL},
412 {"logon path", P_STRING, P_GLOBAL, &Globals.szLogonPath, NULL},
413 {"remote announce", P_STRING, P_GLOBAL, &Globals.szRemoteAnnounce, NULL},
414 {"socket address", P_STRING, P_GLOBAL, &Globals.szSocketAddress, NULL},
415 {"max log size", P_INTEGER, P_GLOBAL, &Globals.max_log_size, NULL},
416 {"mangled stack", P_INTEGER, P_GLOBAL, &Globals.mangled_stack, NULL},
417 {"max mux", P_INTEGER, P_GLOBAL, &Globals.max_mux, NULL},
418 {"max xmit", P_INTEGER, P_GLOBAL, &Globals.max_xmit, NULL},
419 {"max packet", P_INTEGER, P_GLOBAL, &Globals.max_packet, NULL},
420 {"packet size", P_INTEGER, P_GLOBAL, &Globals.max_packet, NULL},
421 {"password level", P_INTEGER, P_GLOBAL, &Globals.pwordlevel, NULL},
422 {"keepalive", P_INTEGER, P_GLOBAL, &keepalive, NULL},
423 {"deadtime", P_INTEGER, P_GLOBAL, &Globals.deadtime, NULL},
424 {"time offset", P_INTEGER, P_GLOBAL, &extra_time_offset, NULL},
425 {"read size", P_INTEGER, P_GLOBAL, &Globals.ReadSize, NULL},
426 #ifdef KANJI
427 {"coding system", P_INTEGER, P_GLOBAL, &coding_system, handle_coding_system},
428 #endif /* KANJI */
429 {"os level", P_INTEGER, P_GLOBAL, &Globals.os_level, NULL},
430 {"max ttl", P_INTEGER, P_GLOBAL, &Globals.max_ttl, NULL},
431 {"wins support", P_BOOL, P_GLOBAL, &Globals.bWINSsupport, NULL},
432 {"wins proxy", P_BOOL, P_GLOBAL, &Globals.bWINSproxy, NULL},
433 {"wins server", P_STRING, P_GLOBAL, &Globals.szWINSserver, NULL},
434 {"preferred master", P_BOOL, P_GLOBAL, &Globals.bPreferredMaster, NULL},
435 {"prefered master", P_BOOL, P_GLOBAL, &Globals.bPreferredMaster, NULL},
436 {"domain master", P_BOOL, P_GLOBAL, &Globals.bDomainMaster, NULL},
437 {"domain logons", P_BOOL, P_GLOBAL, &Globals.bDomainLogons, NULL},
438 {"browse list", P_BOOL, P_GLOBAL, &Globals.bBrowseList, NULL},
440 {"-valid", P_BOOL, P_LOCAL, &sDefault.valid, NULL},
441 {"comment", P_STRING, P_LOCAL, &sDefault.comment, NULL},
442 {"copy", P_STRING, P_LOCAL, &sDefault.szCopy, handle_copy},
443 {"include", P_STRING, P_LOCAL, &sDefault.szInclude, handle_include},
444 {"exec", P_STRING, P_LOCAL, &sDefault.szPreExec, NULL},
445 {"preexec", P_STRING, P_LOCAL, &sDefault.szPreExec, NULL},
446 {"postexec", P_STRING, P_LOCAL, &sDefault.szPostExec, NULL},
447 {"root preexec", P_STRING, P_LOCAL, &sDefault.szRootPreExec, NULL},
448 {"root postexec", P_STRING, P_LOCAL, &sDefault.szRootPostExec, NULL},
449 {"alternate permissions",P_BOOL,P_LOCAL, &sDefault.bAlternatePerm, NULL},
450 {"revalidate", P_BOOL, P_LOCAL, &sDefault.bRevalidate, NULL},
451 {"default case", P_INTEGER, P_LOCAL, &sDefault.iDefaultCase, handle_case},
452 {"case sensitive", P_BOOL, P_LOCAL, &sDefault.bCaseSensitive, NULL},
453 {"casesignames", P_BOOL, P_LOCAL, &sDefault.bCaseSensitive, NULL},
454 {"preserve case", P_BOOL, P_LOCAL, &sDefault.bCasePreserve, NULL},
455 {"short preserve case",P_BOOL, P_LOCAL, &sDefault.bShortCasePreserve,NULL},
456 {"mangle case", P_BOOL, P_LOCAL, &sDefault.bCaseMangle, NULL},
457 {"mangling char", P_CHAR, P_LOCAL, &sDefault.magic_char, NULL},
458 {"browseable", P_BOOL, P_LOCAL, &sDefault.bBrowseable, NULL},
459 {"browsable", P_BOOL, P_LOCAL, &sDefault.bBrowseable, NULL},
460 {"available", P_BOOL, P_LOCAL, &sDefault.bAvailable, NULL},
461 {"path", P_STRING, P_LOCAL, &sDefault.szPath, NULL},
462 {"directory", P_STRING, P_LOCAL, &sDefault.szPath, NULL},
463 {"username", P_STRING, P_LOCAL, &sDefault.szUsername, NULL},
464 {"user", P_STRING, P_LOCAL, &sDefault.szUsername, NULL},
465 {"users", P_STRING, P_LOCAL, &sDefault.szUsername, NULL},
466 {"guest account", P_STRING, P_LOCAL, &sDefault.szGuestaccount, NULL},
467 {"invalid users", P_STRING, P_LOCAL, &sDefault.szInvalidUsers, NULL},
468 {"valid users", P_STRING, P_LOCAL, &sDefault.szValidUsers, NULL},
469 {"admin users", P_STRING, P_LOCAL, &sDefault.szAdminUsers, NULL},
470 {"read list", P_STRING, P_LOCAL, &sDefault.readlist, NULL},
471 {"write list", P_STRING, P_LOCAL, &sDefault.writelist, NULL},
472 {"volume", P_STRING, P_LOCAL, &sDefault.volume, NULL},
473 {"force user", P_STRING, P_LOCAL, &sDefault.force_user, NULL},
474 {"force group", P_STRING, P_LOCAL, &sDefault.force_group, NULL},
475 {"group", P_STRING, P_LOCAL, &sDefault.force_group, NULL},
476 {"read only", P_BOOL, P_LOCAL, &sDefault.bRead_only, NULL},
477 {"write ok", P_BOOLREV, P_LOCAL, &sDefault.bRead_only, NULL},
478 {"writeable", P_BOOLREV, P_LOCAL, &sDefault.bRead_only, NULL},
479 {"writable", P_BOOLREV, P_LOCAL, &sDefault.bRead_only, NULL},
480 {"max connections", P_INTEGER, P_LOCAL, &sDefault.iMaxConnections, NULL},
481 {"min print space", P_INTEGER, P_LOCAL, &sDefault.iMinPrintSpace, NULL},
482 {"create mask", P_OCTAL, P_LOCAL, &sDefault.iCreate_mode, NULL},
483 {"create mode", P_OCTAL, P_LOCAL, &sDefault.iCreate_mode, NULL},
484 {"directory mask", P_OCTAL, P_LOCAL, &sDefault.iDir_mode, NULL},
485 {"directory mode", P_OCTAL, P_LOCAL, &sDefault.iDir_mode, NULL},
486 {"set directory", P_BOOLREV, P_LOCAL, &sDefault.bNo_set_dir, NULL},
487 {"status", P_BOOL, P_LOCAL, &sDefault.status, NULL},
488 {"hide dot files", P_BOOL, P_LOCAL, &sDefault.bHideDotFiles, NULL},
489 {"guest only", P_BOOL, P_LOCAL, &sDefault.bGuest_only, NULL},
490 {"only guest", P_BOOL, P_LOCAL, &sDefault.bGuest_only, NULL},
491 {"guest ok", P_BOOL, P_LOCAL, &sDefault.bGuest_ok, NULL},
492 {"public", P_BOOL, P_LOCAL, &sDefault.bGuest_ok, NULL},
493 {"print ok", P_BOOL, P_LOCAL, &sDefault.bPrint_ok, NULL},
494 {"printable", P_BOOL, P_LOCAL, &sDefault.bPrint_ok, NULL},
495 {"postscript", P_BOOL, P_LOCAL, &sDefault.bPostscript, NULL},
496 {"map system", P_BOOL, P_LOCAL, &sDefault.bMap_system, NULL},
497 {"map hidden", P_BOOL, P_LOCAL, &sDefault.bMap_hidden, NULL},
498 {"map archive", P_BOOL, P_LOCAL, &sDefault.bMap_archive, NULL},
499 {"locking", P_BOOL, P_LOCAL, &sDefault.bLocking, NULL},
500 {"strict locking", P_BOOL, P_LOCAL, &sDefault.bStrictLocking, NULL},
501 {"share modes", P_BOOL, P_LOCAL, &sDefault.bShareModes, NULL},
502 {"only user", P_BOOL, P_LOCAL, &sDefault.bOnlyUser, NULL},
503 {"wide links", P_BOOL, P_LOCAL, &sDefault.bWidelinks, NULL},
504 {"sync always", P_BOOL, P_LOCAL, &sDefault.bSyncAlways, NULL},
505 {"mangled names", P_BOOL, P_LOCAL, &sDefault.bMangledNames, NULL},
506 {"fake oplocks", P_BOOL, P_LOCAL, &sDefault.bFakeOplocks, NULL},
507 {"print command", P_STRING, P_LOCAL, &sDefault.szPrintcommand, NULL},
508 {"lpq command", P_STRING, P_LOCAL, &sDefault.szLpqcommand, NULL},
509 {"lprm command", P_STRING, P_LOCAL, &sDefault.szLprmcommand, NULL},
510 {"lppause command", P_STRING, P_LOCAL, &sDefault.szLppausecommand, NULL},
511 {"lpresume command", P_STRING, P_LOCAL, &sDefault.szLpresumecommand,NULL},
512 {"printer", P_STRING, P_LOCAL, &sDefault.szPrintername, NULL},
513 {"printer name", P_STRING, P_LOCAL, &sDefault.szPrintername, NULL},
514 {"printer driver", P_STRING, P_LOCAL, &sDefault.szPrinterDriver, NULL},
515 {"hosts allow", P_STRING, P_LOCAL, &sDefault.szHostsallow, NULL},
516 {"allow hosts", P_STRING, P_LOCAL, &sDefault.szHostsallow, NULL},
517 {"hosts deny", P_STRING, P_LOCAL, &sDefault.szHostsdeny, NULL},
518 {"deny hosts", P_STRING, P_LOCAL, &sDefault.szHostsdeny, NULL},
519 {"dont descend", P_STRING, P_LOCAL, &sDefault.szDontdescend, NULL},
520 {"magic script", P_STRING, P_LOCAL, &sDefault.szMagicScript, NULL},
521 {"magic output", P_STRING, P_LOCAL, &sDefault.szMagicOutput, NULL},
522 {"mangled map", P_STRING, P_LOCAL, &sDefault.szMangledMap, NULL},
523 {"delete readonly", P_BOOL, P_LOCAL, &sDefault.bDeleteReadonly, NULL},
525 {NULL, P_BOOL, P_NONE, NULL, NULL}
530 /***************************************************************************
531 Initialise the global parameter structure.
532 ***************************************************************************/
533 static void init_globals(void)
535 static BOOL done_init = False;
536 pstring s;
538 if (!done_init)
540 int i;
541 bzero((void *)&Globals,sizeof(Globals));
543 for (i = 0; parm_table[i].label; i++)
544 if ((parm_table[i].type == P_STRING ||
545 parm_table[i].type == P_USTRING) &&
546 parm_table[i].ptr)
547 string_init(parm_table[i].ptr,"");
549 string_set(&sDefault.szGuestaccount, GUEST_ACCOUNT);
550 string_set(&sDefault.szPrinterDriver, "NULL");
552 done_init = True;
556 DEBUG(3,("Initialising global parameters\n"));
558 #ifdef SMB_PASSWD_FILE
559 string_set(&Globals.szSMBPasswdFile, SMB_PASSWD_FILE);
560 #endif
561 string_set(&Globals.szPasswdChat,"*old*password* %o\\n *new*password* %n\\n *new*password* %n\\n *changed*");
562 string_set(&Globals.szWorkGroup, WORKGROUP);
563 #ifdef SMB_PASSWD
564 string_set(&Globals.szPasswdProgram, SMB_PASSWD);
565 #else
566 string_set(&Globals.szPasswdProgram, "/bin/passwd");
567 #endif
568 string_set(&Globals.szPrintcapname, PRINTCAP_NAME);
569 string_set(&Globals.szLockDir, LOCKDIR);
570 string_set(&Globals.szRootdir, "/");
571 string_set(&Globals.szSmbrun, SMBRUN);
572 string_set(&Globals.szSocketAddress, "0.0.0.0");
573 sprintf(s,"Samba %s",VERSION);
574 string_set(&Globals.szServerString,s);
575 Globals.bLoadPrinters = True;
576 Globals.bUseRhosts = False;
577 Globals.max_packet = 65535;
578 Globals.mangled_stack = 50;
579 Globals.max_xmit = Globals.max_packet;
580 Globals.max_mux = 2;
581 Globals.lpqcachetime = 10;
582 Globals.pwordlevel = 0;
583 Globals.deadtime = 0;
584 Globals.max_log_size = 5000;
585 Globals.maxprotocol = PROTOCOL_NT1;
586 Globals.security = SEC_SHARE;
587 Globals.bEncryptPasswords = False;
588 Globals.printing = DEFAULT_PRINTING;
589 Globals.bReadRaw = True;
590 Globals.bWriteRaw = True;
591 Globals.bReadPrediction = False;
592 Globals.bReadbmpx = True;
593 Globals.bNullPasswords = False;
594 Globals.bStripDot = False;
595 Globals.syslog = 1;
596 Globals.bSyslogOnly = False;
597 Globals.os_level = 0;
598 Globals.max_ttl = 60*60*4; /* 2 hours default */
599 Globals.bPreferredMaster = True;
600 Globals.bDomainMaster = False;
601 Globals.bDomainLogons = False;
602 Globals.bBrowseList = True;
603 Globals.bWINSsupport = False;
604 Globals.bWINSproxy = False;
605 Globals.ReadSize = 16*1024;
607 #ifdef KANJI
608 coding_system = interpret_coding_system (KANJI, SJIS_CODE);
609 #endif /* KANJI */
613 /***************************************************************************
614 check if a string is initialised and if not then initialise it
615 ***************************************************************************/
616 static void string_initial(char **s,char *v)
618 if (!*s || !**s)
619 string_init(s,v);
623 /***************************************************************************
624 Initialise the sDefault parameter structure.
625 ***************************************************************************/
626 static void init_locals(void)
628 /* choose defaults depending on the type of printing */
629 switch (Globals.printing)
631 case PRINT_BSD:
632 case PRINT_AIX:
633 case PRINT_LPRNG:
634 case PRINT_PLP:
635 string_initial(&sDefault.szLpqcommand,"lpq -P%p");
636 string_initial(&sDefault.szLprmcommand,"lprm -P%p %j");
637 string_initial(&sDefault.szPrintcommand,"lpr -r -P%p %s");
638 break;
640 case PRINT_SYSV:
641 case PRINT_HPUX:
642 string_initial(&sDefault.szLpqcommand,"lpstat -o%p");
643 string_initial(&sDefault.szLprmcommand,"cancel %p-%j");
644 string_initial(&sDefault.szPrintcommand,"lp -c -d%p %s; rm %s");
645 #ifdef SVR4
646 string_initial(&sDefault.szLppausecommand,"lp -i %p-%j -H hold");
647 string_initial(&sDefault.szLpresumecommand,"lp -i %p-%j -H resume");
648 #endif
649 break;
651 case PRINT_QNX:
652 string_initial(&sDefault.szLpqcommand,"lpq -P%p");
653 string_initial(&sDefault.szLprmcommand,"lprm -P%p %j");
654 string_initial(&sDefault.szPrintcommand,"lp -r -P%p %s");
655 break;
662 /******************************************************************* a
663 convenience routine to grab string parameters into a rotating buffer,
664 and run standard_sub_basic on them. The buffers can be written to by
665 callers without affecting the source string.
666 ********************************************************************/
667 char *lp_string(char *s)
669 static char *bufs[10];
670 static int buflen[10];
671 static int next = -1;
672 char *ret;
673 int i;
674 int len = s?strlen(s):0;
676 if (next == -1) {
677 /* initialisation */
678 for (i=0;i<10;i++) {
679 bufs[i] = NULL;
680 buflen[i] = 0;
682 next = 0;
685 len = MAX(len+100,sizeof(pstring)); /* the +100 is for some
686 substitution room */
688 if (buflen[next] != len) {
689 buflen[next] = len;
690 if (bufs[next]) free(bufs[next]);
691 bufs[next] = (char *)malloc(len);
692 if (!bufs[next]) {
693 DEBUG(0,("out of memory in lp_string()"));
694 exit(1);
698 ret = &bufs[next][0];
699 next = (next+1)%10;
701 if (!s)
702 *ret = 0;
703 else
704 StrCpy(ret,s);
706 standard_sub_basic(ret);
707 return(ret);
712 In this section all the functions that are used to access the
713 parameters from the rest of the program are defined
716 #define FN_GLOBAL_STRING(fn_name,ptr) \
717 char *fn_name(void) {return(lp_string(*(char **)(ptr) ? *(char **)(ptr) : ""));}
718 #define FN_GLOBAL_BOOL(fn_name,ptr) \
719 BOOL fn_name(void) {return(*(BOOL *)(ptr));}
720 #define FN_GLOBAL_CHAR(fn_name,ptr) \
721 char fn_name(void) {return(*(char *)(ptr));}
722 #define FN_GLOBAL_INTEGER(fn_name,ptr) \
723 int fn_name(void) {return(*(int *)(ptr));}
725 #define FN_LOCAL_STRING(fn_name,val) \
726 char *fn_name(int i) {return(lp_string((LP_SNUM_OK(i)&&pSERVICE(i)->val)?pSERVICE(i)->val : sDefault.val));}
727 #define FN_LOCAL_BOOL(fn_name,val) \
728 BOOL fn_name(int i) {return(LP_SNUM_OK(i)? pSERVICE(i)->val : sDefault.val);}
729 #define FN_LOCAL_CHAR(fn_name,val) \
730 char fn_name(int i) {return(LP_SNUM_OK(i)? pSERVICE(i)->val : sDefault.val);}
731 #define FN_LOCAL_INTEGER(fn_name,val) \
732 int fn_name(int i) {return(LP_SNUM_OK(i)? pSERVICE(i)->val : sDefault.val);}
734 FN_GLOBAL_STRING(lp_logfile,&Globals.szLogFile)
735 FN_GLOBAL_STRING(lp_smbrun,&Globals.szSmbrun)
736 FN_GLOBAL_STRING(lp_configfile,&Globals.szConfigFile)
737 FN_GLOBAL_STRING(lp_smb_passwd_file,&Globals.szSMBPasswdFile)
738 FN_GLOBAL_STRING(lp_serverstring,&Globals.szServerString)
739 FN_GLOBAL_STRING(lp_printcapname,&Globals.szPrintcapname)
740 FN_GLOBAL_STRING(lp_lockdir,&Globals.szLockDir)
741 FN_GLOBAL_STRING(lp_rootdir,&Globals.szRootdir)
742 FN_GLOBAL_STRING(lp_defaultservice,&Globals.szDefaultService)
743 FN_GLOBAL_STRING(lp_msg_command,&Globals.szMsgCommand)
744 FN_GLOBAL_STRING(lp_dfree_command,&Globals.szDfree)
745 FN_GLOBAL_STRING(lp_hosts_equiv,&Globals.szHostsEquiv)
746 FN_GLOBAL_STRING(lp_auto_services,&Globals.szAutoServices)
747 FN_GLOBAL_STRING(lp_passwd_program,&Globals.szPasswdProgram)
748 FN_GLOBAL_STRING(lp_passwd_chat,&Globals.szPasswdChat)
749 FN_GLOBAL_STRING(lp_passwordserver,&Globals.szPasswordServer)
750 FN_GLOBAL_STRING(lp_workgroup,&Globals.szWorkGroup)
751 FN_GLOBAL_STRING(lp_domain_controller,&Globals.szDomainController)
752 FN_GLOBAL_STRING(lp_username_map,&Globals.szUsernameMap)
753 FN_GLOBAL_STRING(lp_character_set,&Globals.szCharacterSet)
754 FN_GLOBAL_STRING(lp_logon_script,&Globals.szLogonScript)
755 FN_GLOBAL_STRING(lp_logon_path,&Globals.szLogonPath)
756 FN_GLOBAL_STRING(lp_veto_files,&Globals.szVetoFiles)
757 FN_GLOBAL_STRING(lp_remote_announce,&Globals.szRemoteAnnounce)
758 FN_GLOBAL_STRING(lp_wins_server,&Globals.szWINSserver)
759 FN_GLOBAL_STRING(lp_interfaces,&Globals.szInterfaces)
760 FN_GLOBAL_STRING(lp_socket_address,&Globals.szSocketAddress)
762 FN_GLOBAL_BOOL(lp_wins_support,&Globals.bWINSsupport)
763 FN_GLOBAL_BOOL(lp_wins_proxy,&Globals.bWINSproxy)
764 FN_GLOBAL_BOOL(lp_domain_master,&Globals.bDomainMaster)
765 FN_GLOBAL_BOOL(lp_domain_logons,&Globals.bDomainLogons)
766 FN_GLOBAL_BOOL(lp_preferred_master,&Globals.bPreferredMaster)
767 FN_GLOBAL_BOOL(lp_load_printers,&Globals.bLoadPrinters)
768 FN_GLOBAL_BOOL(lp_use_rhosts,&Globals.bUseRhosts)
769 FN_GLOBAL_BOOL(lp_getwdcache,&use_getwd_cache)
770 FN_GLOBAL_BOOL(lp_readprediction,&Globals.bReadPrediction)
771 FN_GLOBAL_BOOL(lp_readbmpx,&Globals.bReadbmpx)
772 FN_GLOBAL_BOOL(lp_readraw,&Globals.bReadRaw)
773 FN_GLOBAL_BOOL(lp_writeraw,&Globals.bWriteRaw)
774 FN_GLOBAL_BOOL(lp_null_passwords,&Globals.bNullPasswords)
775 FN_GLOBAL_BOOL(lp_strip_dot,&Globals.bStripDot)
776 FN_GLOBAL_BOOL(lp_encrypted_passwords,&Globals.bEncryptPasswords)
777 FN_GLOBAL_BOOL(lp_syslog_only,&Globals.bSyslogOnly)
778 FN_GLOBAL_BOOL(lp_browse_list,&Globals.bBrowseList)
780 FN_GLOBAL_INTEGER(lp_os_level,&Globals.os_level)
781 FN_GLOBAL_INTEGER(lp_max_ttl,&Globals.max_ttl)
782 FN_GLOBAL_INTEGER(lp_max_log_size,&Globals.max_log_size)
783 FN_GLOBAL_INTEGER(lp_mangledstack,&Globals.mangled_stack)
784 FN_GLOBAL_INTEGER(lp_maxxmit,&Globals.max_xmit)
785 FN_GLOBAL_INTEGER(lp_maxmux,&Globals.max_mux)
786 FN_GLOBAL_INTEGER(lp_maxpacket,&Globals.max_packet)
787 FN_GLOBAL_INTEGER(lp_keepalive,&keepalive)
788 FN_GLOBAL_INTEGER(lp_passwordlevel,&Globals.pwordlevel)
789 FN_GLOBAL_INTEGER(lp_readsize,&Globals.ReadSize)
790 FN_GLOBAL_INTEGER(lp_deadtime,&Globals.deadtime)
791 FN_GLOBAL_INTEGER(lp_maxprotocol,&Globals.maxprotocol)
792 FN_GLOBAL_INTEGER(lp_security,&Globals.security)
793 FN_GLOBAL_INTEGER(lp_printing,&Globals.printing)
794 FN_GLOBAL_INTEGER(lp_maxdisksize,&Globals.maxdisksize)
795 FN_GLOBAL_INTEGER(lp_lpqcachetime,&Globals.lpqcachetime)
796 FN_GLOBAL_INTEGER(lp_syslog,&Globals.syslog)
798 FN_LOCAL_STRING(lp_preexec,szPreExec)
799 FN_LOCAL_STRING(lp_postexec,szPostExec)
800 FN_LOCAL_STRING(lp_rootpreexec,szRootPreExec)
801 FN_LOCAL_STRING(lp_rootpostexec,szRootPostExec)
802 FN_LOCAL_STRING(lp_servicename,szService)
803 FN_LOCAL_STRING(lp_pathname,szPath)
804 FN_LOCAL_STRING(lp_dontdescend,szDontdescend)
805 FN_LOCAL_STRING(lp_username,szUsername)
806 FN_LOCAL_STRING(lp_guestaccount,szGuestaccount)
807 FN_LOCAL_STRING(lp_invalid_users,szInvalidUsers)
808 FN_LOCAL_STRING(lp_valid_users,szValidUsers)
809 FN_LOCAL_STRING(lp_admin_users,szAdminUsers)
810 FN_LOCAL_STRING(lp_printcommand,szPrintcommand)
811 FN_LOCAL_STRING(lp_lpqcommand,szLpqcommand)
812 FN_LOCAL_STRING(lp_lprmcommand,szLprmcommand)
813 FN_LOCAL_STRING(lp_lppausecommand,szLppausecommand)
814 FN_LOCAL_STRING(lp_lpresumecommand,szLpresumecommand)
815 FN_LOCAL_STRING(lp_printername,szPrintername)
816 FN_LOCAL_STRING(lp_printerdriver,szPrinterDriver)
817 FN_LOCAL_STRING(lp_hostsallow,szHostsallow)
818 FN_LOCAL_STRING(lp_hostsdeny,szHostsdeny)
819 FN_LOCAL_STRING(lp_magicscript,szMagicScript)
820 FN_LOCAL_STRING(lp_magicoutput,szMagicOutput)
821 FN_LOCAL_STRING(lp_comment,comment)
822 FN_LOCAL_STRING(lp_force_user,force_user)
823 FN_LOCAL_STRING(lp_force_group,force_group)
824 FN_LOCAL_STRING(lp_readlist,readlist)
825 FN_LOCAL_STRING(lp_writelist,writelist)
826 FN_LOCAL_STRING(lp_volume,volume)
827 FN_LOCAL_STRING(lp_mangled_map,szMangledMap)
829 FN_LOCAL_BOOL(lp_alternate_permissions,bAlternatePerm)
830 FN_LOCAL_BOOL(lp_revalidate,bRevalidate)
831 FN_LOCAL_BOOL(lp_casesensitive,bCaseSensitive)
832 FN_LOCAL_BOOL(lp_preservecase,bCasePreserve)
833 FN_LOCAL_BOOL(lp_shortpreservecase,bShortCasePreserve)
834 FN_LOCAL_BOOL(lp_casemangle,bCaseMangle)
835 FN_LOCAL_BOOL(lp_status,status)
836 FN_LOCAL_BOOL(lp_hide_dot_files,bHideDotFiles)
837 FN_LOCAL_BOOL(lp_browseable,bBrowseable)
838 FN_LOCAL_BOOL(lp_readonly,bRead_only)
839 FN_LOCAL_BOOL(lp_no_set_dir,bNo_set_dir)
840 FN_LOCAL_BOOL(lp_guest_ok,bGuest_ok)
841 FN_LOCAL_BOOL(lp_guest_only,bGuest_only)
842 FN_LOCAL_BOOL(lp_print_ok,bPrint_ok)
843 FN_LOCAL_BOOL(lp_postscript,bPostscript)
844 FN_LOCAL_BOOL(lp_map_hidden,bMap_hidden)
845 FN_LOCAL_BOOL(lp_map_archive,bMap_archive)
846 FN_LOCAL_BOOL(lp_locking,bLocking)
847 FN_LOCAL_BOOL(lp_strict_locking,bStrictLocking)
848 FN_LOCAL_BOOL(lp_share_modes,bShareModes)
849 FN_LOCAL_BOOL(lp_onlyuser,bOnlyUser)
850 FN_LOCAL_BOOL(lp_manglednames,bMangledNames)
851 FN_LOCAL_BOOL(lp_widelinks,bWidelinks)
852 FN_LOCAL_BOOL(lp_syncalways,bSyncAlways)
853 FN_LOCAL_BOOL(lp_map_system,bMap_system)
854 FN_LOCAL_BOOL(lp_delete_readonly,bDeleteReadonly)
855 FN_LOCAL_BOOL(lp_fake_oplocks,bFakeOplocks)
857 FN_LOCAL_INTEGER(lp_create_mode,iCreate_mode)
858 FN_LOCAL_INTEGER(lp_dir_mode,iDir_mode)
859 FN_LOCAL_INTEGER(lp_max_connections,iMaxConnections)
860 FN_LOCAL_INTEGER(lp_defaultcase,iDefaultCase)
861 FN_LOCAL_INTEGER(lp_minprintspace,iMinPrintSpace)
863 FN_LOCAL_CHAR(lp_magicchar,magic_char)
867 /* local prototypes */
868 static int strwicmp( char *psz1, char *psz2 );
869 static int map_parameter( char *pszParmName);
870 static BOOL set_boolean( BOOL *pb, char *pszParmValue );
871 static int getservicebyname(char *pszServiceName, service *pserviceDest);
872 static void copy_service( service *pserviceDest,
873 service *pserviceSource,
874 BOOL *pcopymapDest );
875 static BOOL service_ok(int iService);
876 static BOOL do_parameter(char *pszParmName, char *pszParmValue);
877 static BOOL do_section(char *pszSectionName);
878 static void dump_globals(void);
879 static void dump_a_service(service *pService);
880 static void init_copymap(service *pservice);
883 /***************************************************************************
884 initialise a service to the defaults
885 ***************************************************************************/
886 static void init_service(service *pservice)
888 bzero((char *)pservice,sizeof(service));
889 copy_service(pservice,&sDefault,NULL);
893 /***************************************************************************
894 free the dynamically allocated parts of a service struct
895 ***************************************************************************/
896 static void free_service(service *pservice)
898 int i;
899 if (!pservice)
900 return;
902 for (i=0;parm_table[i].label;i++)
903 if ((parm_table[i].type == P_STRING ||
904 parm_table[i].type == P_STRING) &&
905 parm_table[i].class == P_LOCAL)
906 string_free((char **)(((char *)pservice) + PTR_DIFF(parm_table[i].ptr,&sDefault)));
909 /***************************************************************************
910 add a new service to the services array initialising it with the given
911 service
912 ***************************************************************************/
913 static int add_a_service(service *pservice, char *name)
915 int i;
916 service tservice;
917 int num_to_alloc = iNumServices+1;
919 tservice = *pservice;
921 /* it might already exist */
922 if (name)
924 i = getservicebyname(name,NULL);
925 if (i >= 0)
926 return(i);
929 /* find an invalid one */
930 for (i=0;i<iNumServices;i++)
931 if (!pSERVICE(i)->valid)
932 break;
934 /* if not, then create one */
935 if (i == iNumServices)
937 ServicePtrs = (service **)Realloc(ServicePtrs,sizeof(service *)*num_to_alloc);
938 if (ServicePtrs)
939 pSERVICE(iNumServices) = (service *)malloc(sizeof(service));
941 if (!ServicePtrs || !pSERVICE(iNumServices))
942 return(-1);
944 iNumServices++;
946 else
947 free_service(pSERVICE(i));
949 pSERVICE(i)->valid = True;
951 init_service(pSERVICE(i));
952 copy_service(pSERVICE(i),&tservice,NULL);
953 if (name)
954 string_set(&iSERVICE(i).szService,name);
956 return(i);
959 /***************************************************************************
960 add a new home service, with the specified home directory, defaults coming
961 from service ifrom
962 ***************************************************************************/
963 BOOL lp_add_home(char *pszHomename, int iDefaultService, char *pszHomedir)
965 int i = add_a_service(pSERVICE(iDefaultService),pszHomename);
967 if (i < 0)
968 return(False);
970 if (!(*(iSERVICE(i).szPath)) || strequal(iSERVICE(i).szPath,lp_pathname(-1)))
971 string_set(&iSERVICE(i).szPath,pszHomedir);
972 if (!(*(iSERVICE(i).comment)))
974 pstring comment;
975 sprintf(comment,"Home directory of %s",pszHomename);
976 string_set(&iSERVICE(i).comment,comment);
978 iSERVICE(i).bAvailable = sDefault.bAvailable;
979 iSERVICE(i).bBrowseable = sDefault.bBrowseable;
981 DEBUG(3,("adding home directory %s at %s\n", pszHomename, pszHomedir));
983 return(True);
986 /***************************************************************************
987 add a new service, based on an old one
988 ***************************************************************************/
989 int lp_add_service(char *pszService, int iDefaultService)
991 return(add_a_service(pSERVICE(iDefaultService),pszService));
995 /***************************************************************************
996 add the IPC service
997 ***************************************************************************/
998 static BOOL lp_add_ipc(void)
1000 pstring comment;
1001 int i = add_a_service(&sDefault,"IPC$");
1003 if (i < 0)
1004 return(False);
1006 sprintf(comment,"IPC Service (%s)",lp_serverstring());
1008 string_set(&iSERVICE(i).szPath,tmpdir());
1009 string_set(&iSERVICE(i).szUsername,"");
1010 string_set(&iSERVICE(i).comment,comment);
1011 iSERVICE(i).status = False;
1012 iSERVICE(i).iMaxConnections = 0;
1013 iSERVICE(i).bAvailable = True;
1014 iSERVICE(i).bRead_only = True;
1015 iSERVICE(i).bGuest_only = False;
1016 iSERVICE(i).bGuest_ok = True;
1017 iSERVICE(i).bPrint_ok = False;
1018 iSERVICE(i).bBrowseable = sDefault.bBrowseable;
1020 DEBUG(3,("adding IPC service\n"));
1022 return(True);
1026 /***************************************************************************
1027 add a new printer service, with defaults coming from service iFrom
1028 ***************************************************************************/
1029 BOOL lp_add_printer(char *pszPrintername, int iDefaultService)
1031 char *comment = "From Printcap";
1032 int i = add_a_service(pSERVICE(iDefaultService),pszPrintername);
1034 if (i < 0)
1035 return(False);
1037 /* note that we do NOT default the availability flag to True - */
1038 /* we take it from the default service passed. This allows all */
1039 /* dynamic printers to be disabled by disabling the [printers] */
1040 /* entry (if/when the 'available' keyword is implemented!). */
1042 /* the printer name is set to the service name. */
1043 string_set(&iSERVICE(i).szPrintername,pszPrintername);
1044 string_set(&iSERVICE(i).comment,comment);
1045 iSERVICE(i).bBrowseable = sDefault.bBrowseable;
1047 DEBUG(3,("adding printer service %s\n",pszPrintername));
1049 return(True);
1053 /***************************************************************************
1054 Do a case-insensitive, whitespace-ignoring string compare.
1055 ***************************************************************************/
1056 static int strwicmp(char *psz1, char *psz2)
1058 /* if BOTH strings are NULL, return TRUE, if ONE is NULL return */
1059 /* appropriate value. */
1060 if (psz1 == psz2)
1061 return (0);
1062 else
1063 if (psz1 == NULL)
1064 return (-1);
1065 else
1066 if (psz2 == NULL)
1067 return (1);
1069 /* sync the strings on first non-whitespace */
1070 while (1)
1072 while (isspace(*psz1))
1073 psz1++;
1074 while (isspace(*psz2))
1075 psz2++;
1076 if (toupper(*psz1) != toupper(*psz2) || *psz1 == '\0' || *psz2 == '\0')
1077 break;
1078 psz1++;
1079 psz2++;
1081 return (*psz1 - *psz2);
1084 /***************************************************************************
1085 Map a parameter's string representation to something we can use.
1086 Returns False if the parameter string is not recognised, else TRUE.
1087 ***************************************************************************/
1088 static int map_parameter(char *pszParmName)
1090 int iIndex;
1092 if (*pszParmName == '-')
1093 return(-1);
1095 for (iIndex = 0; parm_table[iIndex].label; iIndex++)
1096 if (strwicmp(parm_table[iIndex].label, pszParmName) == 0)
1097 return(iIndex);
1099 DEBUG(0,( "Unknown parameter encountered: \"%s\"\n", pszParmName));
1100 return(-1);
1104 /***************************************************************************
1105 Set a boolean variable from the text value stored in the passed string.
1106 Returns True in success, False if the passed string does not correctly
1107 represent a boolean.
1108 ***************************************************************************/
1109 static BOOL set_boolean(BOOL *pb, char *pszParmValue)
1111 BOOL bRetval;
1113 bRetval = True;
1114 if (strwicmp(pszParmValue, "yes") == 0 ||
1115 strwicmp(pszParmValue, "true") == 0 ||
1116 strwicmp(pszParmValue, "1") == 0)
1117 *pb = True;
1118 else
1119 if (strwicmp(pszParmValue, "no") == 0 ||
1120 strwicmp(pszParmValue, "False") == 0 ||
1121 strwicmp(pszParmValue, "0") == 0)
1122 *pb = False;
1123 else
1125 DEBUG(0,( "Badly formed boolean in configuration file: \"%s\".\n",
1126 pszParmValue));
1127 bRetval = False;
1129 return (bRetval);
1132 /***************************************************************************
1133 Find a service by name. Otherwise works like get_service.
1134 ***************************************************************************/
1135 static int getservicebyname(char *pszServiceName, service *pserviceDest)
1137 int iService;
1139 for (iService = iNumServices - 1; iService >= 0; iService--)
1140 if (VALID(iService) &&
1141 strwicmp(iSERVICE(iService).szService, pszServiceName) == 0)
1143 if (pserviceDest != NULL)
1144 copy_service(pserviceDest, pSERVICE(iService), NULL);
1145 break;
1148 return (iService);
1153 /***************************************************************************
1154 Copy a service structure to another
1156 If pcopymapDest is NULL then copy all fields
1157 ***************************************************************************/
1158 static void copy_service(service *pserviceDest,
1159 service *pserviceSource,
1160 BOOL *pcopymapDest)
1162 int i;
1163 BOOL bcopyall = (pcopymapDest == NULL);
1165 for (i=0;parm_table[i].label;i++)
1166 if (parm_table[i].ptr && parm_table[i].class == P_LOCAL &&
1167 (bcopyall || pcopymapDest[i]))
1169 void *def_ptr = parm_table[i].ptr;
1170 void *src_ptr =
1171 ((char *)pserviceSource) + PTR_DIFF(def_ptr,&sDefault);
1172 void *dest_ptr =
1173 ((char *)pserviceDest) + PTR_DIFF(def_ptr,&sDefault);
1175 switch (parm_table[i].type)
1177 case P_BOOL:
1178 case P_BOOLREV:
1179 *(BOOL *)dest_ptr = *(BOOL *)src_ptr;
1180 break;
1182 case P_INTEGER:
1183 case P_OCTAL:
1184 *(int *)dest_ptr = *(int *)src_ptr;
1185 break;
1187 case P_CHAR:
1188 *(char *)dest_ptr = *(char *)src_ptr;
1189 break;
1191 case P_STRING:
1192 string_set(dest_ptr,*(char **)src_ptr);
1193 break;
1195 case P_USTRING:
1196 string_set(dest_ptr,*(char **)src_ptr);
1197 strupper(*(char **)dest_ptr);
1198 break;
1199 default:
1200 break;
1204 if (bcopyall)
1206 init_copymap(pserviceDest);
1207 if (pserviceSource->copymap)
1208 memcpy((void *)pserviceDest->copymap,
1209 (void *)pserviceSource->copymap,sizeof(BOOL)*NUMPARAMETERS);
1213 /***************************************************************************
1214 Check a service for consistency. Return False if the service is in any way
1215 incomplete or faulty, else True.
1216 ***************************************************************************/
1217 static BOOL service_ok(int iService)
1219 BOOL bRetval;
1221 bRetval = True;
1222 if (iSERVICE(iService).szService[0] == '\0')
1224 DEBUG(0,( "The following message indicates an internal error:\n"));
1225 DEBUG(0,( "No service name in service entry.\n"));
1226 bRetval = False;
1229 /* The [printers] entry MUST be printable. I'm all for flexibility, but */
1230 /* I can't see why you'd want a non-printable printer service... */
1231 if (strwicmp(iSERVICE(iService).szService,PRINTERS_NAME) == 0)
1232 if (!iSERVICE(iService).bPrint_ok)
1234 DEBUG(0,( "WARNING: [%s] service MUST be printable!\n",
1235 iSERVICE(iService).szService));
1236 iSERVICE(iService).bPrint_ok = True;
1239 if (iSERVICE(iService).szPath[0] == '\0' &&
1240 strwicmp(iSERVICE(iService).szService,HOMES_NAME) != 0)
1242 DEBUG(0,("No path in service %s - using %s\n",iSERVICE(iService).szService,tmpdir()));
1243 string_set(&iSERVICE(iService).szPath,tmpdir());
1246 /* If a service is flagged unavailable, log the fact at level 0. */
1247 if (!iSERVICE(iService).bAvailable)
1248 DEBUG(1,( "NOTE: Service %s is flagged unavailable.\n",
1249 iSERVICE(iService).szService));
1251 return (bRetval);
1254 static struct file_lists {
1255 struct file_lists *next;
1256 char *name;
1257 time_t modtime;
1258 } *file_lists = NULL;
1260 /*******************************************************************
1261 keep a linked list of all config files so we know when one has changed
1262 it's date and needs to be reloaded
1263 ********************************************************************/
1264 static void add_to_file_list(char *fname)
1266 struct file_lists *f=file_lists;
1268 while (f) {
1269 if (f->name && !strcmp(f->name,fname)) break;
1270 f = f->next;
1273 if (!f) {
1274 f = (struct file_lists *)malloc(sizeof(file_lists[0]));
1275 if (!f) return;
1276 f->next = file_lists;
1277 f->name = strdup(fname);
1278 if (!f->name) {
1279 free(f);
1280 return;
1282 file_lists = f;
1286 pstring n2;
1287 strcpy(n2,fname);
1288 standard_sub_basic(n2);
1289 f->modtime = file_modtime(n2);
1294 /*******************************************************************
1295 check if a config file has changed date
1296 ********************************************************************/
1297 BOOL lp_file_list_changed(void)
1299 struct file_lists *f = file_lists;
1300 while (f) {
1301 pstring n2;
1302 strcpy(n2,f->name);
1303 standard_sub_basic(n2);
1304 if (f->modtime != file_modtime(n2)) return(True);
1305 f = f->next;
1307 return(False);
1310 #ifdef KANJI
1311 /***************************************************************************
1312 handle the interpretation of the coding system parameter
1313 *************************************************************************/
1314 static BOOL handle_coding_system(char *pszParmValue,int *val)
1316 *val = interpret_coding_system(pszParmValue,*val);
1317 return(True);
1319 #endif /* KANJI */
1321 /***************************************************************************
1322 handle the interpretation of the character set system parameter
1323 ***************************************************************************/
1324 static BOOL handle_character_set(char *pszParmValue,int *val)
1326 string_set(&Globals.szCharacterSet,pszParmValue);
1327 *val = interpret_character_set(pszParmValue,*val);
1328 return(True);
1332 /***************************************************************************
1333 handle the interpretation of the protocol parameter
1334 ***************************************************************************/
1335 static BOOL handle_protocol(char *pszParmValue,int *val)
1337 *val = interpret_protocol(pszParmValue,*val);
1338 return(True);
1341 /***************************************************************************
1342 handle the interpretation of the security parameter
1343 ***************************************************************************/
1344 static BOOL handle_security(char *pszParmValue,int *val)
1346 *val = interpret_security(pszParmValue,*val);
1347 return(True);
1350 /***************************************************************************
1351 handle the interpretation of the default case
1352 ***************************************************************************/
1353 static BOOL handle_case(char *pszParmValue,int *val)
1355 if (strequal(pszParmValue,"LOWER"))
1356 *val = CASE_LOWER;
1357 else if (strequal(pszParmValue,"UPPER"))
1358 *val = CASE_UPPER;
1359 return(True);
1362 /***************************************************************************
1363 handle the interpretation of the printing system
1364 ***************************************************************************/
1365 static BOOL handle_printing(char *pszParmValue,int *val)
1367 if (strequal(pszParmValue,"sysv"))
1368 *val = PRINT_SYSV;
1369 else if (strequal(pszParmValue,"aix"))
1370 *val = PRINT_AIX;
1371 else if (strequal(pszParmValue,"hpux"))
1372 *val = PRINT_HPUX;
1373 else if (strequal(pszParmValue,"bsd"))
1374 *val = PRINT_BSD;
1375 else if (strequal(pszParmValue,"qnx"))
1376 *val = PRINT_QNX;
1377 else if (strequal(pszParmValue,"plp"))
1378 *val = PRINT_PLP;
1379 else if (strequal(pszParmValue,"lprng"))
1380 *val = PRINT_LPRNG;
1381 return(True);
1384 /***************************************************************************
1385 handle the valid chars lines
1386 ***************************************************************************/
1387 static BOOL handle_valid_chars(char *pszParmValue,char **ptr)
1389 string_set(ptr,pszParmValue);
1391 add_char_string(pszParmValue);
1392 return(True);
1396 /***************************************************************************
1397 handle the include operation
1398 ***************************************************************************/
1399 static BOOL handle_include(char *pszParmValue,char **ptr)
1401 pstring fname;
1402 strcpy(fname,pszParmValue);
1404 add_to_file_list(fname);
1406 standard_sub_basic(fname);
1408 string_set(ptr,fname);
1410 if (file_exist(fname,NULL))
1411 return(pm_process(fname, do_section, do_parameter));
1413 DEBUG(2,("Can't find include file %s\n",fname));
1415 return(False);
1419 /***************************************************************************
1420 handle the interpretation of the copy parameter
1421 ***************************************************************************/
1422 static BOOL handle_copy(char *pszParmValue,char **ptr)
1424 BOOL bRetval;
1425 int iTemp;
1426 service serviceTemp;
1428 string_set(ptr,pszParmValue);
1430 init_service(&serviceTemp);
1432 bRetval = False;
1434 DEBUG(3,("Copying service from service %s\n",pszParmValue));
1436 if ((iTemp = getservicebyname(pszParmValue, &serviceTemp)) >= 0)
1438 if (iTemp == iServiceIndex)
1440 DEBUG(0,("Can't copy service %s - unable to copy self!\n",
1441 pszParmValue));
1443 else
1445 copy_service(pSERVICE(iServiceIndex),
1446 &serviceTemp,
1447 iSERVICE(iServiceIndex).copymap);
1448 bRetval = True;
1451 else
1453 DEBUG(0,( "Unable to copy service - source not found: %s\n",
1454 pszParmValue));
1455 bRetval = False;
1458 free_service(&serviceTemp);
1459 return (bRetval);
1463 /***************************************************************************
1464 initialise a copymap
1465 ***************************************************************************/
1466 static void init_copymap(service *pservice)
1468 int i;
1469 if (pservice->copymap) free(pservice->copymap);
1470 pservice->copymap = (BOOL *)malloc(sizeof(BOOL)*NUMPARAMETERS);
1471 if (!pservice->copymap)
1472 DEBUG(0,("Couldn't allocate copymap!! (size %d)\n",NUMPARAMETERS));
1474 for (i=0;i<NUMPARAMETERS;i++)
1475 pservice->copymap[i] = True;
1479 /***************************************************************************
1480 Process a parameter.
1481 ***************************************************************************/
1482 static BOOL do_parameter(char *pszParmName, char *pszParmValue)
1484 int parmnum;
1485 void *parm_ptr=NULL; /* where we are going to store the result */
1486 void *def_ptr=NULL;
1488 if (!bInGlobalSection && bGlobalOnly) return(True);
1490 DEBUG(3,("doing parameter %s = %s\n",pszParmName,pszParmValue));
1492 parmnum = map_parameter(pszParmName);
1494 if (parmnum < 0)
1496 DEBUG(0,( "Ignoring unknown parameter \"%s\"\n", pszParmName));
1497 return(True);
1500 def_ptr = parm_table[parmnum].ptr;
1502 /* we might point at a service, the default service or a global */
1503 if (bInGlobalSection)
1504 parm_ptr = def_ptr;
1505 else
1507 if (parm_table[parmnum].class == P_GLOBAL)
1509 DEBUG(0,( "Global parameter %s found in service section!\n",pszParmName));
1510 return(True);
1512 parm_ptr = ((char *)pSERVICE(iServiceIndex)) + PTR_DIFF(def_ptr,&sDefault);
1515 if (!bInGlobalSection)
1517 int i;
1518 if (!iSERVICE(iServiceIndex).copymap)
1519 init_copymap(pSERVICE(iServiceIndex));
1521 /* this handles the aliases - set the copymap for other entries with
1522 the same data pointer */
1523 for (i=0;parm_table[i].label;i++)
1524 if (parm_table[i].ptr == parm_table[parmnum].ptr)
1525 iSERVICE(iServiceIndex).copymap[i] = False;
1528 /* if it is a special case then go ahead */
1529 if (parm_table[parmnum].special)
1531 parm_table[parmnum].special(pszParmValue,parm_ptr);
1532 return(True);
1535 /* now switch on the type of variable it is */
1536 switch (parm_table[parmnum].type)
1538 case P_BOOL:
1539 set_boolean(parm_ptr,pszParmValue);
1540 break;
1542 case P_BOOLREV:
1543 set_boolean(parm_ptr,pszParmValue);
1544 *(BOOL *)parm_ptr = ! *(BOOL *)parm_ptr;
1545 break;
1547 case P_INTEGER:
1548 *(int *)parm_ptr = atoi(pszParmValue);
1549 break;
1551 case P_CHAR:
1552 *(char *)parm_ptr = *pszParmValue;
1553 break;
1555 case P_OCTAL:
1556 sscanf(pszParmValue,"%o",(int *)parm_ptr);
1557 break;
1559 case P_STRING:
1560 string_set(parm_ptr,pszParmValue);
1561 break;
1563 case P_USTRING:
1564 string_set(parm_ptr,pszParmValue);
1565 strupper(*(char **)parm_ptr);
1566 break;
1568 case P_GSTRING:
1569 strcpy((char *)parm_ptr,pszParmValue);
1570 break;
1572 case P_UGSTRING:
1573 strcpy((char *)parm_ptr,pszParmValue);
1574 strupper((char *)parm_ptr);
1575 break;
1578 return(True);
1581 /***************************************************************************
1582 print a parameter of the specified type
1583 ***************************************************************************/
1584 static void print_parameter(parm_type type,void *ptr)
1586 switch (type)
1588 case P_BOOL:
1589 printf("%s",BOOLSTR(*(BOOL *)ptr));
1590 break;
1592 case P_BOOLREV:
1593 printf("%s",BOOLSTR(! *(BOOL *)ptr));
1594 break;
1596 case P_INTEGER:
1597 printf("%d",*(int *)ptr);
1598 break;
1600 case P_CHAR:
1601 printf("%c",*(char *)ptr);
1602 break;
1604 case P_OCTAL:
1605 printf("0%o",*(int *)ptr);
1606 break;
1608 case P_GSTRING:
1609 case P_UGSTRING:
1610 if ((char *)ptr)
1611 printf("%s",(char *)ptr);
1612 break;
1614 case P_STRING:
1615 case P_USTRING:
1616 if (*(char **)ptr)
1617 printf("%s",*(char **)ptr);
1618 break;
1623 /***************************************************************************
1624 check if two parameters are equal
1625 ***************************************************************************/
1626 static BOOL equal_parameter(parm_type type,void *ptr1,void *ptr2)
1628 switch (type)
1630 case P_BOOL:
1631 case P_BOOLREV:
1632 return(*((BOOL *)ptr1) == *((BOOL *)ptr2));
1634 case P_INTEGER:
1635 case P_OCTAL:
1636 return(*((int *)ptr1) == *((int *)ptr2));
1638 case P_CHAR:
1639 return(*((char *)ptr1) == *((char *)ptr2));
1641 case P_GSTRING:
1642 case P_UGSTRING:
1644 char *p1 = (char *)ptr1, *p2 = (char *)ptr2;
1645 if (p1 && !*p1) p1 = NULL;
1646 if (p2 && !*p2) p2 = NULL;
1647 return(p1==p2 || strequal(p1,p2));
1649 case P_STRING:
1650 case P_USTRING:
1652 char *p1 = *(char **)ptr1, *p2 = *(char **)ptr2;
1653 if (p1 && !*p1) p1 = NULL;
1654 if (p2 && !*p2) p2 = NULL;
1655 return(p1==p2 || strequal(p1,p2));
1658 return(False);
1661 /***************************************************************************
1662 Process a new section (service). At this stage all sections are services.
1663 Later we'll have special sections that permit server parameters to be set.
1664 Returns True on success, False on failure.
1665 ***************************************************************************/
1666 static BOOL do_section(char *pszSectionName)
1668 BOOL bRetval;
1669 BOOL isglobal = ((strwicmp(pszSectionName, GLOBAL_NAME) == 0) ||
1670 (strwicmp(pszSectionName, GLOBAL_NAME2) == 0));
1671 bRetval = False;
1673 /* if we were in a global section then do the local inits */
1674 if (bInGlobalSection && !isglobal)
1675 init_locals();
1677 /* if we've just struck a global section, note the fact. */
1678 bInGlobalSection = isglobal;
1680 /* check for multiple global sections */
1681 if (bInGlobalSection)
1683 DEBUG(3,( "Processing section \"[%s]\"\n", pszSectionName));
1684 return(True);
1687 if (!bInGlobalSection && bGlobalOnly) return(True);
1689 /* if we have a current service, tidy it up before moving on */
1690 bRetval = True;
1692 if (iServiceIndex >= 0)
1693 bRetval = service_ok(iServiceIndex);
1695 /* if all is still well, move to the next record in the services array */
1696 if (bRetval)
1698 /* We put this here to avoid an odd message order if messages are */
1699 /* issued by the post-processing of a previous section. */
1700 DEBUG(2,( "Processing section \"[%s]\"\n", pszSectionName));
1702 if ((iServiceIndex=add_a_service(&sDefault,pszSectionName)) < 0)
1704 DEBUG(0,("Failed to add a new service\n"));
1705 return(False);
1709 return (bRetval);
1712 /***************************************************************************
1713 Display the contents of the global structure.
1714 ***************************************************************************/
1715 static void dump_globals(void)
1717 int i;
1718 printf("Global parameters:\n");
1720 for (i=0;parm_table[i].label;i++)
1721 if (parm_table[i].class == P_GLOBAL &&
1722 parm_table[i].ptr &&
1723 (i == 0 || (parm_table[i].ptr != parm_table[i-1].ptr)))
1725 printf("\t%s: ",parm_table[i].label);
1726 print_parameter(parm_table[i].type,parm_table[i].ptr);
1727 printf("\n");
1731 /***************************************************************************
1732 Display the contents of a single services record.
1733 ***************************************************************************/
1734 static void dump_a_service(service *pService)
1736 int i;
1737 if (pService == &sDefault)
1738 printf("\nDefault service parameters:\n");
1739 else
1740 printf("\nService parameters [%s]:\n",pService->szService);
1742 for (i=0;parm_table[i].label;i++)
1743 if (parm_table[i].class == P_LOCAL &&
1744 parm_table[i].ptr &&
1745 (*parm_table[i].label != '-') &&
1746 (i == 0 || (parm_table[i].ptr != parm_table[i-1].ptr)))
1748 int pdiff = PTR_DIFF(parm_table[i].ptr,&sDefault);
1750 if (pService == &sDefault || !equal_parameter(parm_table[i].type,
1751 ((char *)pService) + pdiff,
1752 ((char *)&sDefault) + pdiff))
1754 printf("\t%s: ",parm_table[i].label);
1755 print_parameter(parm_table[i].type,
1756 ((char *)pService) + pdiff);
1757 printf("\n");
1762 #if 0
1763 /***************************************************************************
1764 Display the contents of a single copy structure.
1765 ***************************************************************************/
1766 static void dump_copy_map(BOOL *pcopymap)
1768 int i;
1769 if (!pcopymap) return;
1771 printf("\n\tNon-Copied parameters:\n");
1773 for (i=0;parm_table[i].label;i++)
1774 if (parm_table[i].class == P_LOCAL &&
1775 parm_table[i].ptr && !pcopymap[i] &&
1776 (i == 0 || (parm_table[i].ptr != parm_table[i-1].ptr)))
1778 printf("\t\t%s\n",parm_table[i].label);
1781 #endif
1783 /***************************************************************************
1784 Return TRUE if the passed service number is within range.
1785 ***************************************************************************/
1786 BOOL lp_snum_ok(int iService)
1788 return (LP_SNUM_OK(iService) && iSERVICE(iService).bAvailable);
1792 /***************************************************************************
1793 auto-load some homes and printer services
1794 ***************************************************************************/
1795 static void lp_add_auto_services(char *str)
1797 char *s;
1798 char *p;
1799 int homes = lp_servicenumber(HOMES_NAME);
1800 int printers = lp_servicenumber(PRINTERS_NAME);
1802 if (!str)
1803 return;
1805 s = strdup(str);
1806 if (!s) return;
1808 for (p=strtok(s,LIST_SEP);p;p=strtok(NULL,LIST_SEP))
1810 char *home = get_home_dir(p);
1812 if (lp_servicenumber(p) >= 0) continue;
1814 if (home && homes >= 0)
1816 lp_add_home(p,homes,home);
1817 continue;
1820 if (printers >= 0 && pcap_printername_ok(p,NULL))
1821 lp_add_printer(p,printers);
1823 free(s);
1826 /***************************************************************************
1827 auto-load one printer
1828 ***************************************************************************/
1829 static void lp_add_one_printer(char *name,char *comment)
1831 int printers = lp_servicenumber(PRINTERS_NAME);
1832 int i;
1834 if (lp_servicenumber(name) < 0)
1836 lp_add_printer(name,printers);
1837 if ((i=lp_servicenumber(name)) >= 0)
1838 string_set(&iSERVICE(i).comment,comment);
1843 /***************************************************************************
1844 auto-load printer services
1845 ***************************************************************************/
1846 static void lp_add_all_printers(void)
1848 int printers = lp_servicenumber(PRINTERS_NAME);
1850 if (printers < 0) return;
1852 pcap_printer_fn(lp_add_one_printer);
1855 /***************************************************************************
1856 have we loaded a services file yet?
1857 ***************************************************************************/
1858 BOOL lp_loaded(void)
1860 return(bLoaded);
1863 /***************************************************************************
1864 unload unused services
1865 ***************************************************************************/
1866 void lp_killunused(BOOL (*snumused)(int ))
1868 int i;
1869 for (i=0;i<iNumServices;i++)
1870 if (VALID(i) && !snumused(i))
1872 iSERVICE(i).valid = False;
1873 free_service(pSERVICE(i));
1877 /***************************************************************************
1878 Load the services array from the services file. Return True on success,
1879 False on failure.
1880 ***************************************************************************/
1881 BOOL lp_load(char *pszFname,BOOL global_only)
1883 pstring n2;
1884 BOOL bRetval;
1886 add_to_file_list(pszFname);
1888 bRetval = False;
1890 bInGlobalSection = True;
1891 bGlobalOnly = global_only;
1893 init_globals();
1895 strcpy(n2,pszFname);
1896 standard_sub_basic(n2);
1898 /* We get sections first, so have to start 'behind' to make up */
1899 iServiceIndex = -1;
1900 bRetval = pm_process(n2, do_section, do_parameter);
1902 /* finish up the last section */
1903 DEBUG(3,("pm_process() returned %s\n", BOOLSTR(bRetval)));
1904 if (bRetval)
1905 if (iServiceIndex >= 0)
1906 bRetval = service_ok(iServiceIndex);
1908 lp_add_auto_services(lp_auto_services());
1909 if (lp_load_printers())
1910 lp_add_all_printers();
1912 lp_add_ipc();
1914 bLoaded = True;
1916 return (bRetval);
1920 /***************************************************************************
1921 return the max number of services
1922 ***************************************************************************/
1923 int lp_numservices(void)
1925 return(iNumServices);
1928 /***************************************************************************
1929 Display the contents of the services array in human-readable form.
1930 ***************************************************************************/
1931 void lp_dump(void)
1933 int iService;
1935 dump_globals();
1937 dump_a_service(&sDefault);
1939 for (iService = 0; iService < iNumServices; iService++)
1941 if (VALID(iService))
1943 if (iSERVICE(iService).szService[0] == '\0')
1944 break;
1945 dump_a_service(pSERVICE(iService));
1950 /***************************************************************************
1951 Return the number of the service with the given name, or -1 if it doesn't
1952 exist. Note that this is a DIFFERENT ANIMAL from the internal function
1953 getservicebyname()! This works ONLY if all services have been loaded, and
1954 does not copy the found service.
1955 ***************************************************************************/
1956 int lp_servicenumber(char *pszServiceName)
1958 int iService;
1960 for (iService = iNumServices - 1; iService >= 0; iService--)
1961 if (VALID(iService) &&
1962 strwicmp(iSERVICE(iService).szService, pszServiceName) == 0)
1963 break;
1965 if (iService < 0)
1966 DEBUG(7,("lp_servicenumber: couldn't find %s\n",pszServiceName));
1968 return (iService);
1971 /*******************************************************************
1972 a useful volume label function
1973 ******************************************************************/
1974 char *volume_label(int snum)
1976 char *ret = lp_volume(snum);
1977 if (!*ret) return(lp_servicename(snum));
1978 return(ret);