00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016 #include <config.h>
00017
00018 #include <drizzled/internal/my_sys.h>
00019
00020 #include <pwd.h>
00021
00022 #include <drizzled/internal/m_string.h>
00023 #include "my_static.h"
00024
00025 namespace drizzled
00026 {
00027 namespace internal
00028 {
00029
00030 static char * expand_tilde(char * *path);
00031 static size_t system_filename(char * to, const char *from);
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053 static size_t cleanup_dirname(char *to, const char *from)
00054 {
00055 size_t length;
00056 char * pos;
00057 const char * from_ptr;
00058 char * start;
00059 char parent[5],
00060 buff[FN_REFLEN+1],*end_parentdir;
00061
00062 start=buff;
00063 from_ptr= from;
00064 #ifdef FN_DEVCHAR
00065 if ((pos=strrchr(from_ptr,FN_DEVCHAR)) != 0)
00066 {
00067 length=(size_t) (pos-from_ptr)+1;
00068 start= strncpy(buff,from_ptr,length);
00069 start+= strlen(from_ptr);
00070 from_ptr+=length;
00071 }
00072 #endif
00073
00074 parent[0]=FN_LIBCHAR;
00075 length= (size_t)((strcpy(parent+1,FN_PARENTDIR)+strlen(FN_PARENTDIR))-parent);
00076 for (pos=start ; (*pos= *from_ptr++) != 0 ; pos++)
00077 {
00078 #ifdef BACKSLASH_MBTAIL
00079 uint32_t l;
00080 if (use_mb(fs) && (l= my_ismbchar(fs, from_ptr - 1, from_ptr + 2)))
00081 {
00082 for (l-- ; l ; *++pos= *from_ptr++, l--);
00083 start= pos + 1;
00084 continue;
00085 }
00086 #endif
00087 if (*pos == '/')
00088 *pos = FN_LIBCHAR;
00089 if (*pos == FN_LIBCHAR)
00090 {
00091 if ((size_t) (pos-start) > length &&
00092 memcmp(pos-length,parent,length) == 0)
00093 {
00094 pos-=length;
00095 if (pos != start)
00096 {
00097 pos--;
00098 if (*pos == FN_HOMELIB && (pos == start || pos[-1] == FN_LIBCHAR))
00099 {
00100 if (!home_dir)
00101 {
00102 pos+=length+1;
00103 continue;
00104 }
00105 pos= strcpy(buff,home_dir)+strlen(home_dir)-1;
00106 if (*pos == FN_LIBCHAR)
00107 pos--;
00108 }
00109 if (*pos == FN_CURLIB && (pos == start || pos[-1] == FN_LIBCHAR))
00110 {
00111 if (getcwd(curr_dir,FN_REFLEN))
00112 {
00113 pos+=length+1;
00114 continue;
00115 }
00116 pos= strcpy(buff,curr_dir)+strlen(curr_dir)-1;
00117 if (*pos == FN_LIBCHAR)
00118 pos--;
00119 }
00120 end_parentdir=pos;
00121 while (pos >= start && *pos != FN_LIBCHAR)
00122 pos--;
00123 if (pos[1] == FN_HOMELIB || memcmp(pos,parent,length) == 0)
00124 {
00125 pos= strcpy(end_parentdir+1,parent)+strlen(parent);
00126 *pos=FN_LIBCHAR;
00127 continue;
00128 }
00129 }
00130 }
00131 else if ((size_t) (pos-start) == length-1 &&
00132 !memcmp(start,parent+1,length-1))
00133 start=pos;
00134 else if (pos-start > 0 && pos[-1] == FN_LIBCHAR)
00135 {
00136 #ifdef FN_NETWORK_DRIVES
00137 if (pos-start != 1)
00138 #endif
00139 pos--;
00140 }
00141 else if (pos-start > 1 && pos[-1] == FN_CURLIB && pos[-2] == FN_LIBCHAR)
00142 pos-=2;
00143 else if (pos > buff+1 && pos[-1] == FN_HOMELIB && pos[-2] == FN_LIBCHAR)
00144 {
00145 buff[0]=FN_HOMELIB;
00146 buff[1]=FN_LIBCHAR;
00147 start=buff; pos=buff+1;
00148 }
00149 }
00150 }
00151 (void) strcpy(to,buff);
00152 return((size_t) (pos-buff));
00153 }
00154
00155
00156
00157
00158
00159
00160
00161
00162
00163
00164
00165 bool my_use_symdir=0;
00166
00167
00168
00169
00170
00171
00172
00173
00174
00175
00176
00177
00178
00179
00180
00181
00182
00183
00184
00185
00186
00187 size_t unpack_dirname(char * to, const char *from)
00188 {
00189 size_t length, h_length;
00190 char buff[FN_REFLEN+1+4],*suffix,*tilde_expansion;
00191
00192 (void) intern_filename(buff,from);
00193 length= strlen(buff);
00194 if (length &&
00195 #ifdef FN_DEVCHAR
00196 buff[length-1] != FN_DEVCHAR &&
00197 #endif
00198 buff[length-1] != FN_LIBCHAR && buff[length-1] != '/')
00199 {
00200 buff[length]=FN_LIBCHAR;
00201 buff[length+1]= '\0';
00202 }
00203
00204 length=cleanup_dirname(buff,buff);
00205 if (buff[0] == FN_HOMELIB)
00206 {
00207 suffix=buff+1; tilde_expansion=expand_tilde(&suffix);
00208 if (tilde_expansion)
00209 {
00210 length-= (size_t) (suffix-buff)-1;
00211 if (length+(h_length= strlen(tilde_expansion)) <= FN_REFLEN)
00212 {
00213 if (tilde_expansion[h_length-1] == FN_LIBCHAR)
00214 h_length--;
00215 if (buff+h_length < suffix)
00216 memmove(buff+h_length, suffix, length);
00217 else
00218 bmove_upp((unsigned char*) buff+h_length+length, (unsigned char*) suffix+length, length);
00219 memmove(buff, tilde_expansion, h_length);
00220 }
00221 }
00222 }
00223 return(system_filename(to,buff));
00224 }
00225
00226
00227
00228
00229
00230 static char * expand_tilde(char * *path)
00231 {
00232 if (path[0][0] == FN_LIBCHAR)
00233 return home_dir;
00234 char *str,save;
00235 struct passwd *user_entry;
00236
00237 if (!(str=strchr(*path,FN_LIBCHAR)))
00238 str= strchr(*path, '\0');
00239 save= *str; *str= '\0';
00240 user_entry=getpwnam(*path);
00241 *str=save;
00242 endpwent();
00243 if (user_entry)
00244 {
00245 *path=str;
00246 return user_entry->pw_dir;
00247 }
00248 return NULL;
00249 }
00250
00251
00252
00253
00254
00255
00256
00257
00258
00259
00260
00261
00262
00263
00264
00265
00266
00267
00268
00269 size_t unpack_filename(char * to, const char *from)
00270 {
00271 size_t length, n_length, buff_length;
00272 char buff[FN_REFLEN];
00273
00274 length=dirname_part(buff, from, &buff_length);
00275 n_length=unpack_dirname(buff,buff);
00276 if (n_length+strlen(from+length) < FN_REFLEN)
00277 {
00278 (void) strcpy(buff+n_length,from+length);
00279 length= system_filename(to,buff);
00280 }
00281 else
00282 length= system_filename(to,from);
00283 return(length);
00284 }
00285
00286
00287
00288
00289
00290
00291 static size_t system_filename(char * to, const char *from)
00292 {
00293 return strlen(strncpy(to,from,FN_REFLEN-1));
00294 }
00295
00296
00297
00298
00299 char *intern_filename(char *to, const char *from)
00300 {
00301 size_t length, to_length;
00302 char buff[FN_REFLEN];
00303 if (from == to)
00304 {
00305 strcpy(buff,from);
00306 from=buff;
00307 }
00308 length= dirname_part(to, from, &to_length);
00309 (void) strcpy(to + to_length,from+length);
00310 return (to);
00311 }
00312
00313 }
00314 }