分享
 
 
 

samba unix风格的配置文件配置信息读取C代码.

王朝system·作者佚名  2006-01-09
窄屏简体版  字體: |||超大  

samba是个开源的文件服务器软件,可以在多个平台上运行.如果你使用过,那么一定设置过它的配置文件.

如果你想写一个类似读这样的配置文件的代码,那么下面的从samba提取出来的代码讲对你很有用.它采用

回调的机制,获取配置信息.

smb.conf 如下

# This is the main Samba configuration file. You should read the

# smb.conf(5) manual page in order to understand the options listed

# here. Samba has a huge number of configurable options (perhaps too

# many!) most of which are not shown in this example

#

# Any line which starts with a ; (semi-colon) or a # (hash)

# is a comment and is ignored. In this example we will use a #

# for commentry and a ; for parts of the config file that you

# may wish to enable

#

# NOTE: Whenever you modify this file you should run the command "testparm"

# to check that you have not made any basic syntactic errors.

#

#======================= Global Settings =====================================

[global]

# workgroup = NT-Domain-Name or Workgroup-Name

workgroup = gdcattsoft

# server string is the equivalent of the NT Description field

server string = samba server

# This option is important for security. It allows you to restrict

# connections to machines which are on your local network. The

# following example restricts access to two C class networks and

# the "loopback" interface. For more examples of the syntax see

# the smb.conf man page

; hosts allow = 192.168.1. 192.168.2. 127.

# if you want to automatically load your printer list rather

# than setting them up individually then you'll need this

printcap name = /etc/printcap

load printers = yes

# It should not be necessary to spell out the print system type unless

# yours is non-standard. Currently supported print systems include:

# bsd, sysv, plp, lprng, aix, hpux, qnx, cups

printing = cups

# Uncomment this if you want a guest account, you must add this to /etc/passwd

# otherwise the user "nobody" is used

; guest account = pcguest

# this tells Samba to use a separate log file for each machine

# that connects

log file = /var/log/samba/%m.log

# Put a capping on the size of the log files (in Kb).

max log size = 0

# Security mode. Most people will want user level security. See

# security_level.txt for details.

# Use password server option only with security = server

# The argument list may include:

# password server = My_PDC_Name [My_BDC_Name] [My_Next_BDC_Name]

# or to auto-locate the domain controller/s

# password server = *

; password server = <NT-Server-Name>

# Password Level allows matching of _n_ characters of the password for

# all combinations of upper and lower case.

; password level = 8

; username level = 8

# You may wish to use password encryption. Please read

# ENCRYPTION.txt, Win95.txt and WinNT.txt in the Samba documentation.

# Do not enable this option unless you have read those documents

encrypt passwords = yes

smb passwd file = /etc/samba/smbpasswd

# The following is needed to keep smbclient from spouting spurious errors

# when Samba is built with support for SSL.

; ssl CA certFile = /usr/share/ssl/certs/ca-bundle.crt

.....

/* -------------------------------------------------------------------------- **

*

* Module name: params

*

* -------------------------------------------------------------------------- **

*

* This module performs lexical analysis and initial parsing of a

* Windows-like parameter file. It recognizes and handles four token

* types: section-name, parameter-name, parameter-value, and

* end-of-file. Comments and line continuation are handled

* internally.

*

* The entry point to the module is function pm_process(). This

* function opens the source file, calls the Parse() function to parse

* the input, and then closes the file when either the EOF is reached

* or a fatal error is encountered.

*

* A sample parameter file might look like this:

*

* [section one]

* parameter one = value string

* parameter two = another value

* [section two]

* new parameter = some value or t'other

*

* The parameter file is divided into sections by section headers:

* section names enclosed in square brackets (eg. [section one]).

* Each section contains parameter lines, each of which consist of a

* parameter name and value delimited by an equal sign. Roughly, the

* syntax is:

*

* <file> :== { <section> } EOF

*

* <section> :== <section header> { <parameter line> }

*

* <section header> :== '[' NAME ']'

*

* <parameter line> :== NAME '=' VALUE '\n'

*

* Blank lines and comment lines are ignored. Comment lines are lines

* beginning with either a semicolon (';') or a pound sign ('#').

*

* All whitespace in section names and parameter names is compressed

* to single spaces. Leading and trailing whitespace is stipped from

* both names and values.

*

* Only the first equals sign in a parameter line is significant.

* Parameter values may contain equals signs, square brackets and

* semicolons. Internal whitespace is retained in parameter values,

* with the exception of the '\r' character, which is stripped for

* historic reasons. Parameter names may not start with a left square

* bracket, an equal sign, a pound sign, or a semicolon, because these

* are used to identify other tokens.

*

* -------------------------------------------------------------------------- **

*/

