[Dibbler-devel] Reimplementation of linux lowlevel configuration option removal functions

petr.pisar at atlas.cz petr.pisar at atlas.cz
Wed Jul 2 16:04:57 CEST 2008


On Tue, Jul 01, 2008 at 10:42:55PM +0200, petr.pisar at atlas.cz wrote:

> Index: Port-linux/lowlevel-options-linux.c
> ===================================================================
> > 			    if (head=='\0' || *head==comment ||
                       ^^^
                       Missing dereference

I found a mistake. Attached is new patch.

-- Petr
-------------- next part --------------
Index: Port-linux/lowlevel-options-linux.c
===================================================================
RCS file: /var/cvs/dibbler/Port-linux/lowlevel-options-linux.c,v
retrieving revision 1.14
diff -r1.14 lowlevel-options-linux.c
15a16,17
> #include <ctype.h>
> #include <errno.h>
20a23,24
> #define MAX_LINE_LEN 511
> 
26a31,146
> /* Remove value of keyword from opened file in and the result is printed into
>  * opened file out. If removed_empty and keyword remains without argument, it
>  * will be removed too. Comments (starting with comment char) are respected.
>  * All values following keyword are removed on all lines (global remove).
>  * Returns LOWLEVEL_NO_ERROR by default, LOWLEVEL_ERROR_FILE on I/O error (and
>  * errno is set up), LOWLEVEL_ERROR_UNSPEC if value or keyword is too long.
>  * */
> int cfg_value_del(FILE *in, FILE *out, const char *keyword, const char *value,
> 	const char comment, int remove_empty) {
>     char buf[MAX_LINE_LEN+1];
> 
>     if (strlen(keyword) > MAX_LINE_LEN || strlen(value) > MAX_LINE_LEN)
> 	return(LOWLEVEL_ERROR_UNSPEC);
> 
>     errno = 0;
>     while (fgets(buf, MAX_LINE_LEN, in)) {
> 
> 	char *head;
> 	/* Skip leading white space */
> 	for (head=buf; *head!='\0' && isspace((int)(*head)); head++);
> 	/* Skip comment */
> 	if (*head!='\0' && *head!=comment) {
> 	    /* Find keyword */
> 	    if (strstr(head, keyword)==head) {
> 		head += strlen(keyword);
> 
> 		/* Skip alone keyword */
> 		if (*head!='\0' && *head!=comment && isspace((int)(*head))) {
> 		    char *keyword_end=head;
> 
> 		    /* Locate each argument */
> 		    while (*head!='\0' && *head!=comment) {
> 		    char *argument_begin=head;
> 		    /* Skip spaces before argument */
> 		    for (; *head!='\0' && isspace((int)(*head)); head++);
> 		    if (*head!='\0' && *head!=comment) {
> 			/* Compare argument to value */
> 			if (strstr(head, value)==head) {
> 			    head += strlen(value);
> 			    if (*head=='\0' || *head==comment ||
> 				    isspace((int)(*head))) {
> 				/* remove this argument */
> 				/* sprinf() moves data and appends '\0' */
> 				sprintf(argument_begin, "%s", head);
> 				head=argument_begin;
> 			    }
> 			}
> 			/* Skip rest of the argument */
> 			for (; *head!='\0' && !isspace((int)(*head)); head++);
> 		    }
> 		}
> 
> 		/* Remove whole line if keyword remains without any arguments.*/
> 		if (remove_empty) {
> 		    for (head=keyword_end; *head!='\0' && isspace((int)(*head));
> 			    head++);
> 		    if (*head=='\0' || *head==comment) *buf='\0';
> 		    }
> 		}
> 	    }
> 	}
> 
> 	/* print output */
> 	if (-1 == fprintf(out, "%s", buf)) return(LOWLEVEL_ERROR_FILE);
>     }
> 
>     return((errno)?LOWLEVEL_ERROR_FILE:LOWLEVEL_NO_ERROR);
> }
> 
> 
> /* Removes value of keyword from file.
>  * It tries to do its best not to corrupt the file.
>  * Returns LOWLEVEL ERROR codes */
> int cfg_file_del(const char *file, const char *keyword, const char *value) {
>     FILE *fold, *ftmp;
>     int tmpfd;
>     int error=LOWLEVEL_NO_ERROR;
>     struct stat st;
>     char template[]="/etc/dibbler.XXXXXX";
> 
>     /* Create temporary FILE */
>     if (-1 == (tmpfd=mkstemp(template)))
> 	return(LOWLEVEL_ERROR_FILE);
> 
>     if (NULL == (ftmp=fdopen(tmpfd, "w"))) {
> 	unlink(template);
> 	close(tmpfd);
> 	return(LOWLEVEL_ERROR_FILE);
>     }
> 
>     /* Open original file */
>     if (!(fold = fopen(file, "r"))) {
> 	unlink(template);
> 	fclose(ftmp);
> 	return(LOWLEVEL_ERROR_FILE);
>     }
> 
>     /* modify configuration */
>     error = cfg_value_del(fold, ftmp, keyword, value, '#', 1);
> 
>     /* close the files */
>     if (EOF==fclose(fold)) error=LOWLEVEL_ERROR_FILE;
>     if (EOF==fclose(ftmp)) error=LOWLEVEL_ERROR_FILE;
> 
>     /* move temp file into place of the old one */
>     if (error==LOWLEVEL_NO_ERROR) {
> 	memset(&st,0,sizeof(st));
> 	if (stat(file, &st) || rename(template, file) ||
> 		chmod(file, st.st_mode))
> 	    error=LOWLEVEL_ERROR_FILE;
>     }
> 
>     return(error);
> }
> 
> 
52,74c172
<     FILE * f, *f2;
<     char buf[512];
<     int found=0;
<     struct stat st;
<     memset(&st,0,sizeof(st));
<     stat(RESOLVCONF_FILE, &st);
< 
<     unlink(RESOLVCONF_FILE".old");
<     rename(RESOLVCONF_FILE,RESOLVCONF_FILE".old");
<     f = fopen(RESOLVCONF_FILE".old","r");
<     f2 = fopen(RESOLVCONF_FILE,"w"); 
<     while (fgets(buf,511,f)) {
< 	if ( (!found) && (strstr(buf, addrPlain)) ) {
< 	    found = 1;
< 	    continue;
< 	}
< 	fprintf(f2,"%s",buf);
<     }
<     fclose(f);
<     fclose(f2);
< 
<     chmod(RESOLVCONF_FILE, st.st_mode);
<     return LOWLEVEL_NO_ERROR;
---
>     return cfg_file_del(RESOLVCONF_FILE, "nameserver", addrPlain);
122,152c220
<     FILE * f, *f2;
<     char buf[512], searchbuf[512], *ptr;
<     int found=0;
<     struct stat st;
<     memset(&st,0,sizeof(st));
<     stat(RESOLVCONF_FILE, &st);
< 
<     if (strlen(domain) >= sizeof(searchbuf)-1 )
< 	return LOWLEVEL_ERROR_UNSPEC;
<     searchbuf[0] = ' ';
<     strcpy(&(searchbuf[1]), domain);
<     unlink(RESOLVCONF_FILE".old");
<     rename(RESOLVCONF_FILE,RESOLVCONF_FILE".old");
<     if ( !(f = fopen(RESOLVCONF_FILE".old","r")) )
< 	return LOWLEVEL_ERROR_FILE;
<     if ( !(f2= fopen(RESOLVCONF_FILE,"w+")))
< 	return LOWLEVEL_ERROR_FILE;
<     while (fgets(buf,511,f)) {
< 	if ( (!found) && (ptr=strstr(buf, searchbuf)) ) {
< 	    found = 1;
< 	    strcpy(ptr, ptr+strlen(searchbuf));
< 	    if (strlen(buf)<11) /* 11=minimum length (one letter domain in 2letter top domain, e.g. "search x.pl") */
< 		continue;
< 	}
< 	fprintf(f2,"%s",buf);
<     }
<     fclose(f);
<     fclose(f2);
< 
<     chmod(RESOLVCONF_FILE,st.st_mode);
<     return LOWLEVEL_NO_ERROR;
---
>     return cfg_file_del(RESOLVCONF_FILE, "search", domain);
175,197c243
<     FILE * f, *f2;
<     char buf[512];
<     int found=0;
<     struct stat st;
<     memset(&st,0,sizeof(st));
<     stat(NTPCONF_FILE, &st);
< 
<     unlink(NTPCONF_FILE".old");
<     rename(NTPCONF_FILE, NTPCONF_FILE".old");
<     f = fopen(NTPCONF_FILE".old","r");
<     f2 = fopen(NTPCONF_FILE,"w"); 
<     while (fgets(buf,511,f)) {
< 	if ( (!found) && (strstr(buf, addrPlain)) ) {
< 	    found = 1;
< 	    continue;
< 	}
< 	fprintf(f2,"%s",buf);
<     }
<     fclose(f);
<     fclose(f2);
< 
<     chmod(NTPCONF_FILE, st.st_mode);
<     return LOWLEVEL_NO_ERROR;
---
>     return cfg_file_del(NTPCONF_FILE, "server", addrPlain);
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 189 bytes
Desc: not available
Url : http://klub.com.pl/pipermail/dibbler-devel/attachments/20080702/45508524/attachment.pgp 


More information about the Dibbler-devel mailing list