00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013 const char *XrdOssMSSCVSID = "$Id: XrdOssMSS.cc 34000 2010-06-21 06:49:56Z ganis $";
00014
00015 #include <dirent.h>
00016 #include <unistd.h>
00017 #include <errno.h>
00018 #include <strings.h>
00019 #include <signal.h>
00020 #include <stdio.h>
00021 #include <time.h>
00022 #if defined(AIX) || defined(__solaris__)
00023 #include <sys/vnode.h>
00024 #include <sys/mode.h>
00025 #endif
00026 #include <sys/param.h>
00027 #include <sys/types.h>
00028 #include <sys/stat.h>
00029 #include <sys/socket.h>
00030 #include <sys/un.h>
00031 #include <sys/wait.h>
00032
00033 #include "XrdNet/XrdNetOpts.hh"
00034 #include "XrdNet/XrdNetSocket.hh"
00035 #include "XrdOss/XrdOssApi.hh"
00036 #include "XrdOss/XrdOssConfig.hh"
00037 #include "XrdOss/XrdOssError.hh"
00038 #include "XrdOss/XrdOssTrace.hh"
00039 #include "XrdOuc/XrdOucProg.hh"
00040 #include "XrdOuc/XrdOucStream.hh"
00041 #include "XrdSys/XrdSysError.hh"
00042 #include "XrdSys/XrdSysHeaders.hh"
00043 #include "XrdSys/XrdSysLogger.hh"
00044 #include "XrdSys/XrdSysPlatform.hh"
00045
00046
00047
00048
00049
00050 extern XrdSysError OssEroute;
00051
00052 extern XrdOucTrace OssTrace;
00053
00054
00055
00056
00057
00058 #define NegVal(x) (x <= 0 ? (x < 0 ? x : -1) : -x)
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068 struct XrdOssHandle
00069 {int hflag;
00070 XrdOucStream *sp;
00071
00072 XrdOssHandle(int type, XrdOucStream *newsp=0) {hflag = type; sp = newsp;}
00073 ~XrdOssHandle() {if (sp) delete sp; hflag = 0;}
00074
00075 };
00076
00077 #define XRDOSS_HT_EOF 1
00078 #define XRDOSS_HT_DIR 4
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088 void *XrdOssSys::MSS_Opendir(const char *dir_path, int &rc) {
00089
00090
00091
00092
00093
00094
00095
00096
00097 const char *epname = "MSS_Opendir";
00098 struct XrdOssHandle *oh;
00099 XrdOucStream *sp;
00100
00101
00102
00103 if (strlen(dir_path) > MAXPATHLEN)
00104 {OssEroute.Emsg(epname, "mss path too long - ", dir_path);
00105 rc = -ENAMETOOLONG;
00106 return (void *)0;
00107 }
00108
00109
00110
00111
00112 if ( (rc = MSS_Xeq(&sp, ENOENT, "dlist", dir_path)))
00113 return (void *)0;
00114
00115
00116
00117 if (!(oh = new XrdOssHandle(XRDOSS_HT_DIR, sp)))
00118 {delete sp; rc = -ENOMEM; return (void *)0;}
00119 return (void *)oh;
00120 }
00121
00122
00123
00124
00125
00126 int XrdOssSys::MSS_Readdir(void *dir_handle, char *buff, int blen) {
00127
00128
00129
00130
00131
00132
00133
00134
00135
00136
00137
00138
00139
00140 const char *epname = "MSS_Readdir";
00141 int retc;
00142 struct XrdOssHandle *oh = (struct XrdOssHandle *)dir_handle;
00143 char *resp;
00144
00145
00146
00147 if ( !(oh->hflag & XRDOSS_HT_DIR) )
00148 {OssEroute.Emsg(epname, "invalid mss handle"); return -EBADF;}
00149
00150
00151
00152 if (oh->hflag & XRDOSS_HT_EOF) *buff = '\0';
00153 else if ((resp = oh->sp->GetLine()))
00154 {if ( ((int)strlen(resp)) >= blen )
00155 {*buff = '\0';
00156 return OssEroute.Emsg(epname, -EOVERFLOW,
00157 "readdir rmt", resp);
00158 }
00159 strlcpy(buff, resp, blen);
00160 } else {
00161 if ((retc = oh->sp->LastError())) return NegVal(retc);
00162 else {*buff = '\0'; oh->hflag |= XRDOSS_HT_EOF;}
00163 }
00164 return XrdOssOK;
00165 }
00166
00167
00168
00169
00170
00171 int XrdOssSys::MSS_Closedir(void *dir_handle) {
00172
00173
00174
00175
00176
00177
00178
00179 const char *epname = "MSS_Closedir";
00180 struct XrdOssHandle *oh = (struct XrdOssHandle *)dir_handle;
00181
00182 if ( !(oh->hflag & XRDOSS_HT_DIR) )
00183 {OssEroute.Emsg(epname, "invalid mss handle"); return -EBADF;}
00184 delete oh;
00185 return XrdOssOK;
00186 }
00187
00188
00189
00190
00191
00192 int XrdOssSys::MSS_Create(const char *path, mode_t file_mode, XrdOucEnv &env)
00193
00194
00195
00196
00197
00198
00199
00200
00201
00202
00203
00204 {
00205 const char *epname = "MSS_Create";
00206 char myMode[16];
00207
00208
00209
00210 if (strlen(path) > MAXPATHLEN)
00211 {OssEroute.Emsg(epname, "mss path too long - ", path);
00212 return -ENAMETOOLONG;
00213 }
00214
00215
00216
00217 sprintf(myMode, "%o", static_cast<int>(file_mode));
00218
00219
00220
00221 return MSS_Xeq(0, 0, "create", path, myMode);
00222 }
00223
00224
00225
00226
00227
00228
00229
00230
00231
00232
00233
00234
00235
00236
00237
00238
00239 int XrdOssSys::MSS_Stat(const char *path, struct stat *buff)
00240 {
00241 const char *epname = "MSS_Stat";
00242 char ftype, mtype[10], *resp;
00243 int retc, xt_nlink;
00244 long xt_uid, xt_gid, atime, ctime, mtime, xt_blksize, xt_blocks;
00245 long long xt_size;
00246 XrdOucStream *sfd;
00247
00248
00249
00250 if (strlen(path) > MAXPATHLEN)
00251 {OssEroute.Emsg(epname, "mss path too long - ", path);
00252 return -ENAMETOOLONG;
00253 }
00254
00255
00256
00257 if (!buff) return MSS_Xeq(0, ENOENT, (isMSSC ? "statx" : "exists"), path);
00258 if ((retc = MSS_Xeq(&sfd, ENOENT, "statx", path))) return retc;
00259
00260
00261
00262 if ( !(resp = sfd ->GetLine()))
00263 return OssEroute.Emsg(epname,-XRDOSS_E8012,"process ",path);
00264
00265
00266
00267 sscanf(resp, "%c %9s %d %ld %ld %ld %ld %ld %lld %ld %ld", &ftype, mtype,
00268 &xt_nlink, &xt_uid, &xt_gid, &atime, &ctime, &mtime,
00269 &xt_size, &xt_blksize, &xt_blocks);
00270
00271
00272
00273 memset( (char *)buff, 0, sizeof(struct stat) );
00274 buff->st_nlink = static_cast<nlink_t>(xt_nlink);
00275 buff->st_uid = static_cast<uid_t>(xt_uid);
00276 buff->st_gid = static_cast<gid_t>(xt_gid);
00277 buff->st_atime = static_cast<time_t>(atime);
00278 buff->st_ctime = static_cast<time_t>(ctime);
00279 buff->st_mtime = static_cast<time_t>(mtime);
00280 buff->st_size = static_cast<off_t>(xt_size);
00281 buff->st_blksize=static_cast<long>(xt_blksize);
00282 #ifdef __macos__
00283 buff->st_blocks = xt_blocks;
00284 #else
00285 buff->st_blocks =static_cast<blkcnt_t>(xt_blocks);
00286 #endif
00287
00288 if (ftype == 'd') buff->st_mode |= S_IFDIR;
00289 else if (ftype == 'l') buff->st_mode |= S_IFLNK;
00290 else buff->st_mode |= S_IFREG;
00291
00292 buff->st_mode |= tranmode(&mtype[0]) << 6;
00293 buff->st_mode |= tranmode(&mtype[3]) << 3;
00294 buff->st_mode |= tranmode(&mtype[6]);
00295
00296 delete sfd;
00297 return 0;
00298 }
00299
00300 int XrdOssSys::tranmode(char *mode) {
00301 int mbits = 0;
00302 if (mode[0] == 'r') mbits |= S_IROTH;
00303 if (mode[1] == 'w') mbits |= S_IWOTH;
00304 if (mode[2] == 'x') mbits |= S_IXOTH;
00305 return mbits;
00306 }
00307
00308
00309
00310
00311
00312
00313
00314
00315
00316
00317
00318
00319 int XrdOssSys::MSS_Unlink(const char *path) {
00320 const char *epname = "MSS_Unlink";
00321
00322
00323
00324 if (strlen(path) > MAXPATHLEN)
00325 {OssEroute.Emsg(epname, "mss path too long - ", path);
00326 return -ENAMETOOLONG;
00327 }
00328
00329
00330
00331 return MSS_Xeq(0, ENOENT, "rm", path);
00332 }
00333
00334
00335
00336
00337
00338
00339
00340
00341
00342
00343
00344
00345
00346 int XrdOssSys::MSS_Rename(const char *oldname, const char *newname) {
00347 const char *epname = "MSS_Rename";
00348
00349
00350
00351 if (strlen(oldname) > MAXPATHLEN
00352 || strlen(newname) > MAXPATHLEN)
00353 {OssEroute.Emsg(epname,"mss path too long - ", oldname, newname);
00354 return -ENAMETOOLONG;
00355 }
00356
00357
00358
00359 return MSS_Xeq(0, 0, "mv", oldname, newname);
00360 }
00361
00362
00363
00364
00365
00366
00367
00368
00369 int XrdOssSys::MSS_Xeq(XrdOucStream **xfd, int okerr,
00370 const char *cmd, const char *arg1, const char *arg2)
00371 {
00372 EPNAME("MSS_Xeq")
00373 static int NoResp = 0;
00374 char *resp;
00375 int retc;
00376 XrdOucStream *sp;
00377
00378
00379
00380 if (!RSSProg) return -XRDOSS_E8013;
00381
00382
00383
00384 if (!(sp = new XrdOucStream(&OssEroute)))
00385 return OssEroute.Emsg("MSS_Xeq",-ENOMEM,"create stream for",RSSCmd);
00386
00387
00388
00389 DEBUG("Invoking '" <<RSSCmd <<' ' <<cmd <<' ' <<(arg1 ? arg1 : "")
00390 <<' ' <<(arg2 ? arg2 : ""));
00391 if ((retc = RSSProg->Run(sp, cmd, arg1, arg2)))
00392 {delete sp; return NegVal(retc);}
00393
00394
00395
00396
00397 if ((retc = sp->Wait4Data(RSSTout)))
00398 {if (retc < 0)
00399 {if (!(0xff & NoResp++))
00400 OssEroute.Emsg("MSS_Xeq", -ETIMEDOUT, "execute", cmd);
00401 retc = ETIMEDOUT;
00402 }
00403 delete sp; return NegVal(retc);
00404 }
00405
00406
00407
00408
00409 if ( !(resp = sp->GetLine()) ) retc = XRDOSS_E8023;
00410 else
00411 {DEBUG("received '" <<resp <<"'");
00412 if (sscanf(resp, "%d", &retc) <= 0) retc = XRDOSS_E8024;
00413 }
00414 if (retc)
00415 {if (retc != -okerr)
00416 OssEroute.Emsg("MSS_Xeq", NegVal(retc), "execute", cmd);
00417 delete sp;
00418 return NegVal(retc);
00419 }
00420
00421
00422
00423 if (xfd) *xfd = sp;
00424 else delete sp;
00425 return 0;
00426 }