#include "stdafx.h"

#include <stdio.h>

#include <stdlib.h>

#include <fcntl.h>

#include <string.h>

#include <ctype.h>

#include <sys/stat.h>

#include <sys/types.h>

#ifdef WIN32

#include <io.h>

#define open _open

#define read _read

#define close _close

#endif

#ifndef WIN32

#include <unistd.h>

#endif

/* -------------------------------------------------------------------------- **

* Define & Constants...

*/

#define BUFR_INC 1024

#define False (0)

#define True (1)

#define Auto (2)

#ifndef _BOOL

typedef int BOOL;

#define _BOOL /* So we don't typedef BOOL again in vfs.h */

#endif

/* free memory if the pointer is valid and zero the pointer */

#ifndef SAFE_FREE

#define SAFE_FREE(x) do { if ((x) != NULL) {free((x)); (x)=NULL;} } while(0)

#endif

/* Global val set if multibyte codepage. */

extern int global_is_multibyte_codepage;

extern int (*_skip_multibyte_char)(char c);

#define skip_multibyte_char(c) ((*_skip_multibyte_char)((c)))

//#define get_character_len(x) (global_is_multibyte_codepage ? skip_multibyte_char((x)) : 0)

#define get_character_len(x) 0

/* -------------------------------------------------------------------------- **

* Variables...

*

* DEBUGLEVEL - The ubiquitous DEBUGLEVEL. This determines which //DEBUG()

* messages will be produced.

* bufr - pointer to a global buffer. This is probably a kludge,

* but it was the nicest kludge I could think of (for now).

* bSize - The size of the global buffer <bufr>.

*/

static char *bufr = NULL;

static int bSize = 0;

/* we can't use FILE* due to the 256 fd limit - use this cheap hack

instead */

typedef struct {

char *buf;

char *p;

size_t size;

} myFILE;

static int mygetc(myFILE *f)

{

if (f->p >= f->buf+f->size) return EOF;

/* be sure to return chars >127 as positive values */

return (int)( *(f->p++) & 0x00FF );

}

static void myfile_close(myFILE *f)

{

if (!f) return;

SAFE_FREE(f->buf);

SAFE_FREE(f);

}

/* -------------------------------------------------------------------------- **

* Functions...

*/

static int EatWhitespace( myFILE *InFile )

/* ------------------------------------------------------------------------ **

* Scan past whitespace (see ctype(3C)) and return the first non-whitespace

* character, or newline, or EOF.

*

* Input: InFile - Input source.

*

* Output: The next non-whitespace character in the input stream.

*

* Notes: Because the config files use a line-oriented grammar, we

* explicitly exclude the newline character from the list of

* whitespace characters.

* - Note that both EOF (-1) and the nul character ('\0') are

* considered end-of-file markers.

*

* ------------------------------------------------------------------------ **

*/

{

int c;

for( c = mygetc( InFile ); isspace( c ) && ('\n' != c); c = mygetc( InFile ) )

;

return( c );

} /* EatWhitespace */

static int EatComment( myFILE *InFile )

