00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
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];
00048 int debugLevel = 0;
00049 static char log_name[32];
00050 static FILE *log_fp = (FILE *)NULL;
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
00072
00073
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
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
00121
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
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 }