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