/* ------------------------------------------------------------------------ **

* Scan to the end of a comment.

*

* Input: InFile - Input source.

*

* Output: The character that marks the end of the comment. Normally,

* this will be a newline, but it *might* be an EOF.

*

* Notes: Because the config files use a line-oriented grammar, we

* explicitly exclude the newline character from the list of

* whitespace characters.

* - Note that both EOF (-1) and the nul character ('\0') are

* considered end-of-file markers.

*

* ------------------------------------------------------------------------ **

*/

{

int c;

for( c = mygetc( InFile ); ('\n'!=c) && (EOF!=c) && (c>0); c = mygetc( InFile ) )

;

return( c );

} /* EatComment */

/*****************************************************************************

* Scan backards within a string to discover if the last non-whitespace

* character is a line-continuation character ('\\').

*

* Input: line - A pointer to a buffer containing the string to be

* scanned.

* pos - This is taken to be the offset of the end of the

* string. This position is *not* scanned.

*

* Output: The offset of the '\\' character if it was found, or -1 to

* indicate that it was not.

*

*****************************************************************************/

static int Continuation( char *line, int pos )

{

int pos2 = 0;

pos--;

while( (pos >= 0) && isspace((int)line[pos]) )

pos--;

/* we should recognize if `\` is part of a multibyte character or not. */

while(pos2 <= pos) {

size_t skip = 0;

skip = get_character_len(line[pos2]);

if (skip) {

pos2 += skip;

} else if (pos == pos2) {

return( ((pos >= 0) && ('\\' == line[pos])) ? pos : -1 );

} else {

pos2++;

}

}

return (-1);

}

void *Realloc(void *p,size_t size)

/* ------------------------------------------------------------------------ **

* expand a pointer to be a particular size

/* ------------------------------------------------------------------------ **/

{

void *ret=NULL;

if (size == 0) {

if (p) free(p);

//DEBUG(5,("Realloc asked for 0 bytes\n"));

return NULL;

}

if (!p)

ret = (void *)malloc(size);

else

ret = (void *)realloc(p,size);

if (!ret)

printf("Memory allocation error: failed to expand to %d bytes\n",(int)size);

return(ret);

}

static BOOL Section( myFILE *InFile, BOOL (*sfunc)(char *) )

/* ------------------------------------------------------------------------ **

* Scan a section name, and pass the name to function sfunc().

*

* Input: InFile - Input source.

* sfunc - Pointer to the function to be called if the section

* name is successfully read.

*

* Output: True if the section name was read and True was returned from

* <sfunc>. False if <sfunc> failed or if a lexical error was

* encountered.

*

* ------------------------------------------------------------------------ **

*/

{

int c;

int i;

int end;

char *func = "params.c:Section() -";

i = 0; /* <i> is the offset of the next free byte in bufr[] and */

end = 0; /* <end> is the current "end of string" offset. In most */

/* cases these will be the same, but if the last */

/* character written to bufr[] is a space, then <end> */

/* will be one less than <i>. */

c = EatWhitespace( InFile ); /* We've already got the '['. Scan */

/* past initial white space. */

while( (EOF != c) && (c > 0) )

{

/* Check that the buffer is big enough for the next character. */

if( i > (bSize - 2) )

{

char *tb;

tb = (char*)Realloc( bufr, bSize +BUFR_INC );

if( NULL == tb )

{

//DEBUG(0, ("%s Memory re-allocation failure.", func) );

return( False );

}

bufr = tb;

bSize += BUFR_INC;

}

/* Handle a single character. */

switch( c )

{

case ']': /* Found the closing bracket. */

bufr[end] = '\0';

if( 0 == end ) /* Don't allow an empty name. */

{

//DEBUG(0, ("%s Empty section name in configuration file.\n", func ));

return( False );

}

//if( !sfunc( unix_to_dos(bufr) ) ) /* Got a valid name. Deal with it. */

if( !sfunc( bufr ) ) /* Got a valid name. Deal with it. */

return( False );

(void)EatComment( InFile ); /* Finish off the line. */

return( True );

case '\n': /* Got newline before closing ']'. */

i = Continuation( bufr, i ); /* Check for line continuation. */

if( i < 0 )

{

bufr[end] = '\0';

//DEBUG(0, ("%s Badly formed line in configuration file: %s\n",func, bufr ));

return( False );

}

end = ( (i > 0) && (' ' == bufr[i - 1]) ) ? (i - 1) : (i);

c = mygetc( InFile ); /* Continue with next line. */

break;

default: /* All else are a valid name chars. */

if( isspace( c ) ) /* One space per whitespace region. */

{

bufr[end] = ' ';

i = end + 1;

c = EatWhitespace( InFile );

}

else /* All others copy verbatim. */

{

bufr[i++] = c;

end = i;

c = mygetc( InFile );

}

}

}

/* We arrive here if we've met the EOF before the closing bracket. */

//DEBUG(0, ("%s Unexpected EOF in the configuration file: %s\n", func, bufr ));

return( False );

} /* Section */

