12
12
You should have received a copy of the GNU General Public License
13
13
along with this program; if not, write to the Free Software
14
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */
18
#include <drizzled/internal/my_sys.h>
14
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
16
#include "mysys_priv.h"
18
#include "my_static.h"
22
#include <drizzled/internal/m_string.h>
23
#include "my_static.h"
30
28
static char * expand_tilde(char * *path);
31
static size_t system_filename(char * to, const char *from);
30
/* Pack a dirname ; Changes HOME to ~/ and current dev to ./ */
31
/* from is a dirname (from dirname() ?) ending with FN_LIBCHAR */
32
/* to may be == from */
34
void pack_dirname(char * to, const char *from)
37
size_t d_length,length,buff_length= 0;
40
DBUG_ENTER("pack_dirname");
42
(void) intern_filename(to,from); /* Change to intern name */
45
if ((start=strrchr(to,FN_DEVCHAR)) != 0) /* Skip device part */
51
if (!(cwd_err= my_getwd(buff,FN_REFLEN,MYF(0))))
53
buff_length= strlen(buff);
54
d_length= (size_t) (start-to);
56
(buff_length == d_length && !bcmp(buff,start,d_length))) &&
57
*start != FN_LIBCHAR && *start)
58
{ /* Put current dir before */
59
bchange((uchar*) to, d_length, (uchar*) buff, buff_length, strlen(to)+1);
63
if ((d_length= cleanup_dirname(to,to)) != 0)
68
length= strlen(home_dir);
69
if (home_dir[length-1] == FN_LIBCHAR)
70
length--; /* Don't test last '/' */
72
if (length > 1 && length < d_length)
73
{ /* test if /xx/yy -> ~/yy */
74
if (bcmp(to,home_dir,length) == 0 && to[length] == FN_LIBCHAR)
76
to[0]=FN_HOMELIB; /* Filename begins with ~ */
77
(void) strmov_overlapp(to+1,to+length);
81
{ /* Test if cwd is ~/... */
82
if (length > 1 && length < buff_length)
84
if (bcmp(buff,home_dir,length) == 0 && buff[length] == FN_LIBCHAR)
87
(void) strmov_overlapp(buff+1,buff+length);
90
if (is_prefix(to,buff))
94
(void) strmov_overlapp(to,to+length); /* Remove everything before */
97
to[0]= FN_CURLIB; /* Put ./ instead of cwd */
104
DBUG_PRINT("exit",("to: '%s'",to));
34
110
remove unwanted chars from dirname
47
123
Unpacks current dir if if "./.." used
53
static size_t cleanup_dirname(char *to, const char *from)
129
size_t cleanup_dirname(register char *to, const char *from)
57
const char * from_ptr;
131
register size_t length;
133
register char * from_ptr;
134
register char * start;
59
135
char parent[5], /* for "FN_PARENTDIR" */
60
136
buff[FN_REFLEN+1],*end_parentdir;
137
#ifdef BACKSLASH_MBTAIL
138
CHARSET_INFO *fs= fs_character_set();
140
DBUG_ENTER("cleanup_dirname");
141
DBUG_PRINT("enter",("from: '%s'",from));
144
from_ptr=(char *) from;
65
146
if ((pos=strrchr(from_ptr,FN_DEVCHAR)) != 0)
66
147
{ /* Skip device part */
67
148
length=(size_t) (pos-from_ptr)+1;
68
start= strncpy(buff,from_ptr,length);
69
start+= strlen(from_ptr);
149
start=strnmov(buff,from_ptr,length); from_ptr+=length;
74
153
parent[0]=FN_LIBCHAR;
75
length= (size_t)((strcpy(parent+1,FN_PARENTDIR)+strlen(FN_PARENTDIR))-parent);
154
length=(size_t) (strmov(parent+1,FN_PARENTDIR)-parent);
76
155
for (pos=start ; (*pos= *from_ptr++) != 0 ; pos++)
78
157
#ifdef BACKSLASH_MBTAIL
80
159
if (use_mb(fs) && (l= my_ismbchar(fs, from_ptr - 1, from_ptr + 2)))
82
161
for (l-- ; l ; *++pos= *from_ptr++, l--);
102
180
pos+=length+1; /* Don't unpack ~/.. */
105
pos= strcpy(buff,home_dir)+strlen(home_dir)-1; /* Unpacks ~/.. */
183
pos=strmov(buff,home_dir)-1; /* Unpacks ~/.. */
106
184
if (*pos == FN_LIBCHAR)
107
185
pos--; /* home ended with '/' */
109
187
if (*pos == FN_CURLIB && (pos == start || pos[-1] == FN_LIBCHAR))
111
if (getcwd(curr_dir,FN_REFLEN))
189
if (my_getwd(curr_dir,FN_REFLEN,MYF(0)))
113
191
pos+=length+1; /* Don't unpack ./.. */
116
pos= strcpy(buff,curr_dir)+strlen(curr_dir)-1; /* Unpacks ./.. */
194
pos=strmov(buff,curr_dir)-1; /* Unpacks ./.. */
117
195
if (*pos == FN_LIBCHAR)
118
196
pos--; /* home ended with '/' */
120
198
end_parentdir=pos;
121
199
while (pos >= start && *pos != FN_LIBCHAR) /* remove prev dir */
123
if (pos[1] == FN_HOMELIB || memcmp(pos,parent,length) == 0)
201
if (pos[1] == FN_HOMELIB || bcmp(pos,parent,length) == 0)
124
202
{ /* Don't remove ~user/ */
125
pos= strcpy(end_parentdir+1,parent)+strlen(parent);
203
pos=strmov(end_parentdir+1,parent);
131
209
else if ((size_t) (pos-start) == length-1 &&
132
!memcmp(start,parent+1,length-1))
210
!bcmp(start,parent+1,length-1))
133
211
start=pos; /* Starts with "../" */
134
212
else if (pos-start > 0 && pos[-1] == FN_LIBCHAR)
151
(void) strcpy(to,buff);
152
return((size_t) (pos-buff));
229
(void) strmov(to,buff);
230
DBUG_PRINT("exit",("to: '%s'",to));
231
DBUG_RETURN((size_t) (pos-buff));
153
232
} /* cleanup_dirname */
157
236
On system where you don't have symbolic links, the following
158
code will allow you to create a file:
237
code will allow you to create a file:
159
238
directory-name.sym that should contain the real path
160
239
to the directory. This will be used if the directory name
165
244
bool my_use_symdir=0; /* Set this if you want to use symdirs */
247
void symdirget(char *dir)
249
char buff[FN_REFLEN];
250
char *pos=strend(dir);
251
if (dir[0] && pos[-1] != FN_DEVCHAR && my_access(dir, F_OK))
255
char temp= *(--pos); /* May be "/" or "\" */
257
file= my_open(dir, O_RDONLY, MYF(0));
258
*pos++=temp; *pos=0; /* Restore old filename */
261
if ((length= my_read(file, buff, sizeof(buff), MYF(0))) > 0)
263
for (pos= buff + length ;
264
pos > buff && (iscntrl(pos[-1]) || isspace(pos[-1])) ;
267
/* Ensure that the symlink ends with the directory symbol */
268
if (pos == buff || pos[-1] != FN_LIBCHAR)
271
strmake(dir,buff, (size_t) (pos-buff));
273
my_close(file, MYF(0));
277
#endif /* USE_SYMDIR */
169
281
Fixes a directroy name so that can be used by open()
213
326
if (tilde_expansion[h_length-1] == FN_LIBCHAR)
215
328
if (buff+h_length < suffix)
216
memmove(buff+h_length, suffix, length);
329
bmove(buff+h_length,suffix,length);
218
bmove_upp((unsigned char*) buff+h_length+length, (unsigned char*) suffix+length, length);
219
memmove(buff, tilde_expansion, h_length);
331
bmove_upp((uchar*) buff+h_length+length, (uchar*) suffix+length, length);
332
bmove(buff,tilde_expansion,h_length);
223
return(system_filename(to,buff)); /* Fix for open */
340
DBUG_RETURN(system_filename(to,buff)); /* Fix for open */
224
341
} /* unpack_dirname */
232
349
if (path[0][0] == FN_LIBCHAR)
233
350
return home_dir; /* ~/ expanded to home */
235
struct passwd *user_entry;
237
if (!(str=strchr(*path,FN_LIBCHAR)))
238
str= strchr(*path, '\0');
239
save= *str; *str= '\0';
240
user_entry=getpwnam(*path);
246
return user_entry->pw_dir;
354
struct passwd *user_entry;
356
if (!(str=strchr(*path,FN_LIBCHAR)))
358
save= *str; *str= '\0';
359
user_entry=getpwnam(*path);
365
return user_entry->pw_dir;
271
392
size_t length, n_length, buff_length;
272
393
char buff[FN_REFLEN];
394
DBUG_ENTER("unpack_filename");
274
396
length=dirname_part(buff, from, &buff_length);/* copy & convert dirname */
275
397
n_length=unpack_dirname(buff,buff);
276
398
if (n_length+strlen(from+length) < FN_REFLEN)
278
(void) strcpy(buff+n_length,from+length);
400
(void) strmov(buff+n_length,from+length);
279
401
length= system_filename(to,buff); /* Fix to usably filename */
282
404
length= system_filename(to,from); /* Fix to usably filename */
284
406
} /* unpack_filename */
288
410
/* Used before system command's like open(), create() .. */
289
411
/* Returns used length of to; total length should be FN_REFLEN */
291
static size_t system_filename(char * to, const char *from)
413
size_t system_filename(char * to, const char *from)
293
return strlen(strncpy(to,from,FN_REFLEN-1));
415
#ifndef FN_C_BEFORE_DIR
416
return (size_t) (strmake(to,from,FN_REFLEN-1)-to);
419
/* change 'dev:lib/xxx' to 'dev:[lib]xxx' */
420
/* change 'dev:xxx' to 'dev:xxx' */
421
/* change './xxx' to 'xxx' */
422
/* change './lib/' or lib/ to '[.lib]' */
423
/* change '/x/y/z to '[x.y]x' */
424
/* change 'dev:/x' to 'dev:[000000]x' */
428
char * to_pos,from_pos,pos;
429
char buff[FN_REFLEN];
430
DBUG_ENTER("system_filename");
433
(void) strmov(buff,from); /* If to == from */
435
if ((pos=strrchr(from_pos,FN_DEVCHAR))) /* Skip device part */
438
to_pos=strnmov(to,from_pos,(size_t) (pos-from_pos));
444
if (from_pos[0] == FN_CURLIB && from_pos[1] == FN_LIBCHAR)
445
from_pos+=2; /* Skip './' */
446
if (strchr(from_pos,FN_LIBCHAR))
448
*(to_pos++) = FN_C_BEFORE_DIR;
449
if (strinstr(from_pos,FN_ROOTDIR) == 1)
451
from_pos+=strlen(FN_ROOTDIR); /* Actually +1 but... */
452
if (! strchr(from_pos,FN_LIBCHAR))
453
{ /* No dir, use [000000] */
454
to_pos=strmov(to_pos,FN_C_ROOT_DIR);
459
*(to_pos++)=FN_C_DIR_SEP; /* '.' gives current dir */
461
while ((pos=strchr(from_pos,FN_LIBCHAR)))
464
*(to_pos++)=FN_C_DIR_SEP; /* Add '.' between dirs */
465
if (strinstr(from_pos,FN_PARENTDIR) == 1 &&
466
from_pos+strlen(FN_PARENTDIR) == pos)
467
to_pos=strmov(to_pos,FN_C_PARENT_DIR); /* Found '../' */
469
to_pos=strnmov(to_pos,from_pos,(size_t) (pos-from_pos));
472
*(to_pos++)=FN_C_AFTER_DIR;
474
length= (size_t) (strmov(to_pos,from_pos)-to);
475
DBUG_PRINT("exit",("name: '%s'",to));
294
478
} /* system_filename */
302
486
char buff[FN_REFLEN];
304
488
{ /* Dirname may destroy from */
308
492
length= dirname_part(to, from, &to_length); /* Copy dirname & fix chars */
309
(void) strcpy(to + to_length,from+length);
493
(void) strmov(to + to_length,from+length);
311
495
} /* intern_filename */
313
} /* namespace internal */
314
} /* namespace drizzled */