14
14
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
16
16
#include "mysys_priv.h"
17
#include <mystrings/m_string.h>
18
#include "my_static.h"
23
27
static char * expand_tilde(char * *path);
29
/* Pack a dirname ; Changes HOME to ~/ and current dev to ./ */
30
/* from is a dirname (from dirname() ?) ending with FN_LIBCHAR */
31
/* to may be == from */
33
void pack_dirname(char * to, const char *from)
36
size_t d_length,length,buff_length= 0;
39
DBUG_ENTER("pack_dirname");
41
(void) intern_filename(to,from); /* Change to intern name */
44
if ((start=strrchr(to,FN_DEVCHAR)) != 0) /* Skip device part */
50
if (!(cwd_err= my_getwd(buff,FN_REFLEN,MYF(0))))
52
buff_length= strlen(buff);
53
d_length= (size_t) (start-to);
55
(buff_length == d_length && !bcmp(buff,start,d_length))) &&
56
*start != FN_LIBCHAR && *start)
57
{ /* Put current dir before */
58
bchange((uchar*) to, d_length, (uchar*) buff, buff_length, strlen(to)+1);
62
if ((d_length= cleanup_dirname(to,to)) != 0)
67
length= strlen(home_dir);
68
if (home_dir[length-1] == FN_LIBCHAR)
69
length--; /* Don't test last '/' */
71
if (length > 1 && length < d_length)
72
{ /* test if /xx/yy -> ~/yy */
73
if (bcmp(to,home_dir,length) == 0 && to[length] == FN_LIBCHAR)
75
to[0]=FN_HOMELIB; /* Filename begins with ~ */
76
(void) strmov_overlapp(to+1,to+length);
80
{ /* Test if cwd is ~/... */
81
if (length > 1 && length < buff_length)
83
if (bcmp(buff,home_dir,length) == 0 && buff[length] == FN_LIBCHAR)
86
(void) strmov_overlapp(buff+1,buff+length);
89
if (is_prefix(to,buff))
93
(void) strmov_overlapp(to,to+length); /* Remove everything before */
96
to[0]= FN_CURLIB; /* Put ./ instead of cwd */
103
DBUG_PRINT("exit",("to: '%s'",to));
27
109
remove unwanted chars from dirname
40
122
Unpacks current dir if if "./.." used
46
128
size_t cleanup_dirname(register char *to, const char *from)
48
130
register size_t length;
49
131
register char * pos;
50
register const char * from_ptr;
132
register char * from_ptr;
51
133
register char * start;
52
134
char parent[5], /* for "FN_PARENTDIR" */
53
135
buff[FN_REFLEN+1],*end_parentdir;
54
136
#ifdef BACKSLASH_MBTAIL
55
137
CHARSET_INFO *fs= fs_character_set();
139
DBUG_ENTER("cleanup_dirname");
140
DBUG_PRINT("enter",("from: '%s'",from));
143
from_ptr=(char *) from;
61
145
if ((pos=strrchr(from_ptr,FN_DEVCHAR)) != 0)
62
146
{ /* Skip device part */
63
147
length=(size_t) (pos-from_ptr)+1;
64
start= strncpy(buff,from_ptr,length);
65
start+= strlen(from_ptr);
148
start=strnmov(buff,from_ptr,length); from_ptr+=length;
70
152
parent[0]=FN_LIBCHAR;
71
length= (size_t)((strcpy(parent+1,FN_PARENTDIR)+strlen(FN_PARENTDIR))-parent);
153
length=(size_t) (strmov(parent+1,FN_PARENTDIR)-parent);
72
154
for (pos=start ; (*pos= *from_ptr++) != 0 ; pos++)
74
156
#ifdef BACKSLASH_MBTAIL
76
158
if (use_mb(fs) && (l= my_ismbchar(fs, from_ptr - 1, from_ptr + 2)))
78
160
for (l-- ; l ; *++pos= *from_ptr++, l--);
98
179
pos+=length+1; /* Don't unpack ~/.. */
101
pos= strcpy(buff,home_dir)+strlen(home_dir)-1; /* Unpacks ~/.. */
182
pos=strmov(buff,home_dir)-1; /* Unpacks ~/.. */
102
183
if (*pos == FN_LIBCHAR)
103
184
pos--; /* home ended with '/' */
105
186
if (*pos == FN_CURLIB && (pos == start || pos[-1] == FN_LIBCHAR))
107
if (getcwd(curr_dir,FN_REFLEN))
188
if (my_getwd(curr_dir,FN_REFLEN,MYF(0)))
109
190
pos+=length+1; /* Don't unpack ./.. */
112
pos= strcpy(buff,curr_dir)+strlen(curr_dir)-1; /* Unpacks ./.. */
193
pos=strmov(buff,curr_dir)-1; /* Unpacks ./.. */
113
194
if (*pos == FN_LIBCHAR)
114
195
pos--; /* home ended with '/' */
116
197
end_parentdir=pos;
117
198
while (pos >= start && *pos != FN_LIBCHAR) /* remove prev dir */
119
if (pos[1] == FN_HOMELIB || memcmp(pos,parent,length) == 0)
200
if (pos[1] == FN_HOMELIB || bcmp(pos,parent,length) == 0)
120
201
{ /* Don't remove ~user/ */
121
pos= strcpy(end_parentdir+1,parent)+strlen(parent);
202
pos=strmov(end_parentdir+1,parent);
127
208
else if ((size_t) (pos-start) == length-1 &&
128
!memcmp(start,parent+1,length-1))
209
!bcmp(start,parent+1,length-1))
129
210
start=pos; /* Starts with "../" */
130
211
else if (pos-start > 0 && pos[-1] == FN_LIBCHAR)
147
(void) strcpy(to,buff);
148
return((size_t) (pos-buff));
228
(void) strmov(to,buff);
229
DBUG_PRINT("exit",("to: '%s'",to));
230
DBUG_RETURN((size_t) (pos-buff));
149
231
} /* cleanup_dirname */
153
235
On system where you don't have symbolic links, the following
154
code will allow you to create a file:
236
code will allow you to create a file:
155
237
directory-name.sym that should contain the real path
156
238
to the directory. This will be used if the directory name
161
bool my_use_symdir=0; /* Set this if you want to use symdirs */
243
my_bool my_use_symdir=0; /* Set this if you want to use symdirs */
163
245
#ifdef USE_SYMDIR
164
246
void symdirget(char *dir)
166
248
char buff[FN_REFLEN];
167
char *pos= strchr(dir, '\0');
249
char *pos=strend(dir);
168
250
if (dir[0] && pos[-1] != FN_DEVCHAR && my_access(dir, F_OK))
172
254
char temp= *(--pos); /* May be "/" or "\" */
174
256
file= my_open(dir, O_RDONLY, MYF(0));
175
257
*pos++=temp; *pos=0; /* Restore old filename */
178
260
if ((length= my_read(file, buff, sizeof(buff), MYF(0))) > 0)
180
for (pos= buff + length ;
181
pos > buff && (iscntrl(pos[-1]) || isspace(pos[-1])) ;
184
/* Ensure that the symlink ends with the directory symbol */
185
if (pos == buff || pos[-1] != FN_LIBCHAR)
188
strncpy(dir,buff, FN_REFLEN-1);
262
for (pos= buff + length ;
263
pos > buff && (iscntrl(pos[-1]) || isspace(pos[-1])) ;
266
/* Ensure that the symlink ends with the directory symbol */
267
if (pos == buff || pos[-1] != FN_LIBCHAR)
270
strmake(dir,buff, (size_t) (pos-buff));
190
272
my_close(file, MYF(0));
242
325
if (tilde_expansion[h_length-1] == FN_LIBCHAR)
244
327
if (buff+h_length < suffix)
245
memmove(buff+h_length, suffix, length);
328
bmove(buff+h_length,suffix,length);
247
bmove_upp((unsigned char*) buff+h_length+length, (unsigned char*) suffix+length, length);
248
memmove(buff, tilde_expansion, h_length);
330
bmove_upp((uchar*) buff+h_length+length, (uchar*) suffix+length, length);
331
bmove(buff,tilde_expansion,h_length);
308
391
size_t length, n_length, buff_length;
309
392
char buff[FN_REFLEN];
393
DBUG_ENTER("unpack_filename");
311
395
length=dirname_part(buff, from, &buff_length);/* copy & convert dirname */
312
396
n_length=unpack_dirname(buff,buff);
313
397
if (n_length+strlen(from+length) < FN_REFLEN)
315
(void) strcpy(buff+n_length,from+length);
399
(void) strmov(buff+n_length,from+length);
316
400
length= system_filename(to,buff); /* Fix to usably filename */
319
403
length= system_filename(to,from); /* Fix to usably filename */
321
405
} /* unpack_filename */
328
412
size_t system_filename(char * to, const char *from)
330
414
#ifndef FN_C_BEFORE_DIR
331
return strlen(strncpy(to,from,FN_REFLEN-1));
415
return (size_t) (strmake(to,from,FN_REFLEN-1)-to);
334
418
/* change 'dev:lib/xxx' to 'dev:[lib]xxx' */
343
427
char * to_pos,from_pos,pos;
344
428
char buff[FN_REFLEN];
429
DBUG_ENTER("system_filename");
347
(void) strcpy(buff,from); /* If to == from */
432
(void) strmov(buff,from); /* If to == from */
349
434
if ((pos=strrchr(from_pos,FN_DEVCHAR))) /* Skip device part */
352
to_pos= strncpy(to,from_pos,(size_t) (pos-from_pos));
437
to_pos=strnmov(to,from_pos,(size_t) (pos-from_pos));
361
445
if (strchr(from_pos,FN_LIBCHAR))
363
447
*(to_pos++) = FN_C_BEFORE_DIR;
364
if (strstr(from_pos,FN_ROOTDIR) == from_pos)
448
if (strinstr(from_pos,FN_ROOTDIR) == 1)
366
450
from_pos+=strlen(FN_ROOTDIR); /* Actually +1 but... */
367
451
if (! strchr(from_pos,FN_LIBCHAR))
368
452
{ /* No dir, use [000000] */
369
to_pos= strcpy(to_pos,FN_C_ROOT_DIR)+strlen(FN_C_ROOT_DIR);
453
to_pos=strmov(to_pos,FN_C_ROOT_DIR);
376
460
while ((pos=strchr(from_pos,FN_LIBCHAR)))
378
462
if (libchar_found++)
379
*(to_pos++)=FN_C_DIR_SEP; /* Add '.' between dirs */
380
if (strstr(from_pos,FN_PARENTDIR) == from_pos &&
381
from_pos+strlen(FN_PARENTDIR) == pos) {
382
to_pos= strcpy(to_pos,FN_C_PARENT_DIR); /* Found '../' */
383
to_pos+= strlen(FN_C_PARENT_DIR);
463
*(to_pos++)=FN_C_DIR_SEP; /* Add '.' between dirs */
464
if (strinstr(from_pos,FN_PARENTDIR) == 1 &&
465
from_pos+strlen(FN_PARENTDIR) == pos)
466
to_pos=strmov(to_pos,FN_C_PARENT_DIR); /* Found '../' */
387
to_pos= strncpy(to_pos,from_pos,(size_t) (pos-from_pos));
388
to_pos+= strlen(to_pos);
468
to_pos=strnmov(to_pos,from_pos,(size_t) (pos-from_pos));
392
471
*(to_pos++)=FN_C_AFTER_DIR;
395
strcpy(to_pos, from_pos);
473
length= (size_t) (strmov(to_pos,from_pos)-to);
474
DBUG_PRINT("exit",("name: '%s'",to));
399
477
} /* system_filename */