static BOOL Parameter( myFILE *InFile, BOOL (*pfunc)(char *, char *), int c )

/* ------------------------------------------------------------------------ **

* Scan a parameter name and value, and pass these two fields to pfunc().

*

* Input: InFile - The input source.

* pfunc - A pointer to the function that will be called to

* process the parameter, once it has been scanned.

* c - The first character of the parameter name, which

* would have been read by Parse(). Unlike a comment

* line or a section header, there is no lead-in

* character that can be discarded.

*

* Output: True if the parameter name and value were scanned and processed

* successfully, else False.

*

* Notes: This function is in two parts. The first loop scans the

* parameter name. Internal whitespace is compressed, and an

* equal sign (=) terminates the token. Leading and trailing

* whitespace is discarded. The second loop scans the parameter

* value. When both have been successfully identified, they are

* passed to pfunc() for processing.

*

* ------------------------------------------------------------------------ **

*/

{

int i = 0; /* Position within bufr. */

int end = 0; /* bufr[end] is current end-of-string. */

int vstart = 0; /* Starting position of the parameter value. */

char *func = "params.c:Parameter() -";

/* Read the parameter name. */

while( 0 == vstart ) /* Loop until we've found the start of the value. */

{

if( i > (bSize - 2) ) /* Ensure there's space for next char. */

{

char *tb;

tb = (char*)Realloc( bufr, bSize + BUFR_INC );

if( NULL == tb )

{

//DEBUG(0, ("%s Memory re-allocation failure.", func) );

return( False );

}

bufr = tb;

bSize += BUFR_INC;

}

switch( c )

{

case '=': /* Equal sign marks end of param name. */

if( 0 == end ) /* Don't allow an empty name. */

{

//DEBUG(0, ("%s Invalid parameter name in config. file.\n", func ));

return( False );

}

bufr[end++] = '\0'; /* Mark end of string & advance. */

i = end; /* New string starts here. */

vstart = end; /* New string is parameter value. */

bufr[i] = '\0'; /* New string is nul, for now. */

break;

case '\n': /* Find continuation char, else error. */

i = Continuation( bufr, i );

if( i < 0 )

{

bufr[end] = '\0';

//DEBUG(1,("%s Ignoring badly formed line in configuration file: %s\n",func, bufr ));

return( True );

}

end = ( (i > 0) && (' ' == bufr[i - 1]) ) ? (i - 1) : (i);

c = mygetc( InFile ); /* Read past eoln. */

break;

case '\0': /* Shouldn't have EOF within param name. */

case EOF:

bufr[i] = '\0';

//DEBUG(1,("%s Unexpected end-of-file at: %s\n", func, bufr ));

return( True );

default:

if( isspace( c ) ) /* One ' ' per whitespace region. */

{

bufr[end] = ' ';

i = end + 1;

c = EatWhitespace( InFile );

}

else /* All others verbatim. */

{

bufr[i++] = c;

end = i;

c = mygetc( InFile );

}

}

}

/* Now parse the value. */

c = EatWhitespace( InFile ); /* Again, trim leading whitespace. */

while( (EOF !=c) && (c > 0) )

{

if( i > (bSize - 2) ) /* Make sure there's enough room. */

{

bSize += BUFR_INC;

bufr = (char*)Realloc( bufr, bSize );

if( NULL == bufr )

{

//DEBUG(0, ("%s Memory re-allocation failure.", func) );

return( False );

}

}

switch( c )

{

case '\r': /* Explicitly remove '\r' because the older */

c = mygetc( InFile ); /* version called fgets_slash() which also */

break; /* removes them. */

case '\n': /* Marks end of value unless there's a '\'. */

i = Continuation( bufr, i );

if( i < 0 )

c = 0;

else

{

for( end = i; (end >= 0) && isspace((int)bufr[end]); end-- )

;

c = mygetc( InFile );

}

break;

default: /* All others verbatim. Note that spaces do */

bufr[i++] = c; /* not advance <end>. This allows trimming */

if( !isspace( c ) ) /* of whitespace at the end of the line. */

end = i;

c = mygetc( InFile );

break;

}

}

bufr[end] = '\0'; /* End of value. */

return( pfunc( bufr, &bufr[vstart] ) ); /* Pass name & value to pfunc(). */

} /* Parameter */

