00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023 #include <config.h>
00024
00025 #include <drizzled/internal/my_sys.h>
00026 #include <drizzled/error.h>
00027 #include <drizzled/internal/m_string.h>
00028
00029 namespace drizzled {
00030 namespace internal {
00031
00032 int my_create_with_symlink(const char *linkname, const char *filename,
00033 int createflags, int access_flags, myf MyFlags)
00034 {
00035
00036 bool create_link= false;
00037 char rp_buff[PATH_MAX];
00038
00039 if (my_disable_symlinks)
00040 {
00041
00042 if (linkname)
00043 filename= linkname;
00044 }
00045 else if (linkname)
00046 {
00047 if (!realpath(linkname,rp_buff))
00048 my_load_path(rp_buff, linkname, NULL);
00049 rp_buff[FN_REFLEN-1]= '\0';
00050 char abs_linkname[FN_REFLEN];
00051 strcpy(abs_linkname, rp_buff);
00052 create_link= strcmp(abs_linkname, filename);
00053 }
00054
00055 if (!(MyFlags & MY_DELETE_OLD))
00056 {
00057 if (!access(filename,F_OK))
00058 {
00059 errno= EEXIST;
00060 my_error(EE_CANTCREATEFILE, MYF(0), filename, EEXIST);
00061 return(-1);
00062 }
00063 if (create_link && !access(linkname,F_OK))
00064 {
00065 errno= EEXIST;
00066 my_error(EE_CANTCREATEFILE, MYF(0), linkname, EEXIST);
00067 return(-1);
00068 }
00069 }
00070
00071 int file= my_create(filename, createflags, access_flags, MyFlags);
00072 if (file >= 0 && create_link)
00073 {
00074
00075 if (MyFlags & MY_DELETE_OLD)
00076 my_delete(linkname, MYF(0));
00077
00078 if (symlink(filename,linkname))
00079 {
00080
00081 int tmp_errno= errno;
00082 my_close(file, MYF(0));
00083 my_delete(filename, MYF(0));
00084 file= -1;
00085 errno= tmp_errno;
00086 }
00087 else if (MyFlags & MY_SYNC_DIR)
00088 my_sync_dir_by_file(linkname, MyFlags);
00089 }
00090 return file;
00091 }
00092
00093
00094
00095
00096
00097
00098 int my_delete_with_symlink(const char *name, myf MyFlags)
00099 {
00100 char link_name[FN_REFLEN];
00101 ssize_t sym_link_size= readlink(name,link_name,FN_REFLEN-1);
00102 int was_symlink= (!my_disable_symlinks && sym_link_size != -1);
00103 int result;
00104
00105 if (!(result=my_delete(name, MyFlags)))
00106 {
00107 if (was_symlink)
00108 {
00109 link_name[sym_link_size]= '\0';
00110 result= my_delete(link_name, MyFlags);
00111 }
00112 }
00113 return(result);
00114 }
00115
00116
00117
00118
00119
00120
00121
00122
00123
00124
00125
00126 int my_rename_with_symlink(const char *from, const char *to, myf MyFlags)
00127 {
00128 char link_name[FN_REFLEN], tmp_name[FN_REFLEN];
00129 int sym_link_size= -1;
00130 int was_symlink= (!my_disable_symlinks &&
00131 (sym_link_size= static_cast<int>(readlink(from,link_name,
00132 FN_REFLEN-1))) != -1);
00133 int result=0;
00134 int name_is_different;
00135
00136 if (!was_symlink)
00137 return(my_rename(from, to, MyFlags));
00138 else
00139 link_name[sym_link_size]= '\0';
00140
00141
00142 strcpy(tmp_name, to);
00143 fn_same(tmp_name,link_name,1);
00144 name_is_different= strcmp(link_name, tmp_name);
00145 if (name_is_different && !access(tmp_name, F_OK))
00146 {
00147 errno= EEXIST;
00148 if (MyFlags & MY_WME)
00149 my_error(EE_CANTCREATEFILE, MYF(0), tmp_name, EEXIST);
00150 return 1;
00151 }
00152
00153
00154 if (symlink(tmp_name, to))
00155 return 1;
00156 else if (MyFlags & MY_SYNC_DIR)
00157 my_sync_dir_by_file(to, MyFlags);
00158
00159
00160
00161
00162
00163
00164
00165 if (name_is_different && my_rename(link_name, tmp_name, MyFlags))
00166 {
00167 int save_errno=errno;
00168 my_delete(to, MyFlags);
00169 errno=save_errno;
00170 return 1;
00171 }
00172
00173
00174 if (my_delete(from, MyFlags))
00175 {
00176 int save_errno=errno;
00177
00178 my_delete(to, MyFlags);
00179
00180 if (strcmp(link_name, tmp_name))
00181 (void) my_rename(tmp_name, link_name, MyFlags);
00182 errno=save_errno;
00183 result= 1;
00184 }
00185 return(result);
00186 }
00187
00188 }
00189 }