• Main Page
  • Data Structures
  • Files
  • File List
  • Globals

/build/buildd-opendnssec_1.3.2-1~bpo60+1-mips-pXL6jA/opendnssec-1.3.2/signer/src/shared/file.c

Go to the documentation of this file.
00001 /*
00002  * $Id: file.c 5558 2011-09-06 13:19:19Z rb $
00003  *
00004  * Copyright (c) 2009 NLNet Labs. All rights reserved.
00005  *
00006  * Redistribution and use in source and binary forms, with or without
00007  * modification, are permitted provided that the following conditions
00008  * are met:
00009  * 1. Redistributions of source code must retain the above copyright
00010  *    notice, this list of conditions and the following disclaimer.
00011  * 2. Redistributions in binary form must reproduce the above copyright
00012  *    notice, this list of conditions and the following disclaimer in the
00013  *    documentation and/or other materials provided with the distribution.
00014  *
00015  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
00016  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
00017  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
00018  * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
00019  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
00020  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
00021  * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
00022  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
00023  * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
00024  * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
00025  * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00026  *
00027  */
00028 
00034 #include "config.h"
00035 #include "shared/file.h"
00036 #include "shared/log.h"
00037 
00038 #include <errno.h>
00039 #include <fcntl.h>
00040 #include <stdio.h>
00041 #include <stdlib.h>
00042 #include <string.h>
00043 #include <sys/stat.h>
00044 #include <sys/types.h>
00045 #include <unistd.h>
00046 
00047 #define BUFFER_SIZE (16 * 1024) /* use 16K buffers */
00048 
00049 static const char* file_str = "file";
00050 
00051 
00056 const char*
00057 ods_file_mode2str(const char* mode)
00058 {
00059     if (!mode) {
00060         return "no mode";
00061     }
00062 
00063     if (ods_strcmp(mode, "a") == 0) {
00064         return "appending";
00065     } else if (ods_strcmp(mode, "r") == 0) {
00066         return "reading";
00067     } else if (ods_strcmp(mode, "w") == 0) {
00068         return "writing";
00069         }
00070     return "unknown mode";
00071 }
00072 
00073 
00078 int
00079 ods_fgetc(FILE* fd, unsigned int* line_nr)
00080 {
00081     int c;
00082 
00083     ods_log_assert(fd);
00084     ods_log_assert(line_nr);
00085 
00086     c = fgetc(fd);
00087         if (c == '\n') {
00088         (*line_nr)++;
00089     }
00090     return c;
00091 }
00092 
00093 
00098 int
00099 ods_skip_whitespace(FILE* fd, unsigned int* line_nr)
00100 {
00101     int c;
00102 
00103     ods_log_assert(fd);
00104     ods_log_assert(line_nr);
00105 
00106     while ((c=ods_fgetc(fd, line_nr)) != EOF) {
00107         if (c == ' ' || c == '\t' || c == '\r') {
00108             continue;
00109         }
00110         return c;
00111     }
00112     return EOF;
00113 }
00114 
00115 
00120 char*
00121 ods_build_path(const char* file, const char* suffix, int dir)
00122 {
00123     size_t len_file = 0;
00124     size_t len_suffix = 0;
00125     size_t len_total = 0;
00126     char* openf = NULL;
00127 
00128     if (file) {
00129         len_file = strlen(file);
00130         if (suffix) {
00131             len_suffix = strlen(suffix);
00132         }
00133         len_total = len_suffix + len_file;
00134         if (dir) {
00135             len_total++;
00136         }
00137 
00138         if (len_total > 0) {
00139             openf = (char*) malloc(sizeof(char)*(len_total + 1));
00140             if (!openf) {
00141                 ods_log_crit("[%s] build path failed: malloc failed", file_str);
00142                 return NULL;
00143             }
00144 
00145             strncpy(openf, file, len_file);
00146             openf[len_file] = '\0';
00147             if (suffix) {
00148                 strncat(openf, suffix, len_suffix);
00149             }
00150             if (dir) {
00151                 strncat(openf, "/", 1);
00152             }
00153             openf[len_total] = '\0';
00154         }
00155     }
00156 
00157     return openf;
00158 }
00159 
00160 
00165 FILE*
00166 ods_fopen(const char* file, const char* dir, const char* mode)
00167 {
00168     FILE* fd = NULL;
00169     size_t len_file = 0;
00170     size_t len_dir = 0;
00171     size_t len_total = 0;
00172     char* openf = NULL;
00173 
00174     ods_log_assert(mode);
00175     ods_log_debug("[%s] open file %s%s file=%s mode=%s", file_str,
00176         (dir?"dir=":""), (dir?dir:""), (file?file:"(null)"),
00177         ods_file_mode2str(mode));
00178 
00179     if (dir) {
00180         len_dir= strlen(dir);
00181     }
00182     if (file) {
00183         len_file= strlen(file);
00184     }
00185     len_total = len_dir + len_file;
00186     if (len_total > 0) {
00187         openf = (char*) malloc(sizeof(char)*(len_total + 1));
00188         if (!openf) {
00189             return NULL;
00190         }
00191         if (dir) {
00192            strncpy(openf, dir, len_dir);
00193            openf[len_dir] = '\0';
00194            if (file) {
00195                strncat(openf, file, len_file);
00196            }
00197         } else if (file) {
00198            strncpy(openf, file, len_file);
00199         }
00200         openf[len_total] = '\0';
00201 
00202         if (len_file) {
00203             fd = fopen(openf, mode);
00204             if (!fd) {
00205                 ods_log_verbose("[%s] unable to open file %s for %s: %s",
00206                     file_str, openf?openf:"(null)",
00207                     ods_file_mode2str(mode), strerror(errno));
00208             }
00209         }
00210         free((void*) openf);
00211     }
00212     return fd;
00213 }
00214 
00219 void
00220 ods_fclose(FILE* fd)
00221 {
00222     if (fd) {
00223         fclose(fd);
00224     }
00225     return;
00226 }
00227 
00228 
00233 ssize_t
00234 ods_writen(int fd, const void* vptr, size_t n)
00235 {
00236     size_t nleft;
00237     ssize_t nwritten;
00238     const char* ptr;
00239 
00240     ptr = vptr;
00241     nleft = n;
00242     while (nleft > 0) {
00243         if ((nwritten = write(fd, ptr, nleft)) <= 0) {
00244             if (nwritten < 0 && errno == EINTR) {
00245                 nwritten = 0; /* and call write again */
00246             } else {
00247                 return -1; /* error */
00248             }
00249         }
00250         nleft -= nwritten;
00251         ptr += nwritten;
00252     }
00253     return n;
00254 }
00255 
00256 
00261 time_t
00262 ods_file_lastmodified(const char* file)
00263 {
00264     int ret;
00265     struct stat buf;
00266     FILE* fd;
00267 
00268     ods_log_assert(file);
00269 
00270     if ((fd = ods_fopen(file, NULL, "r")) != NULL) {
00271         ret = stat(file, &buf);
00272         ods_fclose(fd);
00273         return buf.st_mtime;
00274     }
00275     return 0;
00276 }
00277 
00278 
00283 int
00284 ods_strcmp(const char* s1, const char* s2)
00285 {
00286     if (!s1 && !s2) {
00287         return 0;
00288     } else if (!s1) {
00289         return -1;
00290     } else if (!s2) {
00291         return -1;
00292     } else if (strlen(s1) != strlen(s2)) {
00293         if (strncmp(s1, s2, strlen(s1)) == 0) {
00294             return strlen(s1) - strlen(s2);
00295         }
00296     }
00297     return strncmp(s1, s2, strlen(s1));
00298 }
00299 
00300 
00305 const char*
00306 ods_replace(const char *str, const char *oldstr, const char *newstr)
00307 {
00308     char* buffer = NULL;
00309     char* ch = NULL;
00310     size_t part1_len = 0;
00311     size_t part2_len = 0;
00312     size_t part3_len = 0;
00313 
00314     if (!str) {
00315        return NULL;
00316     }
00317     if (!oldstr || !newstr) {
00318        return str;
00319     }
00320 
00321     if (!(ch = strstr(str, oldstr))) {
00322         buffer = strdup(str);
00323         return buffer;
00324     }
00325 
00326     part1_len = ch-str;
00327     part2_len = strlen(newstr);
00328     part3_len = strlen(ch+strlen(oldstr));
00329     buffer = calloc(part1_len+part2_len+part3_len+1, sizeof(char));
00330     if (!buffer) {
00331         return NULL;
00332     }
00333 
00334     if (part1_len) {
00335         strncpy(buffer, str, part1_len);
00336         buffer[part1_len] = '\0';
00337 
00338         if (part2_len) {
00339             strncat(buffer, str, part2_len);
00340             buffer[part1_len+part2_len] = '\0';
00341         }
00342     } else {
00343         strncpy(buffer, newstr, part2_len);
00344         buffer[part2_len] = '\0';
00345     }
00346 
00347     if (part3_len) {
00348         strncat(buffer, ch+strlen(oldstr), part3_len);
00349         buffer[part1_len+part2_len+part3_len] = '\0';
00350     }
00351 
00352     buffer[ch-str] = '\0';
00353     snprintf(buffer+(ch-str), SYSTEM_MAXLEN, "%s%s", newstr, ch+strlen(oldstr));
00354     return buffer;
00355 }
00356 
00357 
00362 ods_status
00363 ods_file_copy(const char* file1, const char* file2)
00364 {
00365     char buf[BUFFER_SIZE];
00366     int fin = 0;
00367     int fout = 0;
00368     int read_size = 0;
00369     if (!file1 || !file2) {
00370         return ODS_STATUS_ASSERT_ERR;
00371     }
00372     if ((fin = open(file1, O_RDONLY|O_NONBLOCK)) < 0) {
00373         return ODS_STATUS_FOPEN_ERR;
00374     }
00375     if ((fout = open(file2, O_WRONLY|O_TRUNC|O_CREAT, 0666)) < 0) {
00376         close(fin);
00377         return ODS_STATUS_FOPEN_ERR;
00378     }
00379     while (1) {
00380         read_size = read(fin, buf, sizeof(buf));
00381         if (read_size == 0) {
00382             break;
00383         }
00384         if (read_size < 0) {
00385             close(fin);
00386             close(fout);
00387             return ODS_STATUS_FREAD_ERR;
00388         }
00389         if (write(fout, buf, (unsigned int) read_size) < 0) {
00390             close(fin);
00391             close(fout);
00392             return ODS_STATUS_FWRITE_ERR;
00393         }
00394     }
00395     close(fin);
00396     close(fout);
00397     return ODS_STATUS_OK;
00398 }
00399 
00400 
00405 char*
00406 ods_dir_name(const char* file) {
00407     int l = strlen(file);
00408     char* dir = NULL;
00409 
00410     ods_log_assert(file);
00411 
00412     /* find seperator */
00413     while (l>0 && strncmp(file + (l-1), "/", 1) != 0) {
00414         l--;
00415     }
00416 
00417     /* now strip off (multiple seperators) */
00418     while (l>0 && strncmp(file + (l-1), "/", 1) == 0) {
00419         l--;
00420     }
00421 
00422     if (l) {
00423         dir = (char*) calloc(l+1, sizeof(char));
00424         if (dir) {
00425             dir = strncpy(dir, file, l);
00426         }
00427         return dir;
00428     }
00429     return NULL;
00430 }
00431 
00436 void
00437 ods_chown(const char* file, uid_t uid, gid_t gid, int getdir)
00438 {
00439     char* dir = NULL;
00440 
00441     if (!file) {
00442         ods_log_warning("[%s] no filename given for chown()", file_str);
00443         return;
00444     }
00445 
00446     if (!getdir) {
00447         ods_log_debug("[%s] create and chown %s with user=%ld group=%ld",
00448            file_str, file, (signed long) uid, (signed long) gid);
00449         if (chown(file, uid, gid) != 0) {
00450             ods_log_error("[%s] chown() %s failed: %s", file_str, file,
00451                 strerror(errno));
00452         }
00453     } else if ((dir = ods_dir_name(file)) != NULL) {
00454         ods_log_debug("[%s] create and chown %s with user=%ld group=%ld",
00455             file_str, dir, (signed long) uid, (signed long) gid);
00456         if (chown(dir, uid, gid) != 0) {
00457             ods_log_error("[%s] chown() %s failed: %s", file_str,
00458                 dir, strerror(errno));
00459         }
00460         free((void*) dir);
00461     } else {
00462         ods_log_warning("[%s] use of relative path: %s", file_str, file);
00463     }
00464     return;
00465 }
00466 
00467 
00472 void
00473 ods_str_trim(char* str)
00474 {
00475     int i = strlen(str), nl = 0;
00476 
00477     /* trailing */
00478     while (i>0) {
00479         --i;
00480         if (str[i] == '\n') {
00481             nl = 1;
00482         }
00483         if (str[i] == ' ' || str[i] == '\t' || str[i] == '\n') {
00484             str[i] = '\0';
00485         } else {
00486             break;
00487         }
00488     }
00489     if (nl) {
00490         str[++i] = '\n';
00491     }
00492 
00493     /* leading */
00494     i = 0;
00495     while (str[i] == ' ' || str[i] == '\t') {
00496         i++;
00497     }
00498     while (*(str+i) != '\0') {
00499         *str = *(str+i);
00500         str++;
00501     }
00502     *str = '\0';
00503     return;
00504 }

Generated on Sat Dec 17 2011 10:26:02 for OpenDNSSEC-signer by  doxygen 1.7.1