static BOOL Parse( myFILE *InFile,

BOOL (*sfunc)(char *),

BOOL (*pfunc)(char *, char *) )

/* ------------------------------------------------------------------------ **

* Scan & parse the input.

*

* Input: InFile - Input source.

* sfunc - Function to be called when a section name is scanned.

* See Section().

* pfunc - Function to be called when a parameter is scanned.

* See Parameter().

*

* Output: True if the file was successfully scanned, else False.

*

* Notes: The input can be viewed in terms of 'lines'. There are four

* types of lines:

* Blank - May contain whitespace, otherwise empty.

* Comment - First non-whitespace character is a ';' or '#'.

* The remainder of the line is ignored.

* Section - First non-whitespace character is a '['.

* Parameter - The default case.

*

* ------------------------------------------------------------------------ **

*/

{

int c;

c = EatWhitespace( InFile );

while( (EOF != c) && (c > 0) )

{

switch( c )

{

case '\n': /* Blank line. */

c = EatWhitespace( InFile );

break;

case ';': /* Comment line. */

case '#':

c = EatComment( InFile );

break;

case '[': /* Section Header. */

if( !Section( InFile, sfunc ) )

return( False );

c = EatWhitespace( InFile );

break;

case '\\': /* Bogus backslash. */

c = EatWhitespace( InFile );

break;

default: /* Parameter line. */

if( !Parameter( InFile, pfunc, c ) )

return( False );

c = EatWhitespace( InFile );

break;

}

}

return( True );

} /* Parse */

/****************************************************************************

load a file into memory from a fd.

****************************************************************************/

char *fd_load(int fd, size_t *size)

{

struct stat sbuf;

char *p;

if (fstat(fd, &sbuf) != 0) return NULL;

p = (char *)malloc(sbuf.st_size+1);

if (!p) return NULL;

if (read(fd, p, sbuf.st_size) != sbuf.st_size) {

SAFE_FREE(p);

return NULL;

}

p[sbuf.st_size] = 0;

if (size) *size = sbuf.st_size;

return p;

}

/****************************************************************************

load a file into memory

****************************************************************************/

char *file_load(char *fname, size_t *size)

{

int fd;

char *p;

if (!fname || !*fname) return NULL;

fd = open( fname, O_RDONLY );

if (fd == -1) return NULL;

p = fd_load(fd, size);

close(fd);

return p;

}

static myFILE *OpenConfFile( char *FileName )

/* ------------------------------------------------------------------------ **

* Open a configuration file.

*

* Input: FileName - The pathname of the config file to be opened.

*

* Output: A pointer of type (char **) to the lines of the file

*

* ------------------------------------------------------------------------ **

*/

