home *** CD-ROM | disk | FTP | other *** search
/ Serving the Web / ServingTheWeb1995.disc1of1.iso / linux / slacksrce / contrib / samba / samba-1.8 / samba-1 / samba-1.8.05 / loadparm.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-10-27  |  45.5 KB  |  1,447 lines

  1. /* 
  2.    Unix SMB/Netbios implementation.
  3.    Version 1.8.
  4.    Copyright (C) Karl Auer 1993,1994
  5.  
  6.    Largely re-written by Andrew Tridgell, September 1994
  7.    
  8.    This program is free software; you can redistribute it and/or modify
  9.    it under the terms of the GNU General Public License as published by
  10.    the Free Software Foundation; either version 2 of the License, or
  11.    (at your option) any later version.
  12.    
  13.    This program is distributed in the hope that it will be useful,
  14.    but WITHOUT ANY WARRANTY; without even the implied warranty of
  15.    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  16.    GNU General Public License for more details.
  17.    
  18.    You should have received a copy of the GNU General Public License
  19.    along with this program; if not, write to the Free Software
  20.    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  21. */
  22.  
  23. /*
  24.  *  Load parameters.
  25.  *
  26.  *  This module provides suitable callback functions for the params
  27.  *  module. It builds the internal table of service details which is
  28.  *  then used by the rest of the server.
  29.  *
  30.  * To add a parameter:
  31.  *
  32.  * 1) add it to the global or service structure definition
  33.  * 2) add it to the parm_table
  34.  * 3) add it to the list of available functions (eg: using FN_GLOBAL_STRING())
  35.  * 4) If it's a global then initialise it in init_globals. If a local
  36.  *    (ie. service) parameter then initialise it in the sDefault structure
  37.  *  
  38.  *
  39.  * Notes:
  40.  *   The configuration file is processed sequentially for speed. It is NOT
  41.  *   accessed randomly as happens in 'real' Windows. For this reason, there
  42.  *   is a fair bit of sequence-dependent code here - ie., code which assumes
  43.  *   that certain things happen before others. In particular, the code which
  44.  *   happens at the boundary between sections is delicately poised, so be
  45.  *   careful!
  46.  *
  47.  */
  48.  
  49. #include "includes.h"
  50.  
  51. #include "params.h"
  52. #include "loadparm.h"
  53. #include "pcap.h"
  54.  
  55. extern int DEBUGLEVEL;
  56.  
  57. #ifndef GLOBAL_NAME
  58. #define GLOBAL_NAME "global"
  59. #endif
  60.  
  61. #ifndef PRINTCAP_NAME
  62. #define PRINTCAP_NAME "/etc/printcap"
  63. #endif
  64.  
  65. #ifndef PRINTERS_NAME
  66. #define PRINTERS_NAME "printers"
  67. #endif
  68.  
  69. #ifndef HOMES_NAME
  70. #define HOMES_NAME "homes"
  71. #endif
  72.  
  73. /* some helpful bits */
  74. #define LP_SNUM_OK(iService) (((iService) >= 0) && ((iService) < iNumServices))
  75. #define pSERVICE(i) ServicePtrs[i]
  76. #define iSERVICE(i) (*pSERVICE(i))
  77.  
  78. /* these are the types of parameter we have */
  79. typedef enum
  80. {
  81.   P_BOOL,P_BOOLREV,P_CHAR,P_INTEGER,P_OCTAL,P_STRING
  82. } parm_type;
  83.  
  84. typedef enum
  85. {
  86.   P_LOCAL,P_GLOBAL,P_NONE
  87. } parm_class;
  88.  
  89. extern int keepalive;
  90. extern int extra_time_offset;
  91.  
  92. /* 
  93.  * This structure describes global (ie., server-wide) parameters.
  94.  */
  95. typedef struct
  96. {
  97.    char *szPrintcapname;
  98.    char *szLockDir;
  99.    char *szGuestaccount;
  100.    char *szRootdir;
  101.    char *szDefaultService;
  102.    char *szDfree;
  103.    char *szHostsEquiv;
  104.    char *szServerString;
  105.    char *szAutoServices;
  106.    char *szPasswdProgram;
  107.    int mangled_stack;
  108.    int max_xmit;
  109.    int max_mux;
  110.    int max_packet;
  111.    int pwordlevel;
  112.    int deadtime;
  113.    int maxprotocol;
  114.    int security;
  115.    BOOL bNullPasswords;
  116.    BOOL bCaseSigNames;
  117.    BOOL bLoadPrinters;
  118.    BOOL bUseRhosts;
  119.    BOOL bReadRaw;
  120.    BOOL bWriteRaw;
  121.    BOOL bGetwdCache;
  122.    BOOL bReadPrediction;
  123.    BOOL bReadbmpx;
  124. } global;
  125.  
  126. static global Globals;
  127.  
  128.  
  129.  
  130. /* 
  131.  * This structure describes a single service. 
  132.  */
  133. typedef struct
  134. {
  135.    char *szService;
  136.    char *szPath;
  137.    char *szUsername;
  138.    char *szInvalidUsers;
  139.    char *szValidUsers;
  140.    char *szCopy;
  141.    char *szPrintcommand;
  142.    char *szLpqcommand;
  143.    char *szPrintername;
  144.    char *szDontdescend;
  145.    char *szHostsallow;
  146.    char *szHostsdeny;
  147.    char *szMagicScript;
  148.    char *szMagicOutput;
  149.    char *szMangledMap;
  150.    char *comment;
  151.    char *group;
  152.    char *readlist;
  153.    char *writelist;
  154.    int  iCreate_mode;
  155.    int  iMaxConnections;
  156.    int  iDefaultCase;
  157.    BOOL status;
  158.    BOOL bHideDotFiles;
  159.    BOOL bBrowseable;
  160.    BOOL bAvailable;
  161.    BOOL bRead_only;
  162.    BOOL bNo_set_dir;
  163.    BOOL bGuest_only;
  164.    BOOL bGuest_ok;
  165.    BOOL bPrint_ok;
  166.    BOOL bPostscript;
  167.    BOOL bMap_system;
  168.    BOOL bMap_hidden;
  169.    BOOL bLocking;
  170.    BOOL bOnlyUser;
  171.    BOOL bMangledNames;
  172.    BOOL bWidelinks;
  173.    char magic_char;
  174.    BOOL *copymap;
  175.    char dummy[3]; /* for alignment */
  176. } service;
  177.  
  178.  
  179. /* This is a default service used to prime a services structure */
  180. static service sDefault = 
  181. {
  182.   NULL,    /* szService */
  183.   NULL,    /* szPath */
  184.   NULL,    /* szUsername */
  185.   NULL,    /* szInvalidUsers */
  186.   NULL,    /* szValidUsers */
  187.   NULL,    /* szCopy */
  188.   NULL,    /* szPrintcommand */
  189.   NULL,    /* szLpqcommand */
  190.   NULL,    /* szPrintername */
  191.   NULL,    /* szDontdescend */
  192.   NULL,    /* szHostsallow */
  193.   NULL,    /* szHostsdeny */
  194.   NULL,    /* szMagicScript */
  195.   NULL,    /* szMagicOutput */
  196.   NULL,    /* szMangledMap */
  197.   NULL,    /* comment */
  198.   NULL,    /* group */
  199.   NULL,    /* readlist */
  200.   NULL,    /* writelist */
  201.   DEF_CREATE_MASK,   /* iCreate_mode */
  202.   0,     /* iMaxConnections */
  203.   CASE_LOWER, /* iDefaultCase */
  204.   False,  /* status */
  205.   True,  /* bHideDotFiles */
  206.   True,  /* bBrowseable */
  207.   True,  /* bAvailable */
  208.   True,  /* bRead_only */
  209.   True,  /* bNo_set_dir */
  210.   False, /* bGuest_only */
  211.   False, /* bGuest_ok */
  212.   False, /* bPrint_ok */
  213.   False, /* bPostscript */
  214.   False, /* bMap_system */
  215.   False, /* bMap_hidden */
  216.   True,  /* bLocking */
  217.   False, /* bOnlyUser */
  218.   True,  /* bMangledNames */
  219.   True,  /* bWidelinks */
  220.   '~',   /* magic char */
  221.   NULL,  /* copymap */
  222.   ""     /* dummy */
  223. };
  224.  
  225.  
  226.  
  227. /* local variables */
  228. static service **ServicePtrs = NULL;
  229. static int iNumServices = 0;
  230. static int iServiceIndex = 0;
  231. static BOOL bInGlobalSection = False;
  232. static BOOL bDoneGlobalSection = False;
  233.  
  234.  
  235. #define NUMPARAMETERS (sizeof(parm_table) / sizeof(struct parm_struct))
  236.  
  237. /* prototypes for the special type handlers */
  238. static BOOL handle_copy(char *pszParmValue, char **ptr);
  239. static BOOL handle_protocol(char *pszParmValue,int *val);
  240. static BOOL handle_security(char *pszParmValue,int *val);
  241. static BOOL handle_case(char *pszParmValue,int *val);
  242.  
  243.  
  244. struct parm_struct
  245. {
  246.   char *label;
  247.   parm_type type;
  248.   parm_class class;
  249.   void *ptr;
  250.   BOOL (*special)();
  251. } parm_table[] =
  252. {
  253.   {"debuglevel",       P_INTEGER, P_GLOBAL, &DEBUGLEVEL,                NULL},
  254.   {"protocol",         P_INTEGER, P_GLOBAL, &Globals.maxprotocol,handle_protocol},
  255.   {"security",         P_INTEGER, P_GLOBAL, &Globals.security,handle_security},
  256.   {"getwd cache",      P_BOOL,    P_GLOBAL, &Globals.bGetwdCache,       NULL},
  257.   {"read prediction",  P_BOOL,    P_GLOBAL, &Globals.bReadPrediction,   NULL},
  258.   {"read bmpx",        P_BOOL,    P_GLOBAL, &Globals.bReadbmpx,         NULL},
  259.   {"read raw",         P_BOOL,    P_GLOBAL, &Globals.bReadRaw,          NULL},
  260.   {"write raw",        P_BOOL,    P_GLOBAL, &Globals.bWriteRaw,         NULL},
  261.   {"use rhosts",       P_BOOL,    P_GLOBAL, &Globals.bUseRhosts,        NULL},
  262.   {"load printers",    P_BOOL,    P_GLOBAL, &Globals.bLoadPrinters,     NULL},
  263.   {"casesignames",     P_BOOL,    P_GLOBAL, &Globals.bCaseSigNames,     NULL},
  264.   {"null passwords",   P_BOOL,    P_GLOBAL, &Globals.bNullPasswords,    NULL},
  265.   {"hosts equiv",      P_STRING,  P_GLOBAL, &Globals.szHostsEquiv,      NULL},
  266.   {"preload",          P_STRING,  P_GLOBAL, &Globals.szAutoServices,    NULL},
  267.   {"auto services",    P_STRING,  P_GLOBAL, &Globals.szAutoServices,    NULL},
  268.   {"server string",    P_STRING,  P_GLOBAL, &Globals.szServerString,    NULL},
  269.   {"printcap name",    P_STRING,  P_GLOBAL, &Globals.szPrintcapname,    NULL},
  270.   {"printcap",         P_STRING,  P_GLOBAL, &Globals.szPrintcapname,    NULL},
  271.   {"lock dir",         P_STRING,  P_GLOBAL, &Globals.szLockDir,         NULL},
  272.   {"lock directory",   P_STRING,  P_GLOBAL, &Globals.szLockDir,         NULL},
  273.   {"guest account",    P_STRING,  P_GLOBAL, &Globals.szGuestaccount,    NULL},
  274.   {"root directory",   P_STRING,  P_GLOBAL, &Globals.szRootdir,         NULL},
  275.   {"root dir",         P_STRING,  P_GLOBAL, &Globals.szRootdir,         NULL},
  276.   {"root",             P_STRING,  P_GLOBAL, &Globals.szRootdir,         NULL},
  277.   {"default service",  P_STRING,  P_GLOBAL, &Globals.szDefaultService,  NULL},
  278.   {"default",          P_STRING,  P_GLOBAL, &Globals.szDefaultService,  NULL},
  279.   {"dfree command",    P_STRING,  P_GLOBAL, &Globals.szDfree,           NULL},
  280.   {"passwd program",   P_STRING,  P_GLOBAL, &Globals.szPasswdProgram,   NULL},
  281.   {"mangled stack",    P_INTEGER, P_GLOBAL, &Globals.mangled_stack,     NULL},
  282.   {"max mux",          P_INTEGER, P_GLOBAL, &Globals.max_mux,           NULL},
  283.   {"max xmit",         P_INTEGER, P_GLOBAL, &Globals.max_xmit,          NULL},
  284.   {"max packet",       P_INTEGER, P_GLOBAL, &Globals.max_packet,        NULL},
  285.   {"packet size",      P_INTEGER, P_GLOBAL, &Globals.max_packet,        NULL},
  286.   {"password level",   P_INTEGER, P_GLOBAL, &Globals.pwordlevel,        NULL},
  287.   {"keepalive",        P_INTEGER, P_GLOBAL, &keepalive,                 NULL},
  288.   {"deadtime",         P_INTEGER, P_GLOBAL, &Globals.deadtime,          NULL},
  289.   {"time offset",      P_INTEGER, P_GLOBAL, &extra_time_offset,         NULL},
  290.  
  291.   {"comment",          P_STRING,  P_LOCAL,  &sDefault.comment,          NULL},
  292.   {"copy",             P_STRING,  P_LOCAL,  &sDefault.szCopy,    handle_copy},
  293.   {"default case",     P_INTEGER, P_LOCAL,  &sDefault.iDefaultCase,   handle_case},
  294.   {"mangling char",    P_CHAR,    P_LOCAL,  &sDefault.magic_char,       NULL},
  295.   {"browseable",       P_BOOL,    P_LOCAL,  &sDefault.bBrowseable,      NULL},
  296.   {"browsable",        P_BOOL,    P_LOCAL,  &sDefault.bBrowseable,      NULL},
  297.   {"available",        P_BOOL,    P_LOCAL,  &sDefault.bAvailable,       NULL},
  298.   {"path",             P_STRING,  P_LOCAL,  &sDefault.szPath,           NULL},
  299.   {"directory",        P_STRING,  P_LOCAL,  &sDefault.szPath,           NULL},
  300.   {"username",         P_STRING,  P_LOCAL,  &sDefault.szUsername,       NULL},
  301.   {"user",             P_STRING,  P_LOCAL,  &sDefault.szUsername,       NULL},
  302.   {"users",            P_STRING,  P_LOCAL,  &sDefault.szUsername,       NULL},
  303.   {"invalid users",    P_STRING,  P_LOCAL,  &sDefault.szInvalidUsers,   NULL},
  304.   {"valid users",      P_STRING,  P_LOCAL,  &sDefault.szValidUsers,     NULL},
  305.   {"read list",        P_STRING,  P_LOCAL,  &sDefault.readlist,         NULL},
  306.   {"write list",       P_STRING,  P_LOCAL,  &sDefault.writelist,        NULL},
  307.   {"group",            P_STRING,  P_LOCAL,  &sDefault.group,            NULL},
  308.   {"read only",        P_BOOL,    P_LOCAL,  &sDefault.bRead_only,       NULL},
  309.   {"write ok",         P_BOOLREV, P_LOCAL,  &sDefault.bRead_only,       NULL},
  310.   {"writeable",        P_BOOLREV, P_LOCAL,  &sDefault.bRead_only,       NULL},
  311.   {"writable",         P_BOOLREV, P_LOCAL,  &sDefault.bRead_only,       NULL},
  312.   {"max connections",  P_INTEGER, P_LOCAL,  &sDefault.iMaxConnections,  NULL},
  313.   {"create mask",      P_OCTAL,   P_LOCAL,  &sDefault.iCreate_mode,     NULL},
  314.   {"create mode",      P_OCTAL,   P_LOCAL,  &sDefault.iCreate_mode,     NULL},
  315.   {"set directory",    P_BOOLREV, P_LOCAL,  &sDefault.bNo_set_dir,      NULL},
  316.   {"status",           P_BOOL,    P_LOCAL,  &sDefault.status,           NULL},
  317.   {"hide dot files",   P_BOOL,    P_LOCAL,  &sDefault.bHideDotFiles,    NULL},
  318.   {"guest only",       P_BOOL,    P_LOCAL,  &sDefault.bGuest_only,      NULL},
  319.   {"only guest",       P_BOOL,    P_LOCAL,  &sDefault.bGuest_only,      NULL},
  320.   {"guest ok",         P_BOOL,    P_LOCAL,  &sDefault.bGuest_ok,        NULL},
  321.   {"public",           P_BOOL,    P_LOCAL,  &sDefault.bGuest_ok,        NULL},
  322.   {"print ok",         P_BOOL,    P_LOCAL,  &sDefault.bPrint_ok,        NULL},
  323.   {"printable",        P_BOOL,    P_LOCAL,  &sDefault.bPrint_ok,        NULL},
  324.   {"postscript",       P_BOOL,    P_LOCAL,  &sDefault.bPostscript,      NULL},
  325.   {"map system",       P_BOOL,    P_LOCAL,  &sDefault.bMap_system,      NULL},
  326.   {"map hidden",       P_BOOL,    P_LOCAL,  &sDefault.bMap_hidden,      NULL},
  327.   {"locking",          P_BOOL,    P_LOCAL,  &sDefault.bLocking,         NULL},
  328.   {"only user",        P_BOOL,    P_LOCAL,  &sDefault.bOnlyUser,        NULL},
  329.   {"wide links",       P_BOOL,    P_LOCAL,  &sDefault.bWidelinks,       NULL},
  330.   {"mangled names",    P_BOOL,    P_LOCAL,  &sDefault.bMangledNames,    NULL},
  331.   {"print command",    P_STRING,  P_LOCAL,  &sDefault.szPrintcommand,   NULL},
  332.   {"lpq command",      P_STRING,  P_LOCAL,  &sDefault.szLpqcommand,     NULL},
  333.   {"printer",          P_STRING,  P_LOCAL,  &sDefault.szPrintername,    NULL},
  334.   {"printer name",     P_STRING,  P_LOCAL,  &sDefault.szPrintername,    NULL},
  335.   {"hosts allow",      P_STRING,  P_LOCAL,  &sDefault.szHostsallow,     NULL},
  336.   {"allow hosts",      P_STRING,  P_LOCAL,  &sDefault.szHostsallow,     NULL},
  337.   {"hosts deny",       P_STRING,  P_LOCAL,  &sDefault.szHostsdeny,      NULL},
  338.   {"deny hosts",       P_STRING,  P_LOCAL,  &sDefault.szHostsdeny,      NULL},
  339.   {"dont descend",     P_STRING,  P_LOCAL,  &sDefault.szDontdescend,    NULL},
  340.   {"magic script",     P_STRING,  P_LOCAL,  &sDefault.szMagicScript,    NULL},
  341.   {"magic output",     P_STRING,  P_LOCAL,  &sDefault.szMagicOutput,    NULL},
  342.   {"mangled map",      P_STRING,  P_LOCAL,  &sDefault.szMangledMap,     NULL},
  343.  
  344.   {NULL,               P_BOOL,    P_NONE,   NULL,                       NULL}
  345. };
  346.  
  347.  
  348.  
  349. /***************************************************************************
  350. Initialise the global parameter structure.
  351. ***************************************************************************/
  352. static void init_globals(void)
  353. {
  354.   int i;
  355.   pstring s="";
  356.   DEBUG(3,("Initialising global parameters\n"));
  357.  
  358.   memset(&Globals,0,sizeof(Globals));
  359.  
  360.  
  361.   string_init(&Globals.szPasswdProgram, "/bin/passwd");
  362.   string_init(&Globals.szPrintcapname, PRINTCAP_NAME);
  363.   string_init(&Globals.szLockDir, LOCKDIR);
  364.   string_init(&Globals.szGuestaccount, GUEST_ACCOUNT);
  365.   string_init(&Globals.szRootdir, "/");
  366.   string_init(&Globals.szDefaultService, "");
  367.   string_init(&Globals.szDfree, "");
  368.   string_init(&Globals.szHostsEquiv, "");
  369.   sprintf(s,"Samba %s",VERSION);
  370.   string_init(&Globals.szServerString,s);
  371.   string_init(&Globals.szAutoServices, "");
  372.   Globals.bCaseSigNames = False;
  373.   Globals.bLoadPrinters = True;
  374.   Globals.bUseRhosts = False;
  375.   Globals.max_packet = 65535;
  376.   Globals.mangled_stack = 50;
  377.   Globals.max_xmit = Globals.max_packet;
  378.   Globals.max_mux = 2;
  379.   Globals.pwordlevel = 0;
  380.   Globals.deadtime = 0;
  381.   Globals.maxprotocol = PROTOCOL_LANMAN2;
  382.   Globals.security = SEC_SHARE;
  383.   Globals.bReadRaw = True;
  384.   Globals.bWriteRaw = False;
  385.   Globals.bGetwdCache = False;
  386.   Globals.bReadPrediction = True;
  387.   Globals.bReadbmpx = False;
  388.   Globals.bNullPasswords = False;
  389.  
  390.  
  391.   for (i = 0; parm_table[i].label; i++) 
  392.     if (parm_table[i].type == P_STRING && 
  393.     parm_table[i].class == P_LOCAL &&
  394.     parm_table[i].ptr)
  395.       string_init(parm_table[i].ptr,"");
  396.  
  397.   /* and some sDefault strings */
  398.   string_set(&sDefault.szLpqcommand,"lpq -P %p");
  399.   string_set(&sDefault.szPrintcommand,"lpr -r -P %p %s");
  400.  
  401. }
  402.  
  403.  
  404.  
  405.  
  406. /*
  407.    In this section all the functions that are used to access the 
  408.    parameters from the rest of the program are defined 
  409. */
  410.  
  411. #define FN_GLOBAL_STRING(fn_name,ptr) \
  412.  char *fn_name(void) {return(*(char **)(ptr) ? *(char **)(ptr) : "");}
  413. #define FN_GLOBAL_BOOL(fn_name,ptr) \
  414.  BOOL fn_name(void) {return(*(BOOL *)(ptr));}
  415. #define FN_GLOBAL_CHAR(fn_name,ptr) \
  416.  char fn_name(void) {return(*(char *)(ptr));}
  417. #define FN_GLOBAL_INTEGER(fn_name,ptr) \
  418.  int fn_name(void) {return(*(int *)(ptr));}
  419.  
  420. #define FN_LOCAL_STRING(fn_name,val) \
  421.  char *fn_name(int i) {return((LP_SNUM_OK(i)&&pSERVICE(i)->val)?pSERVICE(i)->val : sDefault.val);}
  422. #define FN_LOCAL_BOOL(fn_name,val) \
  423.  BOOL fn_name(int i) {return(LP_SNUM_OK(i)? pSERVICE(i)->val : sDefault.val);}
  424. #define FN_LOCAL_CHAR(fn_name,val) \
  425.  char fn_name(int i) {return(LP_SNUM_OK(i)? pSERVICE(i)->val : sDefault.val);}
  426. #define FN_LOCAL_INTEGER(fn_name,val) \
  427.  int fn_name(int i) {return(LP_SNUM_OK(i)? pSERVICE(i)->val : sDefault.val);}
  428.  
  429. FN_GLOBAL_STRING(lp_guestaccount,&Globals.szGuestaccount)
  430. FN_GLOBAL_STRING(lp_serverstring,&Globals.szServerString)
  431. FN_GLOBAL_STRING(lp_printcapname,&Globals.szPrintcapname)
  432. FN_GLOBAL_STRING(lp_lockdir,&Globals.szLockDir)
  433. FN_GLOBAL_STRING(lp_rootdir,&Globals.szRootdir)
  434. FN_GLOBAL_STRING(lp_defaultservice,&Globals.szDefaultService)
  435. FN_GLOBAL_STRING(lp_dfree_command,&Globals.szDfree)
  436. FN_GLOBAL_STRING(lp_hosts_equiv,&Globals.szHostsEquiv)
  437. FN_GLOBAL_STRING(lp_auto_services,&Globals.szAutoServices)
  438. FN_GLOBAL_STRING(lp_passwd_program,&Globals.szPasswdProgram)
  439.  
  440. FN_GLOBAL_BOOL(lp_casesignames,&Globals.bCaseSigNames)
  441. FN_GLOBAL_BOOL(lp_load_printers,&Globals.bLoadPrinters)
  442. FN_GLOBAL_BOOL(lp_use_rhosts,&Globals.bUseRhosts)
  443. FN_GLOBAL_BOOL(lp_getwdcache,&Globals.bGetwdCache)
  444. FN_GLOBAL_BOOL(lp_readprediction,&Globals.bReadPrediction)
  445. FN_GLOBAL_BOOL(lp_readbmpx,&Globals.bReadbmpx)
  446. FN_GLOBAL_BOOL(lp_readraw,&Globals.bReadRaw)
  447. FN_GLOBAL_BOOL(lp_writeraw,&Globals.bWriteRaw)
  448. FN_GLOBAL_BOOL(lp_null_passwords,&Globals.bNullPasswords)
  449.  
  450. FN_GLOBAL_INTEGER(lp_mangledstack,&Globals.mangled_stack)
  451. FN_GLOBAL_INTEGER(lp_maxxmit,&Globals.max_xmit)
  452. FN_GLOBAL_INTEGER(lp_maxmux,&Globals.max_mux)
  453. FN_GLOBAL_INTEGER(lp_maxpacket,&Globals.max_packet)
  454. FN_GLOBAL_INTEGER(lp_keepalive,&keepalive)
  455. FN_GLOBAL_INTEGER(lp_passwordlevel,&Globals.pwordlevel)
  456. FN_GLOBAL_INTEGER(lp_deadtime,&Globals.deadtime)
  457. FN_GLOBAL_INTEGER(lp_maxprotocol,&Globals.maxprotocol)
  458. FN_GLOBAL_INTEGER(lp_security,&Globals.security)
  459.  
  460. FN_LOCAL_STRING(lp_servicename,szService)
  461. FN_LOCAL_STRING(lp_pathname,szPath)
  462. FN_LOCAL_STRING(lp_dontdescend,szDontdescend)
  463. FN_LOCAL_STRING(lp_username,szUsername)
  464. FN_LOCAL_STRING(lp_invalid_users,szInvalidUsers)
  465. FN_LOCAL_STRING(lp_valid_users,szValidUsers)
  466. FN_LOCAL_STRING(lp_printcommand,szPrintcommand)
  467. FN_LOCAL_STRING(lp_lpqcommand,szLpqcommand)
  468. FN_LOCAL_STRING(lp_printername,szPrintername)
  469. FN_LOCAL_STRING(lp_hostsallow,szHostsallow)
  470. FN_LOCAL_STRING(lp_hostsdeny,szHostsdeny)
  471. FN_LOCAL_STRING(lp_magicscript,szMagicScript)
  472. FN_LOCAL_STRING(lp_magicoutput,szMagicOutput)
  473. FN_LOCAL_STRING(lp_comment,comment)
  474. FN_LOCAL_STRING(lp_group,group)
  475. FN_LOCAL_STRING(lp_readlist,readlist)
  476. FN_LOCAL_STRING(lp_writelist,writelist)
  477. FN_LOCAL_STRING(lp_mangled_map,szMangledMap)
  478.  
  479. FN_LOCAL_BOOL(lp_status,status)
  480. FN_LOCAL_BOOL(lp_hide_dot_files,bHideDotFiles)
  481. FN_LOCAL_BOOL(lp_browseable,bBrowseable)
  482. FN_LOCAL_BOOL(lp_readonly,bRead_only)
  483. FN_LOCAL_BOOL(lp_no_set_dir,bNo_set_dir)
  484. FN_LOCAL_BOOL(lp_guest_ok,bGuest_ok)
  485. FN_LOCAL_BOOL(lp_guest_only,bGuest_only)
  486. FN_LOCAL_BOOL(lp_print_ok,bPrint_ok)
  487. FN_LOCAL_BOOL(lp_postscript,bPostscript)
  488. FN_LOCAL_BOOL(lp_map_hidden,bMap_hidden)
  489. FN_LOCAL_BOOL(lp_locking,bLocking)
  490. FN_LOCAL_BOOL(lp_onlyuser,bOnlyUser)
  491. FN_LOCAL_BOOL(lp_manglednames,bMangledNames)
  492. FN_LOCAL_BOOL(lp_widelinks,bWidelinks)
  493. FN_LOCAL_BOOL(lp_map_system,bMap_system)
  494.  
  495. FN_LOCAL_INTEGER(lp_create_mode,iCreate_mode)
  496. FN_LOCAL_INTEGER(lp_max_connections,iMaxConnections)
  497. FN_LOCAL_INTEGER(lp_defaultcase,iDefaultCase)
  498.  
  499. FN_LOCAL_CHAR(lp_magicchar,magic_char)
  500.  
  501.  
  502.  
  503. /* local prototypes */
  504. static void   init_globals(void);
  505. static int    strwicmp( char *psz1, char *psz2 );
  506. static int    map_parameter( char *pszParmName);
  507. static BOOL   set_boolean( BOOL *pb, char *pszParmValue );
  508. static int    getservicebyname(char *pszServiceName, service *pserviceDest);
  509. static void   copy_service( service *pserviceDest, 
  510.                             service *pserviceSource,
  511.                             BOOL *pcopymapDest );
  512. static BOOL   service_ok(int iService);
  513. static BOOL   do_parameter(char *pszParmName, char *pszParmValue);
  514. static BOOL   do_section(char *pszSectionName);
  515. static void   dump_globals(void);
  516. static void   dump_a_service(service *pService);
  517. static void init_copymap(service *pservice);
  518.  
  519.  
  520. /***************************************************************************
  521. initialise a service to the defaults
  522. ***************************************************************************/
  523. static void init_service(service *pservice)
  524. {
  525.   memset((char *)pservice,0,sizeof(service));
  526.   copy_service(pservice,&sDefault,NULL);
  527. }
  528.  
  529. /***************************************************************************
  530. add a new service to the services array initialising it with the given 
  531. service
  532. ***************************************************************************/
  533. static int add_a_service(service *pservice)
  534. {
  535.   service tservice = *pservice;
  536.   int num_to_alloc = iNumServices+1;
  537.  
  538.   ServicePtrs = (service **)Realloc(ServicePtrs,sizeof(service *)*num_to_alloc);
  539.   if (ServicePtrs)
  540.     pSERVICE(iNumServices) = (service *)malloc(sizeof(service));
  541.  
  542.   if (ServicePtrs && pSERVICE(iNumServices))
  543.     {
  544.       init_service(pSERVICE(iNumServices));
  545.       copy_service(pSERVICE(iNumServices),&tservice,NULL);
  546.       iNumServices++;
  547.     }
  548.   else
  549.     return(-1);
  550.  
  551.   return(iNumServices - 1);
  552. }
  553.  
  554. /***************************************************************************
  555. add a new home service, with the specified home directory, defaults coming 
  556. from service ifrom
  557. ***************************************************************************/
  558. BOOL lp_add_home(char *pszHomename, int iDefaultService, char *pszHomedir)
  559. {
  560.   int i = add_a_service(pSERVICE(iDefaultService));
  561.  
  562.   if (i < 0)
  563.     return(False);
  564.  
  565.   string_set(&iSERVICE(i).szService,pszHomename);
  566.   string_set(&iSERVICE(i).szPath,pszHomedir);
  567.   string_set(&iSERVICE(i).comment,pszHomedir);
  568.   iSERVICE(i).bAvailable = True;
  569.   iSERVICE(i).bBrowseable = sDefault.bBrowseable;
  570.  
  571.   if (!iSERVICE(i).bGuest_ok)
  572.     {
  573.       pstring s;
  574.       strcpy(s,pszHomename);
  575.       strcat(s," ");
  576.       if (iSERVICE(i).szUsername)
  577.     strcat(s,iSERVICE(i).szUsername);
  578.       string_set(&iSERVICE(i).szUsername,s);
  579.     }
  580.  
  581.   DEBUG(2,("adding home directory %s at %s\n", pszHomename, pszHomedir));
  582.  
  583.   return(True);
  584. }
  585.  
  586.  
  587. /***************************************************************************
  588. add the IPC service
  589. ***************************************************************************/
  590. BOOL lp_add_ipc(void)
  591. {
  592.   pstring myname="SAMBA";
  593.   pstring comment="";
  594.   int i = add_a_service(&sDefault);
  595.  
  596.   if (i < 0)
  597.     return(False);
  598.  
  599.   get_myname(myname,NULL);
  600.  
  601.   sprintf(comment,"IPC Service (%s)",lp_serverstring());
  602.   string_sub(comment,"%v",VERSION);
  603.   string_sub(comment,"%h",myname);
  604.  
  605.   string_set(&iSERVICE(i).szService,"IPC$");
  606.   string_set(&iSERVICE(i).szPath,"/tmp");
  607.   string_set(&iSERVICE(i).szUsername,"");
  608.   string_set(&iSERVICE(i).comment,comment);
  609.   iSERVICE(i).status = False;
  610.   iSERVICE(i).iMaxConnections = 0;
  611.   iSERVICE(i).bAvailable = True;
  612.   iSERVICE(i).bRead_only = True;
  613.   iSERVICE(i).bGuest_only = True;
  614.   iSERVICE(i).bGuest_ok = True;
  615.   iSERVICE(i).bPrint_ok = False;
  616.   iSERVICE(i).bBrowseable = sDefault.bBrowseable;
  617.  
  618.   DEBUG(2,("adding IPC service\n"));
  619.  
  620.   return(True);
  621. }
  622.  
  623.  
  624. /***************************************************************************
  625. add a new printer service, with defaults coming from service iFrom
  626. ***************************************************************************/
  627. BOOL lp_add_printer(char *pszPrintername, int iDefaultService)
  628. {
  629.   char *comment = "From Printcap";
  630.   int i = add_a_service(pSERVICE(iDefaultService));
  631.   
  632.   if (i < 0)
  633.     return(False);
  634.   
  635.   string_set(&iSERVICE(i).szService,pszPrintername);
  636.   
  637.   /* note that we do NOT default the availability flag to True - */
  638.   /* we take it from the default service passed. This allows all */
  639.   /* dynamic printers to be disabled by disabling the [printers] */
  640.   /* entry (if/when the 'available' keyword is implemented!).    */
  641.   
  642.   /* if there's no default username and the printer is not guest access, */
  643.   /* make the username the service name. */
  644.   if (iSERVICE(i).szUsername[0] == '\0')
  645.     if (!iSERVICE(i).bGuest_ok)
  646.       string_set(&iSERVICE(i).szUsername,pszPrintername);
  647.  
  648.   /* the printer name is set to the service name too. */
  649.   string_set(&iSERVICE(i).szPrintername,pszPrintername);
  650.   string_set(&iSERVICE(i).comment,comment);
  651.   iSERVICE(i).bBrowseable = sDefault.bBrowseable;
  652.   
  653.   DEBUG(2,("adding printer service %s\n",pszPrintername));
  654.   
  655.   return(True);
  656. }
  657.  
  658.  
  659. /***************************************************************************
  660. Do a case-insensitive, whitespace-ignoring string compare.
  661. ***************************************************************************/
  662. static int strwicmp(char *psz1, char *psz2)
  663. {
  664.    /* if BOTH strings are NULL, return TRUE, if ONE is NULL return */
  665.    /* appropriate value. */
  666.    if (psz1 == psz2)
  667.       return (0);
  668.    else
  669.       if (psz1 == NULL)
  670.          return (-1);
  671.       else
  672.           if (psz2 == NULL)
  673.               return (1);
  674.  
  675.    /* sync the strings on first non-whitespace */
  676.    while (1)
  677.    {
  678.       while (isspace(*psz1))
  679.          psz1++;
  680.       while (isspace(*psz2))
  681.          psz2++;
  682.       if (toupper(*psz1) != toupper(*psz2) || *psz1 == '\0' || *psz2 == '\0')
  683.          break;
  684.       psz1++;
  685.       psz2++;
  686.    }
  687.    return (*psz1 - *psz2);
  688. }
  689.  
  690. /***************************************************************************
  691. Map a parameter's string representation to something we can use. 
  692. Returns False if the parameter string is not recognised, else TRUE.
  693. ***************************************************************************/
  694. static int map_parameter(char *pszParmName)
  695. {
  696.    int iIndex;
  697.  
  698.    for (iIndex = 0; parm_table[iIndex].label; iIndex++) 
  699.       if (strwicmp(parm_table[iIndex].label, pszParmName) == 0)
  700.          return(iIndex);
  701.  
  702.    DEBUG(0,( "Unknown parameter encountered: \"%s\"\n", pszParmName));
  703.    return(-1);
  704. }
  705.  
  706.  
  707. /***************************************************************************
  708. Set a boolean variable from the text value stored in the passed string.
  709. Returns True in success, False if the passed string does not correctly 
  710. represent a boolean.
  711. ***************************************************************************/
  712. static BOOL set_boolean(BOOL *pb, char *pszParmValue)
  713. {
  714.    BOOL bRetval;
  715.  
  716.    bRetval = True;
  717.    if (strwicmp(pszParmValue, "yes") == 0 ||
  718.        strwicmp(pszParmValue, "true") == 0 ||
  719.        strwicmp(pszParmValue, "1") == 0)
  720.       *pb = True;
  721.    else
  722.       if (strwicmp(pszParmValue, "no") == 0 ||
  723.           strwicmp(pszParmValue, "False") == 0 ||
  724.           strwicmp(pszParmValue, "0") == 0)
  725.          *pb = False;
  726.       else
  727.       {
  728.          DEBUG(0,( "Badly formed boolean in configuration file: \"%s\".\n",
  729.                pszParmValue));
  730.          bRetval = False;
  731.       }
  732.    return (bRetval);
  733. }
  734.  
  735. /***************************************************************************
  736. Find a service by name. Otherwise works like get_service.
  737. Note that this works from iServiceIndex because it is only called while
  738. loading services, during which time iNumServices does not reflect the number
  739. of correct and complete services.
  740. ***************************************************************************/
  741. static int getservicebyname(char *pszServiceName, service *pserviceDest)
  742. {
  743.    int iService;
  744.  
  745.    for (iService = iServiceIndex - 1; iService >= 0; iService--)
  746.       if (strwicmp(iSERVICE(iService).szService, pszServiceName) == 0) 
  747.       {
  748.          if (pserviceDest != NULL)
  749.        copy_service(pserviceDest, pSERVICE(iService), NULL);
  750.          break;
  751.       }
  752.  
  753.    return (iService);
  754. }
  755.  
  756. /***************************************************************************
  757. free the dynamically allocated parts of the globals structure.
  758. ***************************************************************************/
  759. static void free_globals(void)
  760. {
  761.   int i;
  762.   for (i=0;parm_table[i].label;i++)
  763.     if (parm_table[i].type == P_STRING && parm_table[i].class == P_GLOBAL)
  764.       string_free(parm_table[i].ptr);
  765. }
  766.  
  767. /***************************************************************************
  768. free the dynamically allocated parts of a service struct
  769. ***************************************************************************/
  770. static void free_service(service *pservice)
  771. {
  772.   int i;
  773.   if (!pservice)
  774.      return;
  775.  
  776.   for (i=0;parm_table[i].label;i++)
  777.     if (parm_table[i].type == P_STRING && parm_table[i].class == P_LOCAL)
  778.       string_free((char **)(((char *)pservice) + PTR_DIFF(parm_table[i].ptr,&sDefault)));
  779. }
  780.  
  781. /***************************************************************************
  782. Copy a service structure to another
  783.  
  784. If pcopymapDest is NULL then copy all fields
  785. ***************************************************************************/
  786. static void copy_service(service *pserviceDest, 
  787.                          service *pserviceSource,
  788.                          BOOL *pcopymapDest)
  789. {
  790.   int i;
  791.   BOOL bcopyall = (pcopymapDest == NULL);
  792.  
  793.   for (i=0;parm_table[i].label;i++)
  794.     if (parm_table[i].ptr && parm_table[i].class == P_LOCAL && 
  795.     (bcopyall || pcopymapDest[i]))
  796.       {
  797.     void *def_ptr = parm_table[i].ptr;
  798.     void *src_ptr = 
  799.       ((char *)pserviceSource) + PTR_DIFF(def_ptr,&sDefault);
  800.     void *dest_ptr = 
  801.       ((char *)pserviceDest) + PTR_DIFF(def_ptr,&sDefault);
  802.  
  803.     switch (parm_table[i].type)
  804.       {
  805.       case P_BOOL:
  806.       case P_BOOLREV:
  807.         *(BOOL *)dest_ptr = *(BOOL *)src_ptr;
  808.         break;
  809.  
  810.       case P_INTEGER:
  811.       case P_OCTAL:
  812.         *(int *)dest_ptr = *(int *)src_ptr;
  813.         break;
  814.  
  815.       case P_CHAR:
  816.         *(char *)dest_ptr = *(char *)src_ptr;
  817.         break;
  818.  
  819.       case P_STRING:
  820.         string_set(dest_ptr,*(char **)src_ptr);
  821.         break;        
  822.       }
  823.       }
  824.  
  825.   if (bcopyall)
  826.     {
  827.       init_copymap(pserviceDest);
  828.       if (pserviceSource->copymap)
  829.     memcpy(pserviceDest->copymap,pserviceSource->copymap,sizeof(BOOL)*NUMPARAMETERS);
  830.     }
  831. }
  832.  
  833. /***************************************************************************
  834. Check a service for consistency. Return False if the service is in any way
  835. incomplete or faulty, else True.
  836. ***************************************************************************/
  837. static BOOL service_ok(int iService)
  838. {
  839.    BOOL bRetval;
  840.  
  841.    bRetval = True;
  842.    if (iSERVICE(iService).szService[0] == '\0')
  843.    {
  844.       DEBUG(0,( "The following message indicates an internal error:\n"));
  845.       DEBUG(0,( "No service name in service entry.\n"));
  846.       bRetval = False;
  847.    }
  848.  
  849.    /* The [printers] entry MUST be printable. I'm all for flexibility, but */
  850.    /* I can't see why you'd want a non-printable printer service...        */
  851.    if (strwicmp(iSERVICE(iService).szService,PRINTERS_NAME) == 0)
  852.       if (!iSERVICE(iService).bPrint_ok)
  853.       {
  854.          DEBUG(0,( "WARNING: [%s] service MUST be printable!\n",
  855.                iSERVICE(iService).szService));
  856.      iSERVICE(iService).bPrint_ok = True;
  857.       }
  858.  
  859.    if (iSERVICE(iService).szPath[0] == '\0' &&
  860.        strwicmp(iSERVICE(iService).szService,HOMES_NAME) != 0)
  861.    {
  862.       DEBUG(0,( "No path in service %s\n", iSERVICE(iService).szService));
  863.       bRetval = False;
  864.    }
  865.  
  866.    /* If a service is flagged unavailable, log the fact at level 0. */
  867.    if (!iSERVICE(iService).bAvailable) 
  868.       DEBUG(1,( "NOTE: Service %s is flagged unavailable.\n",
  869.             iSERVICE(iService).szService));
  870.  
  871.    return (bRetval);
  872. }
  873.  
  874.  
  875. /***************************************************************************
  876. handle the interpretation of the protocol parameter
  877. ***************************************************************************/
  878. static BOOL handle_protocol(char *pszParmValue,int *val)
  879. {
  880.   *val = interpret_protocol(pszParmValue,*val);
  881.   return(True);
  882. }
  883.  
  884. /***************************************************************************
  885. handle the interpretation of the security parameter
  886. ***************************************************************************/
  887. static BOOL handle_security(char *pszParmValue,int *val)
  888. {
  889.   *val = interpret_security(pszParmValue,*val);
  890.   return(True);
  891. }
  892.  
  893. /***************************************************************************
  894. handle the interpretation of the default case
  895. ***************************************************************************/
  896. static BOOL handle_case(char *pszParmValue,int *val)
  897. {
  898.   if (strequal(pszParmValue,"LOWER"))
  899.     *val = CASE_LOWER;
  900.   else if (strequal(pszParmValue,"UPPER"))
  901.     *val = CASE_UPPER;
  902.   return(True);
  903. }
  904.  
  905. /***************************************************************************
  906. handle the interpretation of the copy parameter
  907. ***************************************************************************/
  908. static BOOL handle_copy(char *pszParmValue,char **ptr)
  909. {
  910.    BOOL bRetval;
  911.    int iTemp;
  912.    service serviceTemp;
  913.  
  914.    string_set(ptr,pszParmValue);
  915.  
  916.    init_service(&serviceTemp);
  917.  
  918.    bRetval = False;
  919.    
  920.    DEBUG(3,("Copying service from service %s\n",pszParmValue));
  921.  
  922.    if ((iTemp = getservicebyname(pszParmValue, &serviceTemp)) >= 0)
  923.      {
  924.        if (iTemp == iServiceIndex)
  925.      DEBUG(0,( "Can't copy service %s- unable to copy self!\n",
  926.           pszParmValue));
  927.        else
  928.      {
  929.        copy_service(pSERVICE(iServiceIndex), 
  930.             &serviceTemp,
  931.             iSERVICE(iServiceIndex).copymap);
  932.        bRetval = True;
  933.      }
  934.      }
  935.    else
  936.      {
  937.        DEBUG(0,( "Unable to copy service - source not found: %s\n",
  938.         pszParmValue));
  939.        bRetval = False;
  940.      }
  941.  
  942.    free_service(&serviceTemp);
  943.    return (bRetval);
  944. }
  945.  
  946.  
  947. /***************************************************************************
  948. initialise a copymap
  949. ***************************************************************************/
  950. static void init_copymap(service *pservice)
  951. {
  952.   int i;
  953.   if (pservice->copymap) free(pservice->copymap);
  954.   pservice->copymap = (BOOL *)malloc(sizeof(BOOL)*NUMPARAMETERS);
  955.   if (!pservice->copymap)
  956.     DEBUG(0,("Couldn't allocate copymap!! (size %d)\n",NUMPARAMETERS));
  957.  
  958.   for (i=0;i<NUMPARAMETERS;i++)
  959.     pservice->copymap[i] = True;
  960. }
  961.  
  962.  
  963. /***************************************************************************
  964. Process a parameter.
  965. ***************************************************************************/
  966. static BOOL do_parameter(char *pszParmName, char *pszParmValue)
  967. {
  968.    int parmnum;
  969.    void *parm_ptr=NULL; /* where we are going to store the result */
  970.    void *def_ptr=NULL;
  971.  
  972.    DEBUG(3,("doing parameter %s = %s\n",pszParmName,pszParmValue));
  973.    
  974.    parmnum = map_parameter(pszParmName);
  975.  
  976.    if (parmnum < 0)
  977.      {
  978.        DEBUG(0,( "Ignoring unknown parameter \"%s\"\n", pszParmName));
  979.        return(True);
  980.      }
  981.  
  982.    def_ptr = parm_table[parmnum].ptr;
  983.  
  984.    /* we might point at a service, the default service or a global */
  985.    if (bInGlobalSection)
  986.      parm_ptr = def_ptr;
  987.    else
  988.      {
  989.        if (parm_table[parmnum].class == P_GLOBAL)
  990.      {
  991.        DEBUG(0,( "Global parameter %s found in service section!\n",pszParmName));
  992.        return(True);
  993.      }
  994.        parm_ptr = ((char *)pSERVICE(iServiceIndex)) + PTR_DIFF(def_ptr,&sDefault);
  995.      }
  996.  
  997.    if (!bInGlobalSection)
  998.      {
  999.        int i;
  1000.        if (!iSERVICE(iServiceIndex).copymap)
  1001.      init_copymap(pSERVICE(iServiceIndex));
  1002.        
  1003.        /* this handles the aliases - set the copymap for other entries with
  1004.       the same data pointer */
  1005.        for (i=0;parm_table[i].label;i++)
  1006.      if (parm_table[i].ptr == parm_table[parmnum].ptr)
  1007.        iSERVICE(iServiceIndex).copymap[i] = False;
  1008.      }
  1009.  
  1010.    /* if it is a special case then go ahead */
  1011.    if (parm_table[parmnum].special)
  1012.      return(parm_table[parmnum].special(pszParmValue,parm_ptr));
  1013.  
  1014.    /* now switch on the type of variable it is */
  1015.    switch (parm_table[parmnum].type)
  1016.      {
  1017.      case P_BOOL:
  1018.        set_boolean(parm_ptr,pszParmValue);
  1019.        break;
  1020.  
  1021.      case P_BOOLREV:
  1022.        set_boolean(parm_ptr,pszParmValue);
  1023.        *(BOOL *)parm_ptr = ! *(BOOL *)parm_ptr;
  1024.        break;
  1025.  
  1026.      case P_INTEGER:
  1027.        *(int *)parm_ptr = atoi(pszParmValue);
  1028.        break;
  1029.  
  1030.      case P_CHAR:
  1031.        *(char *)parm_ptr = *pszParmValue;
  1032.        break;
  1033.  
  1034.      case P_OCTAL:
  1035.        sscanf(pszParmValue,"%o",(int *)parm_ptr);
  1036.        break;
  1037.  
  1038.      case P_STRING:
  1039.        string_set(parm_ptr,pszParmValue);
  1040.        break;
  1041.      }
  1042.  
  1043.    return(True);
  1044. }
  1045.  
  1046. /***************************************************************************
  1047. print a parameter of the specified type
  1048. ***************************************************************************/
  1049. static void print_parameter(parm_type type,void *ptr)
  1050. {
  1051.   switch (type)
  1052.     {
  1053.     case P_BOOL:
  1054.       printf("%s",BOOLSTR(*(BOOL *)ptr));
  1055.       break;
  1056.       
  1057.     case P_BOOLREV:
  1058.       printf("%s",BOOLSTR(! *(BOOL *)ptr));
  1059.       break;
  1060.       
  1061.     case P_INTEGER:
  1062.       printf("%d",*(int *)ptr);
  1063.       break;
  1064.       
  1065.     case P_CHAR:
  1066.       printf("%c",*(char *)ptr);
  1067.       break;
  1068.       
  1069.     case P_OCTAL:
  1070.       printf("0%o",*(int *)ptr);
  1071.       break;
  1072.       
  1073.     case P_STRING:
  1074.       if (*(char **)ptr)
  1075.     printf("%s",*(char **)ptr);
  1076.       break;
  1077.     }
  1078. }
  1079.  
  1080.  
  1081. /***************************************************************************
  1082. check if two parameters are equal
  1083. ***************************************************************************/
  1084. static BOOL equal_parameter(parm_type type,void *ptr1,void *ptr2)
  1085. {
  1086.   switch (type)
  1087.     {
  1088.     case P_BOOL:
  1089.     case P_BOOLREV:
  1090.       return(*((BOOL *)ptr1) == *((BOOL *)ptr2));
  1091.  
  1092.     case P_INTEGER:
  1093.     case P_OCTAL:
  1094.       return(*((int *)ptr1) == *((int *)ptr2));
  1095.       
  1096.     case P_CHAR:
  1097.       return(*((char *)ptr1) == *((char *)ptr2));
  1098.  
  1099.     case P_STRING:
  1100.       {
  1101.     char *p1 = *(char **)ptr1, *p2 = *(char **)ptr2;
  1102.     if (p1 && !*p1) p1 = NULL;
  1103.     if (p2 && !*p2) p2 = NULL;
  1104.     return(p1==p2 || strequal(p1,p2));
  1105.       }
  1106.     }
  1107.   return(False);
  1108. }
  1109.  
  1110. /***************************************************************************
  1111. Process a new section (service). At this stage all sections are services.
  1112. Later we'll have special sections that permit server parameters to be set.
  1113. Returns True on success, False on failure.
  1114. ***************************************************************************/
  1115. static BOOL do_section(char *pszSectionName)
  1116. {
  1117.    BOOL bRetval;
  1118.  
  1119.    bRetval = False;
  1120.  
  1121.    /* if we've just struck a global section, note the fact. */
  1122.    bInGlobalSection = (strwicmp(pszSectionName, GLOBAL_NAME) == 0);
  1123.  
  1124.    /* check for multiple global sections */
  1125.    if (bInGlobalSection)
  1126.    {
  1127.       /* if found, bug out with error */
  1128.       if (bDoneGlobalSection)
  1129.          DEBUG(0,( "Multiple global sections found in configuration file!\n"));
  1130.       else
  1131.       {
  1132.          /* otherwise there is nothing more to do here */
  1133.          DEBUG(3,( "Processing section \"[%s]\"\n", pszSectionName));
  1134.          bDoneGlobalSection = True;
  1135.          bRetval = True;
  1136.       }
  1137.       return (bRetval);
  1138.    }
  1139.  
  1140.    /*
  1141.     * Following processing occurs only for service sections, not for global
  1142.     */
  1143.  
  1144.    /* check that service name is unique */
  1145.    if (getservicebyname(pszSectionName, NULL) >= 0)
  1146.    {
  1147.       DEBUG(0,( "The service name \"%s\" is not unique.\n", pszSectionName));
  1148.       return (bRetval);
  1149.    }
  1150.  
  1151.    if (iServiceIndex >= iNumServices)
  1152.    {
  1153.       DEBUG(0,( "Maximum service count (%d) exceeded at service \"%s\"\n",
  1154.             iNumServices, pszSectionName));
  1155.    }
  1156.    else
  1157.    {
  1158.       /* if we have a current service, tidy it up before moving on */
  1159.       bRetval = True;
  1160.  
  1161.       if (iServiceIndex >= 0)
  1162.          bRetval = service_ok(iServiceIndex);
  1163.  
  1164.       /* if all is still well, move to the next record in the services array */
  1165.       if (bRetval)
  1166.       {
  1167.          /* We put this here to avoid an odd message order if messages are */
  1168.          /* issued by the post-processing of a previous section. */
  1169.          DEBUG(3,( "Processing section \"[%s]\"\n", pszSectionName));
  1170.  
  1171.          iServiceIndex++;
  1172.  
  1173.      if (add_a_service(&sDefault) < 0)
  1174.        {
  1175.          DEBUG(0,("Failed to add a new service\n"));
  1176.          return(False);
  1177.        }
  1178.  
  1179.          string_init(&iSERVICE(iServiceIndex).szService, pszSectionName); 
  1180.       }
  1181.    }
  1182.    return (bRetval);
  1183. }
  1184.  
  1185. /***************************************************************************
  1186. Display the contents of the global structure.
  1187. ***************************************************************************/
  1188. static void dump_globals(void)
  1189. {
  1190.   int i;
  1191.   printf("Global parameters:\n");
  1192.  
  1193.   for (i=0;parm_table[i].label;i++)
  1194.     if (parm_table[i].class == P_GLOBAL &&
  1195.     parm_table[i].ptr &&
  1196.     (i == 0 || (parm_table[i].ptr != parm_table[i-1].ptr)))
  1197.       {
  1198.     printf("\t%s: ",parm_table[i].label);
  1199.     print_parameter(parm_table[i].type,parm_table[i].ptr);
  1200.     printf("\n");
  1201.       }
  1202. }
  1203.  
  1204. /***************************************************************************
  1205. Display the contents of a single services record.
  1206. ***************************************************************************/
  1207. static void dump_a_service(service *pService)
  1208. {
  1209.   int i;
  1210.   if (pService == &sDefault)
  1211.     printf("\nDefault service parameters:\n");
  1212.   else
  1213.     printf("\nService parameters [%s]:\n",pService->szService);
  1214.  
  1215.   for (i=0;parm_table[i].label;i++)
  1216.     if (parm_table[i].class == P_LOCAL &&
  1217.     parm_table[i].ptr && 
  1218.     (i == 0 || (parm_table[i].ptr != parm_table[i-1].ptr)))
  1219.       {
  1220.     int pdiff = PTR_DIFF(parm_table[i].ptr,&sDefault);
  1221.  
  1222.     if (pService == &sDefault || !equal_parameter(parm_table[i].type,
  1223.                               ((char *)pService) + pdiff,
  1224.                               ((char *)&sDefault) + pdiff))
  1225.       {
  1226.         printf("\t%s: ",parm_table[i].label);
  1227.         print_parameter(parm_table[i].type,
  1228.                 ((char *)pService) + pdiff);
  1229.         printf("\n");
  1230.       }
  1231.       }
  1232. }
  1233.  
  1234. #if 0
  1235. /***************************************************************************
  1236. Display the contents of a single copy structure.
  1237. ***************************************************************************/
  1238. static void dump_copy_map(BOOL *pcopymap)
  1239. {
  1240.   int i;
  1241.   if (!pcopymap) return;
  1242.  
  1243.   printf("\n\tNon-Copied parameters:\n");
  1244.  
  1245.   for (i=0;parm_table[i].label;i++)
  1246.     if (parm_table[i].class == P_LOCAL &&
  1247.     parm_table[i].ptr && !pcopymap[i] &&
  1248.     (i == 0 || (parm_table[i].ptr != parm_table[i-1].ptr)))
  1249.       {
  1250.     printf("\t\t%s\n",parm_table[i].label);
  1251.       }
  1252. }
  1253. #endif
  1254.  
  1255. /***************************************************************************
  1256. Return TRUE if the passed service number is within range.
  1257. ***************************************************************************/
  1258. BOOL lp_snum_ok(int iService)
  1259. {
  1260.    return (LP_SNUM_OK(iService) && iSERVICE(iService).bAvailable);
  1261. }
  1262.  
  1263.  
  1264. /***************************************************************************
  1265. Discard the services array. Used internally, but available for external use
  1266. by the conscientious. Also unloads the globals.
  1267. ***************************************************************************/
  1268. void lp_unload(void)
  1269. {
  1270.    bDoneGlobalSection = False;
  1271.    bInGlobalSection = False;
  1272.  
  1273.    free_globals();
  1274.    if (ServicePtrs)
  1275.    {
  1276.      int i;
  1277.      for (i=0;i<iNumServices;i++)
  1278.        {
  1279.      free_service(pSERVICE(i));
  1280.      free(pSERVICE(i));
  1281.        }
  1282.       free (ServicePtrs);
  1283.       ServicePtrs = NULL;
  1284.    }
  1285.  
  1286.    iNumServices = 0;
  1287. }
  1288.  
  1289. /***************************************************************************
  1290. auto-load some homes and printer services
  1291. ***************************************************************************/
  1292. void lp_add_auto_services(char *str)
  1293. {
  1294.   char *s;
  1295.   char *p;
  1296.   int homes = lp_servicenumber(HOMES_NAME);
  1297.   int printers = lp_servicenumber(PRINTERS_NAME);
  1298.  
  1299.   if (!str)
  1300.     return;
  1301.  
  1302.   s = strdup(str);
  1303.   if (!s) return;
  1304.  
  1305.   for (p=strtok(s,LIST_SEP);p;p=strtok(NULL,LIST_SEP))
  1306.     {
  1307.       char *home = get_home_dir(p);
  1308.  
  1309.       if (lp_servicenumber(p) >= 0) continue;
  1310.  
  1311.       if (home && homes >= 0)
  1312.     {
  1313.       lp_add_home(p,homes,home);
  1314.       continue;
  1315.     }
  1316.  
  1317.       if (printers >= 0 && pcap_printername_ok(p,NULL))
  1318.     lp_add_printer(p,printers);
  1319.     }
  1320.   free(s);
  1321. }
  1322.  
  1323. /***************************************************************************
  1324. auto-load one printer
  1325. ***************************************************************************/
  1326. void lp_add_one_printer(char *name,char *comment)
  1327. {
  1328.   int printers = lp_servicenumber(PRINTERS_NAME);
  1329.   int i;
  1330.  
  1331.   if (lp_servicenumber(name) < 0)
  1332.     {
  1333.       lp_add_printer(name,printers);
  1334.       if ((i=lp_servicenumber(name)) >= 0)
  1335.     string_set(&iSERVICE(i).comment,comment);
  1336.     }      
  1337. }
  1338.  
  1339.  
  1340. /***************************************************************************
  1341. auto-load printer services
  1342. ***************************************************************************/
  1343. void lp_add_all_printers(void)
  1344. {
  1345.   int printers = lp_servicenumber(PRINTERS_NAME);
  1346.  
  1347.   if (printers < 0) return;
  1348.  
  1349.   pcap_printer_fn(lp_add_one_printer);
  1350. }
  1351.  
  1352.  
  1353. /***************************************************************************
  1354. Load the services array from the services file. Return True on success, 
  1355. False on failure.
  1356. ***************************************************************************/
  1357. BOOL lp_load(char *pszFname)
  1358. {
  1359.   static BOOL first_time = True;
  1360.  
  1361.   BOOL bRetval;
  1362.   
  1363.   bRetval = False;
  1364.   
  1365.   /* throw away any existing service details */
  1366.   if (!first_time)
  1367.     lp_unload();
  1368.   first_time = False;
  1369.   init_globals();
  1370.   
  1371.   /* We get sections first, so have to start 'behind' to make up */
  1372.   iServiceIndex = -1;
  1373.   bRetval = pm_process(pszFname, do_section, do_parameter);
  1374.   
  1375.   /* finish up the last section */
  1376.   DEBUG(3,( "pm_process() returned %s\n", BOOLSTR(bRetval)));
  1377.   if (bRetval)
  1378.     if (iServiceIndex >= 0)
  1379.       bRetval = service_ok(iServiceIndex);       
  1380.  
  1381.  
  1382.   lp_add_auto_services(lp_auto_services());
  1383.   if (lp_load_printers())
  1384.     lp_add_all_printers();
  1385.  
  1386.   lp_add_ipc();
  1387.  
  1388.   if (Globals.maxprotocol < PROTOCOL_LANMAN1)
  1389.     DEBUG(0,("WARNING! You have restricted the maximum protocol to be below LANMAN1.\nThis may not be what you want in this version of Samba\nSee the README for details."));  
  1390.   
  1391.   return (bRetval);
  1392. }
  1393.  
  1394. /***************************************************************************
  1395. how many services are available
  1396. ***************************************************************************/
  1397. int lp_numservices(void)
  1398. {
  1399.   return(iNumServices);
  1400. }
  1401.  
  1402. /***************************************************************************
  1403. Display the contents of the services array in human-readable form.
  1404. ***************************************************************************/
  1405. void lp_dump(void)
  1406. {
  1407.    int iService;
  1408.  
  1409.    dump_globals();
  1410.    
  1411.    dump_a_service(&sDefault);
  1412.  
  1413.    for (iService = 0; iService < iNumServices; iService++)
  1414.    {
  1415.       if (iSERVICE(iService).szService[0] == '\0')
  1416.          break;
  1417.       dump_a_service(pSERVICE(iService));
  1418. #if 0
  1419.       dump_copy_map(iSERVICE(iService).copymap);
  1420. #endif
  1421.    }
  1422. }
  1423.  
  1424. /***************************************************************************
  1425. Return the number of the service with the given name, or -1 if it doesn't
  1426. exist. Note that this is a DIFFERENT ANIMAL from the internal function
  1427. getservicebyname()! This works ONLY if all services have been loaded, and
  1428. does not copy the found service.
  1429. ***************************************************************************/
  1430. int lp_servicenumber(char *pszServiceName)
  1431. {
  1432.    int iService;
  1433.  
  1434.    for (iService = iNumServices - 1; iService >= 0; iService--)
  1435.       if (strwicmp(iSERVICE(iService).szService, pszServiceName) == 0) 
  1436.          break;
  1437.  
  1438.    if (iService < 0)
  1439.      DEBUG(7,("lp_servicenumber: couldn't find %s\n",pszServiceName));
  1440.    
  1441.    return (iService);
  1442. }
  1443.  
  1444.  
  1445.  
  1446.  
  1447.