00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013 const char *XrdOssUnlinkCVSID = "$Id: XrdOssUnlink.cc 34000 2010-06-21 06:49:56Z ganis $";
00014
00015 #include <unistd.h>
00016 #include <errno.h>
00017 #include <strings.h>
00018 #include <limits.h>
00019 #include <stdio.h>
00020 #include <sys/param.h>
00021 #include <sys/types.h>
00022 #include <sys/stat.h>
00023
00024 #include "XrdSys/XrdSysHeaders.hh"
00025 #include "XrdOss/XrdOssApi.hh"
00026 #include "XrdOss/XrdOssCache.hh"
00027 #include "XrdOss/XrdOssConfig.hh"
00028 #include "XrdOss/XrdOssError.hh"
00029 #include "XrdOss/XrdOssLock.hh"
00030 #include "XrdOss/XrdOssOpaque.hh"
00031 #include "XrdOss/XrdOssPath.hh"
00032 #include "XrdOss/XrdOssTrace.hh"
00033
00034
00035
00036
00037
00038 extern XrdSysError OssEroute;
00039
00040 extern XrdOucTrace OssTrace;
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053 int XrdOssSys::Remdir(const char *path, int Opts)
00054 {
00055 unsigned long long opts;
00056 int retc;
00057 struct stat statbuff;
00058 char local_path[MAXPATHLEN+1+8];
00059
00060
00061
00062 if (Opts & XRDOSS_isPFN) strcpy(local_path, path);
00063 else {retc = Check_RO(Unlink, opts, path, "deleting ");
00064 if ( (retc = GenLocalPath( path, local_path))) return retc;
00065 }
00066
00067
00068
00069 if (lstat(local_path, &statbuff)) return (errno == ENOENT ? 0 : -errno);
00070 if ((statbuff.st_mode & S_IFMT) != S_IFDIR) return -ENOTDIR;
00071
00072
00073
00074 return Unlink(path, Opts);
00075 }
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088 int XrdOssSys::Unlink(const char *path, int Opts)
00089 {
00090 EPNAME("Unlink")
00091 unsigned long long haslf, remotefs;
00092 int i, retc2, doAdjust = 0, retc = XrdOssOK;
00093 XrdOssLock un_file;
00094 struct stat statbuff;
00095 char *fnp;
00096 char local_path[MAXPATHLEN+1+8];
00097 char remote_path[MAXPATHLEN+1];
00098
00099
00100
00101 if (Opts & XRDOSS_isPFN)
00102 {strcpy(local_path, path),
00103 *remote_path = '\0';
00104 haslf = Opts & XRDOSS_isMIG;
00105 remotefs = 0;
00106 } else {
00107 remotefs = Check_RO(Unlink, haslf, path, "deleting ");
00108 if ( (retc = GenLocalPath( path, local_path))
00109 || (retc = GenRemotePath(path, remote_path)) ) return retc;
00110 haslf &= XRDEXP_MAKELF;
00111 }
00112
00113
00114
00115 if (remotefs && (retc=un_file.Serialize(local_path,XrdOssDIR|XrdOssEXC)) < 0)
00116 return retc;
00117
00118
00119
00120 if (lstat(local_path, &statbuff)) retc = (errno == ENOENT ? 0 : -errno);
00121 else if ((statbuff.st_mode & S_IFMT) == S_IFLNK)
00122 retc = BreakLink(local_path, statbuff);
00123 else if ((statbuff.st_mode & S_IFMT) == S_IFDIR)
00124 {if (remotefs) un_file.UnSerialize(0);
00125 un_file.NoSerialize(local_path, XrdOssDIR);
00126 if ((retc = rmdir(local_path))) retc = -errno;
00127 DEBUG("dir rc=" <<retc <<" path=" <<local_path);
00128 return retc;
00129 } else doAdjust = 1;
00130
00131
00132
00133 if (!retc)
00134 {if (unlink(local_path)) retc = -errno;
00135 else {i = strlen(local_path); fnp = &local_path[i];
00136 if (doAdjust && statbuff.st_size)
00137 XrdOssCache::Adjust(statbuff.st_dev, -statbuff.st_size);
00138 if (haslf) for (i = 0; i < XrdOssPath::sfxMigL; i++)
00139 {strcpy(fnp, XrdOssPath::Sfx[i]);
00140 if (unlink(local_path))
00141 if (errno == ENOENT) continue;
00142 else retc2 = errno;
00143 else retc2 = 0;
00144 DEBUG("sfx retc=" <<retc2 <<' ' <<local_path);
00145 }
00146 }
00147 DEBUG("lcl rc=" <<retc <<" path=" <<local_path);
00148 }
00149
00150
00151
00152 if (remotefs && !(Opts & XRDOSS_Online)
00153 && (!retc || retc == -ENOENT) && RSSCmd)
00154 {if ((retc2 = MSS_Unlink(remote_path)) != -ENOENT) retc = retc2;
00155 DEBUG("rmt rc=" <<retc2 <<" path=" <<remote_path);
00156 }
00157
00158
00159
00160 if (remotefs) un_file.UnSerialize(0);
00161 return retc;
00162 }
00163
00164
00165
00166
00167
00168
00169
00170
00171 int XrdOssSys::BreakLink(const char *local_path, struct stat &statbuff)
00172 {
00173 EPNAME("BreakLink")
00174 char *lP, lnkbuff[MAXPATHLEN+64];
00175 int lnklen, retc = 0;
00176
00177
00178
00179 if ((lnklen = readlink(local_path, lnkbuff, sizeof(lnkbuff)-1)) < 0)
00180 return -errno;
00181
00182
00183
00184 lnkbuff[lnklen] = '\0';
00185 if (stat(lnkbuff, &statbuff)) statbuff.st_size = 0;
00186 else if (unlink(lnkbuff) && errno != ENOENT)
00187 {retc = -errno;
00188 OssEroute.Emsg("BreakLink",retc,"unlink symlink target",lnkbuff);
00189 } else {DEBUG("broke link " <<local_path <<"->" <<lnkbuff);}
00190
00191
00192
00193
00194 lP = lnkbuff+lnklen-1;
00195 if (*lP == XrdOssPath::xChar)
00196 {strcpy(lP+1, ".pfn"); unlink(lnkbuff);
00197 if (statbuff.st_size)
00198 {XrdOssPath::Trim2Base(lP);
00199 XrdOssCache::Adjust(lnkbuff, -statbuff.st_size);
00200 }
00201 } else if (statbuff.st_size)
00202 XrdOssCache::Adjust(statbuff.st_dev, -statbuff.st_size);
00203
00204
00205
00206 return retc;
00207 }