diff options
author | Rainer Gerhards <rgerhards@adiscon.com> | 2007-07-17 10:09:19 +0000 |
---|---|---|
committer | Rainer Gerhards <rgerhards@adiscon.com> | 2007-07-17 10:09:19 +0000 |
commit | 6ce20a8c79fc3d3e7ed06b93f03308d78d7dbb4e (patch) | |
tree | 580548bddfed38a12897161ff30545ddf10ae44d | |
parent | 31e188f8e7db7c057f1edd29c72703a3ff00ef0b (diff) | |
download | rsyslog-6ce20a8c79fc3d3e7ed06b93f03308d78d7dbb4e.tar.gz rsyslog-6ce20a8c79fc3d3e7ed06b93f03308d78d7dbb4e.tar.xz rsyslog-6ce20a8c79fc3d3e7ed06b93f03308d78d7dbb4e.zip |
basic support for creating directories with dynaFiles added
-rwxr-xr-x | srUtils.c | 244 | ||||
-rwxr-xr-x | srUtils.h | 118 | ||||
-rw-r--r-- | syslogd.c | 15 |
3 files changed, 218 insertions, 159 deletions
@@ -1,103 +1,141 @@ -/**\file srUtils.c
- * \brief General utilties that fit nowhere else.
- *
- * The namespace for this file is "srUtil".
- *
- * \author Rainer Gerhards <rgerhards@adiscon.com>
- * \date 2003-09-09
- * Coding begun.
- *
- * Copyright 2003-2007 Rainer Gerhards and Adiscon GmbH.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- *
- * A copy of the GPL can be found in the file "COPYING" in this distribution.
- */
-#include "config.h"
-
-
-#include <stdlib.h>
-#include <string.h>
-#include "rsyslog.h" /* THIS IS A MODIFICATION FOR RSYSLOG! 2004-11-18 rgerards */
-#include "liblogging-stub.h" /* THIS IS A MODIFICATION FOR RSYSLOG! 2004-11-18 rgerards */
-#define TRUE 1
-#define FALSE 0
-#include "srUtils.h"
-#include "assert.h"
-
-
-/* ################################################################# *
- * private members *
- * ################################################################# */
-
-/* As this is not a "real" object, there won't be any private
- * members in this file.
- */
-
-/* ################################################################# *
- * public members *
- * ################################################################# */
-
-rsRetVal srUtilItoA(char *pBuf, int iLenBuf, int iToConv)
-{
- int i;
- int bIsNegative;
- char szBuf[32]; /* sufficiently large for my lifespan and those of my children... ;) */
-
- assert(pBuf != NULL);
- assert(iLenBuf > 1); /* This is actually an app error and as thus checked for... */
-
- if(iToConv < 0)
- {
- bIsNegative = TRUE;
- iToConv *= -1;
- }
- else
- bIsNegative = FALSE;
-
- /* first generate a string with the digits in the reverse direction */
- i = 0;
- do
- {
- szBuf[i] = iToConv % 10 + '0';
- iToConv /= 10;
- } while(iToConv > 0); /* warning: do...while()! */
-
- /* make sure we are within bounds... */
- if(i + 2 > iLenBuf) /* +2 because: a) i starts at zero! b) the \0 byte */
- return RS_RET_PROVIDED_BUFFER_TOO_SMALL;
-
- /* then move it to the right direction... */
- if(bIsNegative == TRUE)
- *pBuf++ = '-';
- while(i >= 0)
- *pBuf++ = szBuf[i--];
- *pBuf = '\0'; /* terminate it!!! */
-
- return RS_RET_OK;
-}
-
-unsigned char *srUtilStrDup(unsigned char *pOld, size_t len)
-{
- unsigned char *pNew;
-
- assert(pOld != NULL);
- assert(len >= 0);
-
- if((pNew = malloc(len + 1)) != NULL)
- memcpy(pNew, pOld, len + 1);
-
- return pNew;
-}
+/**\file srUtils.c + * \brief General utilties that fit nowhere else. + * + * The namespace for this file is "srUtil". + * + * \author Rainer Gerhards <rgerhards@adiscon.com> + * \date 2003-09-09 + * Coding begun. + * + * Copyright 2003-2007 Rainer Gerhards and Adiscon GmbH. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * A copy of the GPL can be found in the file "COPYING" in this distribution. + */ +#include "config.h" + + +#include <stdlib.h> +#include <string.h> +#include <unistd.h> +#include <errno.h> +#include "rsyslog.h" /* THIS IS A MODIFICATION FOR RSYSLOG! 2004-11-18 rgerards */ +#include "liblogging-stub.h" /* THIS IS A MODIFICATION FOR RSYSLOG! 2004-11-18 rgerards */ +#define TRUE 1 +#define FALSE 0 +#include "srUtils.h" +#include "assert.h" + + +/* ################################################################# * + * private members * + * ################################################################# */ + +/* As this is not a "real" object, there won't be any private + * members in this file. + */ + +/* ################################################################# * + * public members * + * ################################################################# */ + +rsRetVal srUtilItoA(char *pBuf, int iLenBuf, int iToConv) +{ + int i; + int bIsNegative; + char szBuf[32]; /* sufficiently large for my lifespan and those of my children... ;) */ + + assert(pBuf != NULL); + assert(iLenBuf > 1); /* This is actually an app error and as thus checked for... */ + + if(iToConv < 0) + { + bIsNegative = TRUE; + iToConv *= -1; + } + else + bIsNegative = FALSE; + + /* first generate a string with the digits in the reverse direction */ + i = 0; + do + { + szBuf[i] = iToConv % 10 + '0'; + iToConv /= 10; + } while(iToConv > 0); /* warning: do...while()! */ + + /* make sure we are within bounds... */ + if(i + 2 > iLenBuf) /* +2 because: a) i starts at zero! b) the \0 byte */ + return RS_RET_PROVIDED_BUFFER_TOO_SMALL; + + /* then move it to the right direction... */ + if(bIsNegative == TRUE) + *pBuf++ = '-'; + while(i >= 0) + *pBuf++ = szBuf[i--]; + *pBuf = '\0'; /* terminate it!!! */ + + return RS_RET_OK; +} + +uchar *srUtilStrDup(uchar *pOld, size_t len) +{ + uchar *pNew; + + assert(pOld != NULL); + assert(len >= 0); + + if((pNew = malloc(len + 1)) != NULL) + memcpy(pNew, pOld, len + 1); + + return pNew; +} + + +/* creates a path recursively + * Return 0 on success, -1 otherwise. On failure, errno + * hold the last OS error. + * Param "mode" holds the mode that all non-existing directories + * are to be created with. + */ +int makeFileParentDirs(uchar *szFile, size_t lenFile, mode_t mode) +{ + uchar *p; + uchar *pszWork; + size_t len; + + assert(szFile != NULL); + assert(len > 0); + + len = strlen(szFile) + 1; /* add one for '\0'-byte */ + if((pszWork = malloc(sizeof(uchar) * len)) == NULL) + return -1; + memcpy(pszWork, szFile, len); + for(p = pszWork+1 ; *p ; p++) + if(*p == '/') { + /* temporarily terminate string, create dir and go on */ + *p = '\0'; + if(access(pszWork, F_OK)) + if(mkdir(pszWork, mode) != 0) { + int eSave = errno; + free(pszWork); + errno = eSave; + return -1; + } + *p = '/'; + } + free(pszWork); +} @@ -1,55 +1,63 @@ -/*! \file srUtils.h
- * \brief General, small utilities that fit nowhere else.
- *
- * \author Rainer Gerhards <rgerhards@adiscon.com>
- * \date 2003-09-09
- * Coding begun.
- *
- * Copyright 2003-2007 Rainer Gerhards and Adiscon GmbH.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- *
- * A copy of the GPL can be found in the file "COPYING" in this distribution.
- */
-#ifndef __SRUTILS_H_INCLUDED__
-#define __SRUTILS_H_INCLUDED__ 1
-
-/**
- * A reimplementation of itoa(), as this is not available
- * on all platforms. We used the chance to make an interface
- * that fits us well, so it is no longer plain itoa().
- *
- * This method works with the US-ASCII alphabet. If you port this
- * to e.g. EBCDIC, you need to make a small adjustment. Keep in mind,
- * that on the wire it MUST be US-ASCII, so basically all you need
- * to do is replace the constant '0' with 0x30 ;).
- *
- * \param pBuf Caller-provided buffer that will receive the
- * generated ASCII string.
- *
- * \param iLenBuf Length of the caller-provided buffer.
- *
- * \param iToConv The integer to be converted.
- */
-rsRetVal srUtilItoA(char *pBuf, int iLenBuf, int iToConv);
-
-/**
- * A method to duplicate a string for which the length is known.
- * Len must be the length in characters WITHOUT the trailing
- * '\0' byte.
- * rgerhards, 2007-07-10
- */
-unsigned char *srUtilStrDup(unsigned char *pOld, size_t len);
-#endif
+/*! \file srUtils.h + * \brief General, small utilities that fit nowhere else. + * + * \author Rainer Gerhards <rgerhards@adiscon.com> + * \date 2003-09-09 + * Coding begun. + * + * Copyright 2003-2007 Rainer Gerhards and Adiscon GmbH. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * A copy of the GPL can be found in the file "COPYING" in this distribution. + */ +#ifndef __SRUTILS_H_INCLUDED__ +#define __SRUTILS_H_INCLUDED__ 1 + +/** + * A reimplementation of itoa(), as this is not available + * on all platforms. We used the chance to make an interface + * that fits us well, so it is no longer plain itoa(). + * + * This method works with the US-ASCII alphabet. If you port this + * to e.g. EBCDIC, you need to make a small adjustment. Keep in mind, + * that on the wire it MUST be US-ASCII, so basically all you need + * to do is replace the constant '0' with 0x30 ;). + * + * \param pBuf Caller-provided buffer that will receive the + * generated ASCII string. + * + * \param iLenBuf Length of the caller-provided buffer. + * + * \param iToConv The integer to be converted. + */ +rsRetVal srUtilItoA(char *pBuf, int iLenBuf, int iToConv); + +/** + * A method to duplicate a string for which the length is known. + * Len must be the length in characters WITHOUT the trailing + * '\0' byte. + * rgerhards, 2007-07-10 + */ +unsigned char *srUtilStrDup(unsigned char *pOld, size_t len); +/** + * A method to create a directory and all its missing parents for + * a given file name. Please not that the rightmost element is + * considered to be a file name and thus NO directory is being created + * for it. + * added 2007-07-17 by rgerhards + */ +int makeFileParentDirs(uchar *szFile, size_t lenFile, mode_t mode); +#endif @@ -6229,10 +6229,23 @@ static int prepareDynFile(selector_t *f) /* Ok, we finally can open the file */ f->f_file = open((char*) newFileName, O_WRONLY|O_APPEND|O_CREAT|O_NOCTTY, f->f_un.f_file.fCreateMode); + + if(f->f_file == -1) { + /* on first failure, we try to create parent directories and then + * retry the open. Only if that fails, we give up. We do not report + * any errors here ourselfs but let the code fall through to error + * handler below. + */ + if(makeFileParentDirs(newFileName, strlen(newFileName), + f->f_un.f_file.fCreateMode) == 0) { + f->f_file = open((char*) newFileName, O_WRONLY|O_APPEND|O_CREAT|O_NOCTTY, + f->f_un.f_file.fCreateMode); + } + } if(f->f_file == -1) { /* do not report anything if the message is an internally-generated * message. Otherwise, we could run into a never-ending loop. The bad - * news is that we also loose errors on startup messages, but so it is. + * news is that we also lose errors on startup messages, but so it is. */ if(f->f_pMsg->msgFlags & INTERNAL_MSG) dprintf("Could not open dynaFile, discarding message\n"); |