00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013 const char *XrdFrmAdminFilesCVSID = "$Id: XrdFrmAdminFiles.cc 32231 2010-02-05 18:24:46Z ganis $";
00014
00015 #include <errno.h>
00016 #include <fcntl.h>
00017 #include <stdio.h>
00018 #include <string.h>
00019 #include <time.h>
00020 #include <unistd.h>
00021 #include <sys/param.h>
00022 #include <sys/types.h>
00023 #include <sys/stat.h>
00024
00025 #include "XrdFrm/XrdFrmAdmin.hh"
00026 #include "XrdFrm/XrdFrmConfig.hh"
00027 #include "XrdFrm/XrdFrmFiles.hh"
00028 #include "XrdFrm/XrdFrmUtils.hh"
00029
00030 using namespace XrdFrm;
00031
00032
00033
00034
00035
00036 int XrdFrmAdmin::mkLock(const char *Lfn)
00037 {
00038 XrdFrmFileset *sP;
00039 XrdFrmFiles *fP;
00040 char Pfn[MAXPATHLEN+8], Resp;
00041 int opts = (Opt.Recurse ? XrdFrmFiles::Recursive : 0);
00042 int ec = 0;
00043
00044
00045
00046 if (!(Resp = mkStat(mkLF, Lfn, Pfn, sizeof(Pfn)-8))) return 1;
00047 if (Resp == 'a') return 0;
00048
00049
00050
00051 if (Resp == 'f')
00052 {if (mkFile(mkLF|isPFN, Pfn)) numFiles++;
00053 return 1;
00054 }
00055
00056
00057
00058 fP = new XrdFrmFiles(Pfn, opts);
00059 while((sP = fP->Get(ec,1)))
00060 {if (sP->baseFile() && mkFile(mkLF|isPFN, sP->basePath())) numFiles++;}
00061
00062
00063
00064 if (ec) finalRC = 4;
00065 delete fP;
00066 return 1;
00067 }
00068
00069
00070
00071
00072
00073 int XrdFrmAdmin::mkPin(const char *Lfn, const char *Pdata, int Pdlen)
00074 {
00075 XrdFrmFileset *sP;
00076 XrdFrmFiles *fP;
00077 char Pfn[MAXPATHLEN+8], Resp;
00078 int opts = (Opt.Recurse ? XrdFrmFiles::Recursive : 0);
00079 int ec;
00080
00081
00082
00083 if (!(Resp = mkStat(mkPF, Lfn, Pfn, sizeof(Pfn)-8))) return 1;
00084 if (Resp == 'a') return 0;
00085
00086
00087
00088 if (Resp == 'f')
00089 {if (mkFile(mkPF|isPFN, Pfn, Pdata, Pdlen)) numFiles++;
00090 return 1;
00091 }
00092
00093
00094
00095 fP = new XrdFrmFiles(Pfn, opts);
00096 while((sP = fP->Get(ec,1)))
00097 {if (sP->baseFile() && mkFile(mkPF|isPFN,sP->basePath(),Pdata,Pdlen))
00098 numFiles++;
00099 }
00100
00101
00102
00103 if (ec) finalRC = 4;
00104 delete fP;
00105 return 1;
00106 }
00107
00108
00109
00110
00111
00112 int XrdFrmAdmin::mkFile(int What, const char *Path, const char *Data, int DLen)
00113 {
00114 static const mode_t Mode = S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|S_IROTH;
00115 struct stat Stat;
00116 time_t Tid;
00117 uid_t Uid;
00118 gid_t Gid;
00119 char *pfn, baseFN[1038], tempFN[1038];
00120 int rc, theFD;
00121
00122
00123
00124 if (!Config.lockFN || *Config.lockFN != '.') pfn = baseFN;
00125 else {*baseFN = '.'; pfn = baseFN+1;}
00126
00127
00128
00129 if (What & isPFN) strcpy(pfn, Path);
00130 else if (!Config.LocalPath(Path, pfn, sizeof(baseFN)-6)) return 0;
00131
00132
00133
00134 if (stat(pfn, &Stat)) {Emsg(errno,"stat pfn ",pfn); return 0;}
00135
00136
00137
00138 strcat(baseFN, (What & mkLF ? ".lock" : ".pin"));
00139 strcpy(tempFN, baseFN);
00140 strcat(tempFN, ".TEMP");
00141
00142
00143
00144 if ((What & mkPF) && !Opt.ktAlways && !Opt.KeepTime)
00145 {if (unlink(baseFN)) {Emsg(errno, "remove pfn ", tempFN); return 0;}
00146 return 1;
00147 }
00148
00149
00150
00151 if ((theFD = open(tempFN, O_RDWR | O_CREAT | O_TRUNC, Mode)) < 0)
00152 {Emsg(errno, "open pfn ", tempFN); return 0;}
00153
00154
00155
00156 if (Data && DLen)
00157 {do {rc = write(theFD, Data, DLen);
00158 if (rc < 0) {if (errno != EINTR) break;}
00159 else {Data += rc; DLen -= rc;}
00160 } while(DLen > 0);
00161 if (rc< 0) {Emsg(errno, "write pfn ", tempFN);
00162 close(theFD); unlink(tempFN); return 0;
00163 }
00164 }
00165
00166
00167
00168 Uid = (int(Opt.Uid) < 0 ? Stat.st_uid : Opt.Uid);
00169 Gid = (int(Opt.Gid) < 0 ? Stat.st_gid : Opt.Gid);
00170 if (Stat.st_uid != Uid || Stat.st_gid != Gid)
00171 {do {rc = fchown(theFD, Uid, Gid);} while(rc && errno == EINTR);
00172 if (rc) {Emsg(errno, "set uid/gid for pfn ", tempFN);
00173 close(theFD); unlink(tempFN); return 0;
00174 }
00175 }
00176
00177
00178
00179 if (What & mkLF) {Tid = Stat.st_mtime + (Opt.MPType == 'p' ? +113 : -113);}
00180 else {Tid = (DLen || Opt.ktAlways ? time(0) : Opt.KeepTime);
00181 if (Opt.ktAlways)
00182 {do {rc = fchmod(theFD, Mode|S_ISUID);} while(rc && errno == EINTR);
00183 if (rc) {Emsg(errno, "set mode for pfn ", tempFN);
00184 close(theFD); unlink(tempFN); return 0;
00185 }
00186 }
00187 }
00188 close(theFD);
00189 if (!XrdFrmUtils::Utime(tempFN,Tid)) {unlink(tempFN); return 0;}
00190
00191
00192
00193 if (rename(tempFN, baseFN))
00194 {Emsg(errno, "rename pfn ", tempFN);
00195 unlink(tempFN);
00196 return 0;
00197 }
00198 return 1;
00199 }
00200
00201
00202
00203
00204
00205 char XrdFrmAdmin::mkStat(int What, const char *Lfn, char *Pfn, int Pfnsz)
00206 {
00207 struct stat Stat;
00208 const char *Msg = (What & mkLF ? "create lock file for "
00209 : "create pin file for ");
00210 const char *Msh = (What & mkLF ? "create lock files in "
00211 : "create pin files in ");
00212 char Resp;
00213
00214
00215
00216 if (!Config.LocalPath(Lfn, Pfn, Pfnsz)) {finalRC = 4; return 0;}
00217
00218
00219
00220 if (stat(Pfn, &Stat))
00221 {Emsg(errno, "create ", Msg, Lfn); return 0;}
00222
00223
00224
00225 if ((Stat.st_mode & S_IFMT) != S_IFDIR)
00226 {if (!Opt.All) return 'f';
00227 Emsg(ENOTDIR, "create ", Msh, Lfn);
00228 return 0;
00229 }
00230
00231
00232
00233 if (Opt.All || Opt.Recurse) return 'd';
00234
00235
00236
00237 Msg = (What & mkLF ? "Apply makelf to ALL files in directory "
00238 : "Apply pin to ALL files in directory ");
00239 if ((Resp = XrdFrmUtils::Ask('n', Msg, Lfn)) == 'y') return 'd';
00240 return (Resp == 'a' ? 'a' : 0);
00241 }