Back to index

avfs  1.0.1
sysdeps.c
Go to the documentation of this file.
00001 /*
00002     AVFS: A Virtual File System Library
00003     Copyright (C) 1998-1999  Miklos Szeredi <miklos@szeredi.hu>
00004 
00005     This program can be distributed under the terms of the GNU GPL.
00006     See the file COPYING.
00007 */
00008 
00009 #include "internal.h"
00010 
00011 #include "config.h"
00012 #include "info.h"
00013 
00014 #include <stdio.h>
00015 #include <stdlib.h>
00016 #include <stdarg.h>
00017 #include <string.h>
00018 #include <unistd.h>
00019 #include <fcntl.h>
00020 #include <syslog.h>
00021 
00022 #include <sys/types.h>
00023 #include <sys/stat.h>
00024 #include <sys/time.h>
00025 
00026 #ifdef MAJOR_IN_MKDEV
00027 #include <sys/mkdev.h>
00028 #endif
00029 
00030 #ifdef MAJOR_IN_SYSMACROS
00031 #include <sys/sysmacros.h>
00032 #endif
00033 
00034 #define DEFAULT_LOGMASK (AVLOG_ERROR | AVLOG_WARNING)
00035 
00036 static int loginited;
00037 static int logmask;
00038 static char *logfile;
00039 static int logfd;
00040 static AV_LOCK_DECL(loglock);
00041 
00042 static int debug_get(struct entry *ent, const char *param, char **retp)
00043 {
00044     char buf[32];
00045     
00046     AV_LOCK(loglock);
00047     sprintf(buf, "%02o\n", logmask);
00048     AV_UNLOCK(loglock);
00049 
00050     *retp = av_strdup(buf);
00051     return 0;
00052 }
00053 
00054 static int debug_set(struct entry *ent, const char *param, const char *val)
00055 {
00056     int mask;
00057 
00058     if(val[0] < '0' || val[0] > '7' || val[1] < '0' || val[1] > '7' ||
00059        (val[2] != '\0' && !isspace((int) val[2]))) 
00060         return -EIO;
00061 
00062     mask = (val[0] - '0') * 8 + (val[1] - '0');
00063     
00064     AV_LOCK(loglock);
00065     logmask = mask;
00066     AV_UNLOCK(loglock);
00067 
00068     return 0;
00069 }
00070 
00071 static void log_open()
00072 {
00073     if(logfile != NULL) {
00074         if(strcmp(logfile, "-") == 0)
00075             logfd = STDERR_FILENO;
00076         else
00077             logfd = open(logfile, O_WRONLY | O_APPEND | O_CREAT, 0600);
00078     } else {
00079         openlog("avfs", LOG_CONS | LOG_PID, LOG_USER);
00080     }
00081 }
00082 
00083 static void log_close()
00084 {
00085     if(logfile != NULL) {
00086         if(strcmp(logfile, "-") != 0 && logfd != -1)
00087             close(logfd);
00088     } else {
00089         closelog();
00090     }
00091 }
00092 
00093 static void log_init()
00094 {
00095     char *logenv;
00096 
00097     logmask = DEFAULT_LOGMASK;
00098     logenv = getenv("AVFS_DEBUG");
00099     if(logenv != NULL &&
00100        logenv[0] >= '0' && logenv[0] <= '7' &&
00101        logenv[1] >= '0' && logenv[1] <= '7' &&
00102        logenv[2] == '\0')
00103         logmask = (logenv[0] - '0') * 8 + (logenv[1] - '0');
00104 
00105     logfile = getenv("AVFS_LOGFILE");
00106     log_open();
00107     loginited = 1;
00108 }
00109 
00110 static int logfile_get(struct entry *ent, const char *param, char **retp)
00111 {
00112     char *s;
00113 
00114     AV_LOCK(loglock);
00115     if(logfile != NULL)
00116         s = av_stradd(NULL, logfile, "\n", NULL);
00117     else
00118         s = av_strdup("");
00119     AV_UNLOCK(loglock);
00120 
00121     *retp = s;
00122 
00123     return 0;
00124 }
00125 
00126 static int logfile_set(struct entry *ent, const char *param, const char *val)
00127 {
00128     char *s;
00129     unsigned int len;
00130 
00131     s = av_strdup(val);
00132     len = strlen(s);
00133     if(len > 0 && s[len-1] == '\n')
00134         s[len-1] = '\0';
00135 
00136     if(s[0] == '\0') {
00137         av_free(s);
00138         s = NULL;
00139     }
00140 
00141     AV_LOCK(loglock);
00142     log_close();
00143     av_free(logfile);
00144     logfile = s;
00145     log_open();
00146     AV_UNLOCK(loglock);
00147 
00148     return 0;
00149 }
00150 
00151 #define LOGMSG_SIZE 1024
00152 static void filelog(const char *msg)
00153 {
00154     char buf[LOGMSG_SIZE + 128];
00155 
00156     if(logfd != -1) {
00157         struct avtm tmbuf;
00158 
00159         av_localtime(time(NULL), &tmbuf);
00160         sprintf(buf, "%02i/%02i %02i:%02i:%02i avfs[%lu]: %s\n", 
00161                 tmbuf.mon + 1, tmbuf.day, tmbuf.hour, tmbuf.min, tmbuf.sec,
00162                 (unsigned long) getpid(), msg);
00163         
00164         write(logfd, buf, strlen(buf));
00165     }
00166 }
00167 
00168 void av_init_logstat()
00169 {
00170     struct statefile statf;
00171 
00172     if(!loginited)
00173         log_init();
00174 
00175     statf.data = NULL;
00176     statf.get = debug_get;
00177     statf.set = debug_set;
00178 
00179     av_avfsstat_register("debug", &statf);
00180 
00181     statf.get = logfile_get;
00182     statf.set = logfile_set;
00183 
00184     av_avfsstat_register("logfile", &statf);
00185 }
00186 
00187 void av_log(int type, const char *format, ...)
00188 {
00189     va_list ap;
00190     char buf[LOGMSG_SIZE+1];
00191 
00192     AV_LOCK(loglock);
00193 
00194     if(!loginited)
00195         log_init();
00196 
00197     if((type & logmask) == 0) {
00198         AV_UNLOCK(loglock);
00199         return;
00200     }
00201 
00202     va_start(ap, format);
00203 #ifdef HAVE_VSNPRINTF
00204     vsnprintf(buf, LOGMSG_SIZE, format, ap);
00205 #else
00206     strncpy(buf, format, LOGMSG_SIZE);
00207 #endif  
00208     buf[LOGMSG_SIZE] = '\0';
00209     va_end(ap);
00210 
00211     if(logfile == NULL)
00212         syslog(LOG_INFO, "%s", buf);
00213     else
00214         filelog(buf);
00215     AV_UNLOCK(loglock);
00216 }
00217 
00218 avdev_t av_mkdev(int major, int minor)
00219 {
00220     return makedev(major, minor);
00221 }
00222 
00223 void av_splitdev(avdev_t dev, int *majorp, int *minorp)
00224 {
00225     *majorp = major(dev);
00226     *minorp = minor(dev);
00227 }
00228 
00229 
00230 char *av_get_config(const char *param)
00231 {
00232     const char *val;
00233 
00234     val = NULL;
00235 
00236     if(strcmp(param, "moduledir") == 0) 
00237         val = MODULE_DIR;
00238     else if(strcmp(param, "compiledate") == 0) 
00239         val = COMPILE_DATE;
00240     else if(strcmp(param, "compilesystem") == 0) 
00241         val = COMPILE_SYSTEM;
00242   
00243     if(val == NULL)
00244         return NULL;
00245 
00246     return av_strdup(val);
00247 }
00248 
00249 void av_default_stat(struct avstat *stbuf)
00250 {
00251     static avuid_t myuid = -1;
00252     static avuid_t mygid = -1;
00253 
00254     if(myuid == -1) {
00255         myuid = getuid();
00256         mygid = getgid();
00257     }
00258 
00259     stbuf->dev = 0;
00260     stbuf->ino = 0;
00261     stbuf->mode = 0;
00262     stbuf->nlink = 0;
00263     stbuf->uid = myuid;
00264     stbuf->gid = mygid;
00265     stbuf->rdev = 0;
00266     stbuf->size = 0;
00267     stbuf->blksize = 512;
00268     stbuf->blocks = 0;
00269     av_curr_time(&stbuf->atime);
00270     stbuf->mtime = stbuf->atime;
00271     stbuf->ctime = stbuf->atime;
00272 }
00273 
00274 void av_curr_time(avtimestruc_t *tim)
00275 {
00276     struct timeval tv;
00277 
00278     gettimeofday(&tv, NULL);
00279 
00280     tim->sec = tv.tv_sec;
00281     tim->nsec = tv.tv_usec * 1000;
00282 }
00283 
00284 avtime_t av_time()
00285 {
00286     return time(NULL);
00287 }
00288 
00289 void av_sleep(unsigned long msec)
00290 {
00291     struct timespec rem;
00292     int res;
00293 
00294     rem.tv_sec = msec / 1000;
00295     rem.tv_nsec = (msec % 1000) * 1000 * 1000;
00296 
00297     do {
00298         struct timespec req;
00299 
00300         req = rem;
00301         res = nanosleep(&req, &rem);
00302     } while(res == -1 && errno == EINTR);
00303 }
00304 
00305 
00306 avtime_t av_mktime(struct avtm *tp)
00307 {
00308     struct tm tms;
00309   
00310     tms.tm_sec  = tp->sec;
00311     tms.tm_min  = tp->min;
00312     tms.tm_hour = tp->hour;
00313     tms.tm_mday = tp->day;
00314     tms.tm_mon  = tp->mon;
00315     tms.tm_year = tp->year;
00316     tms.tm_isdst = -1;
00317 
00318     return mktime(&tms);
00319 }
00320 
00321 void av_localtime(avtime_t t, struct avtm *tp)
00322 {
00323     struct tm tms;
00324   
00325     localtime_r(&t, &tms);
00326   
00327     tp->sec  = tms.tm_sec;
00328     tp->min  = tms.tm_min;
00329     tp->hour = tms.tm_hour;
00330     tp->day  = tms.tm_mday;
00331     tp->mon  = tms.tm_mon;
00332     tp->year = tms.tm_year;
00333 }
00334 
00335 
00336 void av_registerfd(int fd)
00337 {
00338     fcntl(fd, F_SETFD, FD_CLOEXEC);
00339 }
00340