Main Page | Namespace List | Class Hierarchy | Class List | Directories | File List | Namespace Members | Class Members | File Members

logging.C

Go to the documentation of this file.
00001 // Copyright (C) 2001, Compaq Computer Corporation
00002 // 
00003 // This file is part of Vesta.
00004 // 
00005 // Vesta is free software; you can redistribute it and/or
00006 // modify it under the terms of the GNU Lesser General Public
00007 // License as published by the Free Software Foundation; either
00008 // version 2.1 of the License, or (at your option) any later version.
00009 // 
00010 // Vesta is distributed in the hope that it will be useful,
00011 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00012 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00013 // Lesser General Public License for more details.
00014 // 
00015 // You should have received a copy of the GNU Lesser General Public
00016 // License along with Vesta; if not, write to the Free Software
00017 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00018 
00019 // Last modified on Wed Dec  8 01:34:38 EST 2004 by ken@xorian.net
00020 
00021 /*
00022  * logging.C    This module handles error and debug info logging.
00023  *
00024  * Rewritten for Vesta; not much is left of the original, and those
00025  *  are the bad parts.  By the way, what copyright notice?  Listing
00026  *  authors is not a copyright notice. --Tim Mann <mann@pa.dec.com>
00027  * 
00028  * Original Authors:    Donald J. Becker, <becker@super.org>
00029  *              Rick Sladkey, <jrs@world.std.com>
00030  *              Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG>
00031  *
00032  *              This software may be used for any purpose provided
00033  *              the above copyright notice is retained.  It is supplied
00034  *              as is, with no warranty expressed or implied.
00035  */
00036 
00037 #include <Basics.H>
00038 #include <pthread.h>
00039 #include "nfsd.H"
00040 #include "logging.H"
00041 
00042 #define LOG_FILE  "%s.log"
00043 
00044 pthread_mutex_t dp_mutex;
00045 static pthread_once_t dp_once = PTHREAD_ONCE_INIT;
00046 
00047 static char printbuf[1024];             /* local print buffer           */
00048 int debugLevel = 0;                     /* enable/disable DEBUG logs    */
00049 static char log_name[32];               /* name of this program         */
00050 static FILE *log_fp = (FILE *)NULL;     /* fp for the log file          */
00051 
00052 extern "C"
00053 {
00054   static void
00055   dp_init()
00056   {
00057     pthread_mutex_init(&dp_mutex, (pthread_mutexattr_t *)NULL);
00058   }
00059 }
00060 
00061 void Repos::setDebugLevel(int level)
00062 {
00063     debugLevel = level;
00064 }
00065 
00066 int Repos::isDebugLevel(int level)
00067 {
00068     return level == 0 || ((debugLevel & level) != 0);
00069 }
00070 
00071 /* Log debugging information to stderr.  It will be printed if 
00072    level == 0 or if (level & debugLevel) != 0, where debugLevel
00073    is the argument to -d on the repository command line.
00074 */
00075 void Repos::dprintf(int level, const char *fmt, ...)
00076 {
00077     va_list args;
00078     time_t now;
00079     struct tm *tm;
00080 
00081     if (level == 0 || (level & debugLevel)) {
00082         pthread_once(&dp_once, dp_init);
00083         pthread_mutex_lock(&dp_mutex);
00084 
00085         (void) time(&now);
00086         tm = localtime(&now);
00087         fprintf(stderr, "%s %02d/%02d/%04d %02d:%02d:%02d ",
00088                 log_name, tm->tm_mon + 1, tm->tm_mday, tm->tm_year+1900,
00089                 tm->tm_hour, tm->tm_min, tm->tm_sec);
00090 
00091         va_start(args, fmt);
00092         vfprintf(stderr, fmt, args);
00093         va_end(args);
00094 
00095         pthread_mutex_unlock(&dp_mutex);
00096     }       
00097 }
00098 
00099 /* Log an incoming call */
00100 void
00101 Repos::log_call(struct svc_req *rqstp, struct dispatch_entry* dent,
00102                 union argument_types* argument)
00103 {
00104     char buff[2048];
00105     register char *sp;
00106     int i;
00107 
00108     if (!isDebugLevel(DBG_NFS)) return;
00109 
00110     sp = buff;
00111     sprintf(sp, "%s\n  [%d ", dent->name, rqstp->rq_cred.oa_flavor);
00112     sp += strlen(sp);
00113     if (rqstp->rq_cred.oa_flavor == AUTH_UNIX) {
00114         struct authunix_parms *unix_cred;
00115         struct tm stm;
00116 
00117         unix_cred = (struct authunix_parms *) rqstp->rq_clntcred;
00118 #if defined(__digital__) && defined(__DECCXX_VER)
00119 # if __DECCXX_VER < 60290033
00120         // Workaround for broken macro for localtime_r in the classic
00121         // Tru64 std_env.
00122 #  undef localtime_r
00123 # endif
00124 #endif
00125         localtime_r((time_t*) &unix_cred->aup_time, &stm);
00126         sprintf(sp, "%d/%d/%d %02d:%02d:%02d %s %d.%d",
00127                 stm.tm_year+1900, stm.tm_mon + 1, stm.tm_mday,
00128                 stm.tm_hour, stm.tm_min, stm.tm_sec,
00129                 unix_cred->aup_machname,
00130                 unix_cred->aup_uid,
00131                 unix_cred->aup_gid);
00132         sp += strlen(sp);
00133         if ((int) unix_cred->aup_len > 0) {
00134             sprintf(sp, "+%d", unix_cred->aup_gids[0]);
00135             sp += strlen(sp);
00136             for (i = 1; i < unix_cred->aup_len; i++) {
00137                 sprintf(sp, ",%d", unix_cred->aup_gids[i]);
00138                 sp += strlen(sp);
00139             }
00140         }
00141     }
00142     strcpy(sp, "]\n  ");
00143     sp += strlen(sp);
00144     dent->log_print(sp, argument);
00145     dprintf(DBG_NFS, "%s\n", buff);
00146 }
00147 
00148 /* Log a call's result */
00149 void Repos::log_result(struct svc_req *rqstp,
00150                        struct dispatch_entry* dent,
00151                        union result_types* result)
00152 {
00153     char buf[2048];
00154     if (!isDebugLevel(DBG_NFS)) return;
00155     dent->log_print_res(buf, result);
00156     dprintf(DBG_NFS, "%s\n", buf);
00157 }
00158 
00159 void Repos::pr_void(char* buf)
00160 {
00161     buf[0] = '\000';
00162 }
00163 
00164 void Repos::pr_sattrargs(char* buf, sattrargs *argp)
00165 {
00166     pr_nfs_fh(buf, &argp->file);
00167     buf += strlen(buf);
00168     sprintf(buf, " m:%0o u/g:%d/%d size:%d atime:%#x mtime:%#x",
00169             argp->attributes.mode,
00170             argp->attributes.uid, argp->attributes.gid,
00171             argp->attributes.size,
00172             argp->attributes.atime.seconds, argp->attributes.mtime.seconds);
00173 }
00174 
00175 void Repos::pr_diropargs(char* buf, diropargs *argp)
00176 {
00177     pr_nfs_fh(buf, &(argp->dir));
00178     buf += strlen(buf);
00179     sprintf(buf, " n:%s", argp->name);
00180 }
00181 
00182 void Repos::pr_readargs(char* buf, readargs *argp)
00183 {
00184     pr_nfs_fh(buf, &(argp->file));
00185     buf += strlen(buf);
00186     sprintf(buf, ": %d bytes at %d", argp->count, argp->offset);
00187 }
00188 
00189 void Repos::pr_writeargs(char* buf, writeargs *argp)
00190 {
00191     pr_nfs_fh(buf, &(argp->file));
00192     buf += strlen(buf);
00193     sprintf(buf, ": %d bytes at %d", argp->data.data_len, argp->offset);
00194 }
00195 
00196 void Repos::pr_createargs(char* buf, createargs *argp)
00197 {
00198     pr_nfs_fh(buf, &(argp->where.dir));
00199     buf += strlen(buf);
00200     sprintf(buf, " n:%s m:%0o u/g:%d/%d size:%d atime:%#x mtime:%#x",
00201             argp->where.name,
00202             argp->attributes.mode, argp->attributes.uid,
00203             argp->attributes.gid, argp->attributes.size,
00204             argp->attributes.atime.seconds, argp->attributes.mtime.seconds);
00205 }
00206 
00207 void Repos::pr_renameargs(char* buf, renameargs *argp)
00208 {
00209     strcpy(buf, "from:");
00210     buf += strlen(buf);
00211     pr_nfs_fh(buf, &(argp->from.dir));
00212     strcat(buf, " n:");
00213     strcat(buf, argp->from.name);
00214     strcat(buf, " to:");
00215     buf += strlen(buf);
00216     pr_nfs_fh(buf, &(argp->to.dir));
00217     strcat(buf, " n:");
00218     strcat(buf, argp->to.name);
00219 }
00220 
00221 void Repos::pr_linkargs(char *buf, linkargs *argp)
00222 {
00223     strcpy(buf, "unimplemented");
00224 }
00225 
00226 void Repos::pr_symlinkargs(char *buf, symlinkargs *argp)
00227 {
00228     strcpy(buf, "unimplemented");
00229 }
00230 
00231 void Repos::pr_readdirargs(char* buf, readdirargs *argp)
00232 {
00233     char digits[64];
00234     int i;
00235     pr_nfs_fh(buf, &argp->dir);
00236     strcat(buf, " cookie:");
00237     for (i=0; i<NFS_COOKIESIZE; i++) {
00238         sprintf(digits, "%02x", argp->cookie[i]);
00239         strcat(buf, digits);
00240     }
00241     sprintf(digits, " count:%u", argp->count);
00242     strcat(buf, digits);
00243 }
00244 
00245 static void pr_fattr(char* buf, fattr *argp)
00246 {
00247     sprintf(buf,
00248             "t:%d m:%0o n:%d u/g:%d/%d\n"
00249             "  sz:%d bsz:%d bks:%d rdev:%d fsid:%d fid:%#x\n"
00250             "  atime:%#x mtime:%#x ctime:%#x",
00251             argp->type,
00252             argp->mode,
00253             argp->nlink,
00254             argp->uid,
00255             argp->gid,
00256             argp->size,
00257             argp->blocksize,
00258             argp->blocks,
00259             argp->rdev,
00260             argp->fsid,
00261             argp->fileid,
00262             argp->atime,
00263             argp->mtime,
00264             argp->ctime);
00265 }
00266 
00267 void Repos::pr_attrstat(char* buf, attrstat *argp)
00268 {
00269     if (argp->status != NFS_OK) {
00270         sprintf(buf, "error:%d", argp->status);
00271     } else {
00272         pr_fattr(buf, &argp->attrstat_u.attributes);
00273     }
00274 }
00275 
00276 void Repos::pr_diropres(char* buf, diropres *argp)
00277 {
00278     if (argp->status != NFS_OK) {
00279         sprintf(buf, "error:%d", argp->status);
00280     } else {
00281         strcpy(buf, "fh:");
00282         buf += strlen(buf);
00283         pr_nfs_fh(buf, &argp->diropres_u.diropres.file);
00284         strcat(buf, " ");
00285         buf += strlen(buf);
00286         pr_fattr(buf, &argp->diropres_u.diropres.attributes);
00287     }
00288 }
00289 
00290 void Repos::pr_readlinkres(char* buf, readlinkres *argp)
00291 {
00292     if (argp->status != NFS_OK) {
00293         sprintf(buf, "error:%d", argp->status);
00294     } else {
00295         sprintf(buf, "ok");
00296     }
00297 }
00298 
00299 void Repos::pr_readres(char* buf, readres *argp)
00300 {
00301     if (argp->status != NFS_OK) {
00302         sprintf(buf, "error:%d", argp->status);
00303     } else {
00304         sprintf(buf, "len:%d ",
00305                 argp->readres_u.reply.data.data_len);
00306         buf += strlen(buf);
00307         pr_fattr(buf, &argp->readres_u.reply.attributes);
00308     }
00309 }
00310 
00311 void Repos::pr_nfsstat(char* buf, nfsstat *argp)
00312 {
00313     if (*argp != NFS_OK) {
00314         sprintf(printbuf, "error:%d", *argp);
00315     } else {
00316         sprintf(buf, "ok");
00317     }
00318 }
00319 
00320 void Repos::pr_readdirres(char* buf, readdirres *argp)
00321 {
00322     if (argp->status != NFS_OK) {
00323         sprintf(buf, "error:%d", argp->status);
00324     } else {
00325         sprintf(buf, "ok");
00326     }
00327 }
00328 
00329 void Repos::pr_statfsres(char* buf, statfsres *argp)
00330 {
00331     if (argp->status != NFS_OK) {
00332         sprintf(buf, "error:%d", argp->status);
00333     } else {
00334         sprintf(buf, "ok");
00335     }
00336 }
00337 
00338 void Repos::pr_nfs_fh(char* buf, nfs_fh *fh)
00339 {
00340     unsigned char *p = (unsigned char *) fh;
00341     int i, len;
00342 
00343     if (p[0] == 0 && p[1] == 4) {
00344         len = 24;
00345     } else {
00346         len = strlen((char*)&p[1]) + 1;
00347     }
00348     for (i = 0; i < len; i++) {
00349         sprintf(&buf[i*2], "%02x", p[i]);
00350     }
00351 }
00352 
00353 VRErrorCode::errorCode
00354 Repos::errno_to_errorCode(int err)
00355 {
00356     switch (err) {
00357       case 0:
00358         return VRErrorCode::ok;
00359       case EACCES:
00360       case EPERM:
00361       case EROFS:
00362         return VRErrorCode::noPermission;
00363       case EDQUOT:
00364       case EFBIG:
00365       case ENOSPC:
00366         return VRErrorCode::outOfSpace;
00367       case EISDIR:
00368         return VRErrorCode::isADirectory;
00369       case ENOTDIR:
00370         return VRErrorCode::notADirectory;
00371       case ENAMETOOLONG:
00372         return VRErrorCode::nameTooLong;
00373       case ENOENT:
00374         return VRErrorCode::notFound;
00375       case EINVAL:
00376         return VRErrorCode::invalidArgs;
00377       default:
00378         dprintf(DBG_ALWAYS,
00379                 "errno_to_errorCode: unexpected errno %d\n", err);
00380         return VRErrorCode::invalidArgs;
00381     }
00382 }

Generated on Mon May 8 00:48:44 2006 for Vesta by  doxygen 1.4.2