{

char *func = "params.c:OpenConfFile() -";

//extern BOOL in_client;

//int lvl = in_client?1:0;

myFILE *ret;

ret = (myFILE *)malloc(sizeof(*ret));

if (!ret) return NULL;

ret->buf = file_load(FileName, &ret->size);

if( NULL == ret->buf )

{

//DEBUG( lvl,

// ("%s Unable to open configuration file \"%s\":\n\t%s\n",

// func, FileName, strerror(errno)) );

SAFE_FREE(ret);

return NULL;

}

ret->p = ret->buf;

return( ret );

} /* OpenConfFile */

BOOL pm_process( char *FileName,

BOOL (*sfunc)(char *),

BOOL (*pfunc)(char *, char *) )

/* ------------------------------------------------------------------------ **

* Process the named parameter file.

*

* Input: FileName - The pathname of the parameter file to be opened.

* sfunc - A pointer to a function that will be called when

* a section name is discovered.

* pfunc - A pointer to a function that will be called when

* a parameter name and value are discovered.

*

* Output: TRUE if the file was successfully parsed, else FALSE.

*

* ------------------------------------------------------------------------ **

*/

{

int result;

myFILE *InFile;

char *func = "params.c:pm_process() -";

InFile = OpenConfFile( FileName ); /* Open the config file. */

if( NULL == InFile )

return( False );

//DEBUG( 3, ("%s Processing configuration file \"%s\"\n", func, FileName) );

if( NULL != bufr ) /* If we already have a buffer */

result = Parse( InFile, sfunc, pfunc ); /* (recursive call), then just */

/* use it. */

else /* If we don't have a buffer */

{ /* allocate one, then parse, */

bSize = BUFR_INC; /* then free. */

bufr = (char *)malloc( bSize );

if( NULL == bufr )

{

//DEBUG(0,("%s memory allocation failure.\n", func));

myfile_close(InFile);

return( False );

}

result = Parse( InFile, sfunc, pfunc );

SAFE_FREE( bufr );

bufr = NULL;

bSize = 0;

}

myfile_close(InFile);

if( !result ) /* Generic failure. */

{

//DEBUG(0,("%s Failed. Error returned from params.c:parse().\n", func));

return( False );

}

return( True ); /* Generic success. */

} /* pm_process */

/* -------------------------------------------------------------------------- */

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
2023年上半年GDP全球前十五强
 百态   2023-10-24
美众议院议长启动对拜登的弹劾调查
 百态   2023-09-13
上海、济南、武汉等多地出现不明坠落物
 探索   2023-09-06
印度或要将国名改为“巴拉特”
 百态   2023-09-06
男子为女友送行,买票不登机被捕
 百态   2023-08-20
手机地震预警功能怎么开?
 干货   2023-08-06
女子4年卖2套房花700多万做美容:不但没变美脸,面部还出现变形
 百态   2023-08-04
住户一楼被水淹 还冲来8头猪
 百态   2023-07-31
女子体内爬出大量瓜子状活虫
 百态   2023-07-25
地球连续35年收到神秘规律性信号,网友:不要回答!
 探索   2023-07-21
全球镓价格本周大涨27%
 探索   2023-07-09
钱都流向了那些不缺钱的人,苦都留给了能吃苦的人
 探索   2023-07-02
倩女手游刀客魅者强控制(强混乱强眩晕强睡眠)和对应控制抗性的关系
 百态   2020-08-20
美国5月9日最新疫情:美国确诊人数突破131万
 百态   2020-05-09
荷兰政府宣布将集体辞职
 干货   2020-04-30
倩女幽魂手游师徒任务情义春秋猜成语答案逍遥观:鹏程万里
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案神机营:射石饮羽
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案昆仑山:拔刀相助
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案天工阁:鬼斧神工
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案丝路古道:单枪匹马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:与虎谋皮
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:李代桃僵
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:指鹿为马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:小鸟依人
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:千金买邻
 干货   2019-11-12
 
推荐阅读
 
 
 
>>返回首頁<<
 
靜靜地坐在廢墟上,四周的荒凉一望無際,忽然覺得,淒涼也很美
© 2005- 王朝網路 版權所有