00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013 const char *XrdOssRenameCVSID = "$Id: XrdOssRename.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 <fcntl.h>
00020 #include <stdio.h>
00021 #include <sys/param.h>
00022 #include <sys/types.h>
00023 #include <sys/stat.h>
00024
00025 #include "XrdSys/XrdSysHeaders.hh"
00026 #include "XrdOss/XrdOssApi.hh"
00027 #include "XrdOss/XrdOssCache.hh"
00028 #include "XrdOss/XrdOssError.hh"
00029 #include "XrdOss/XrdOssLock.hh"
00030 #include "XrdOss/XrdOssPath.hh"
00031 #include "XrdOss/XrdOssTrace.hh"
00032 #include "XrdOuc/XrdOucExport.hh"
00033 #include "XrdOuc/XrdOucUtils.hh"
00034
00035
00036
00037
00038
00039 extern XrdSysError OssEroute;
00040
00041 extern XrdOucTrace OssTrace;
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055 int XrdOssSys::Rename(const char *oldname, const char *newname)
00056 {
00057 EPNAME("Rename")
00058 static const mode_t pMode = S_IRWXU | S_IRWXG;
00059 unsigned long long remotefs_Old, remotefs_New, remotefs, haslf;
00060 unsigned long long old_popts, new_popts;
00061 int i, retc2, retc = XrdOssOK;
00062 XrdOssLock old_file, new_file;
00063 struct stat statbuff;
00064 char *slashPlus, sPChar;
00065 char local_path_Old[MAXPATHLEN+8], *lpo;
00066 char local_path_New[MAXPATHLEN+8], *lpn;
00067 char remote_path_Old[MAXPATHLEN+1];
00068 char remote_path_New[MAXPATHLEN+1];
00069
00070
00071
00072 remotefs_Old = Check_RO(Rename, old_popts, oldname, "renaming ");
00073 remotefs_New = Check_RO(Rename, new_popts, newname, "renaming to ");
00074
00075
00076
00077 if (remotefs_Old ^ remotefs_New
00078 || ((old_popts & XRDEXP_MIG) ^ (new_popts & XRDEXP_MIG)))
00079 {char buff[MAXPATHLEN+128];
00080 snprintf(buff, sizeof(buff), "rename %s to ", oldname);
00081 return OssEroute.Emsg("Rename",-XRDOSS_E8011,buff,(char *)newname);
00082 }
00083 remotefs = remotefs_Old | remotefs_New;
00084 haslf = (XRDEXP_MAKELF & (old_popts | new_popts));
00085
00086
00087
00088 if ( (retc = GenLocalPath( oldname, local_path_Old))
00089 || (retc = GenLocalPath( newname, local_path_New)) ) return retc;
00090 if (remotefs
00091 && (((retc = GenRemotePath(oldname, remote_path_Old))
00092 || (retc = GenRemotePath(newname, remote_path_New)))) ) return retc;
00093
00094
00095
00096 if (remotefs &&
00097 (retc2 = new_file.Serialize(local_path_New, XrdOssDIR|XrdOssEXC)) < 0)
00098 return retc2;
00099
00100
00101
00102 retc2 = lstat(local_path_New, &statbuff);
00103 if (remotefs) new_file.UnSerialize(0);
00104 if (!retc2) return -EEXIST;
00105
00106
00107
00108 if (!(slashPlus = rindex(local_path_New, '/'))) return -EINVAL;
00109 slashPlus++; sPChar = *slashPlus; *slashPlus = '\0';
00110 retc2 = XrdOucUtils::makePath(local_path_New, pMode);
00111 *slashPlus = sPChar;
00112 if (retc2) return retc2;
00113
00114
00115
00116 if (remotefs &&
00117 (retc = old_file.Serialize(local_path_Old, XrdOssDIR|XrdOssEXC)) < 0)
00118 return retc;
00119
00120
00121
00122 if (lstat(local_path_Old, &statbuff)) retc = -errno;
00123 else if ((statbuff.st_mode & S_IFMT) == S_IFLNK)
00124 retc = RenameLink(local_path_Old, local_path_New);
00125 else if (rename(local_path_Old, local_path_New)) retc = -errno;
00126 DEBUG("lcl rc=" <<retc <<" op=" <<local_path_Old <<" np=" <<local_path_New);
00127
00128
00129
00130 if (haslf)
00131 {if ((!retc || retc == -ENOENT))
00132 {i = strlen(local_path_Old); lpo = &local_path_Old[i];
00133 i = strlen(local_path_New); lpn = &local_path_New[i];
00134 for (i = 0; i < XrdOssPath::sfxMigL; i++)
00135 {strcpy(lpo,XrdOssPath::Sfx[i]); strcpy(lpn,XrdOssPath::Sfx[i]);
00136 if (rename(local_path_Old,local_path_New) && ENOENT != errno)
00137 DEBUG("sfx retc=" <<errno <<" op=" <<local_path_Old);
00138 }
00139 }
00140 }
00141
00142
00143
00144
00145 if (remotefs)
00146 {if (remotefs && (!retc || retc == -ENOENT) && RSSCmd)
00147 {if ( (retc2 = MSS_Rename(remote_path_Old, remote_path_New))
00148 != -ENOENT) retc = retc2;
00149 DEBUG("rmt rc=" <<retc2 <<" op=" <<remote_path_Old <<" np=" <<remote_path_New);
00150 }
00151
00152
00153
00154 old_file.UnSerialize(0);
00155 }
00156
00157
00158
00159 return retc;
00160 }
00161
00162
00163
00164
00165
00166
00167
00168
00169 int XrdOssSys::RenameLink(char *old_path, char *new_path)
00170 {
00171 struct stat statbuff;
00172 char oldlnk[MAXPATHLEN+32], newlnk[MAXPATHLEN+32];
00173 int lnklen, n, rc = 0;
00174
00175
00176
00177 if ((lnklen = readlink(old_path,oldlnk,sizeof(oldlnk)-1)) < 0) return -errno;
00178 oldlnk[lnklen] = '\0';
00179
00180
00181
00182
00183 if (oldlnk[lnklen-1] == XrdOssPath::xChar)
00184 {if ((rc=RenameLink2(lnklen,oldlnk,old_path,newlnk,new_path))) return rc;
00185 if (Solitary && UDir)
00186 {n = strlen(old_path);
00187 if (n < 6 || strcmp(old_path+n-5, ".anew")
00188 || stat(new_path, &statbuff) || !statbuff.st_size) return 0;
00189 XrdOssPath::Trim2Base(oldlnk+lnklen-1);
00190 XrdOssCache::Adjust(oldlnk, statbuff.st_size);
00191 }
00192 return 0;
00193 }
00194
00195
00196
00197 if ((rc = XrdOssPath::Convert(newlnk, sizeof(newlnk), oldlnk, new_path)))
00198 {OssEroute.Emsg("RenameLink", rc, "convert", oldlnk);
00199 return rc;
00200 }
00201
00202
00203
00204 if (!lstat(newlnk, &statbuff))
00205 {OssEroute.Emsg("RenameLink",-EEXIST,"check new target", newlnk);
00206 return -EEXIST;
00207 }
00208
00209
00210
00211 if (symlink(newlnk, new_path))
00212 {rc = errno;
00213 OssEroute.Emsg("RenameLink", rc, "symlink to", newlnk);
00214 return -rc;
00215 }
00216
00217
00218
00219 if (rename(oldlnk, newlnk))
00220 {rc = errno;
00221 OssEroute.Emsg("RenameLink", rc, "rename", oldlnk);
00222 unlink(new_path);
00223 return -rc;
00224 }
00225
00226
00227
00228 if (unlink(old_path))
00229 OssEroute.Emsg("RenameLink", rc, "unlink", old_path);
00230
00231
00232
00233 return 0;
00234 }
00235
00236
00237
00238
00239
00240 int XrdOssSys::RenameLink2(int Llen, char *oLnk, char *old_path,
00241 char *nLnk, char *new_path)
00242 {
00243 int rc;
00244
00245
00246
00247 strcpy(nLnk, oLnk);
00248 strcpy(nLnk+Llen, ".pfn");
00249 unlink(nLnk);
00250
00251
00252
00253 if (symlink(new_path, nLnk))
00254 {rc = errno;
00255 OssEroute.Emsg("RenameLink", rc, "create symlink", nLnk);
00256 return -rc;
00257 }
00258
00259
00260
00261 if (symlink(oLnk, new_path))
00262 {rc = errno;
00263 OssEroute.Emsg("RenameLink", rc, "symlink to", oLnk);
00264 unlink(nLnk);
00265 return -rc;
00266 }
00267
00268
00269
00270 if (unlink(old_path))
00271 OssEroute.Emsg("RenameLink", errno, "unlink", old_path);
00272
00273
00274
00275 return 0;
00276 }