~drizzle-trunk/drizzle/development

1 by brian
clean slate
1
/* Copyright (C) 2000 MySQL AB
2
3
   This program is free software; you can redistribute it and/or modify
4
   it under the terms of the GNU General Public License as published by
5
   the Free Software Foundation; version 2 of the License.
6
7
   This program is distributed in the hope that it will be useful,
8
   but WITHOUT ANY WARRANTY; without even the implied warranty of
9
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
10
   GNU General Public License for more details.
11
12
   You should have received a copy of the GNU General Public License
13
   along with this program; if not, write to the Free Software
14
   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */
15
994.2.4 by Monty Taylor
Blast. Fixed some make distcheck issues.
16
#include "mysys/mysys_priv.h"
212.5.18 by Monty Taylor
Moved m_ctype, m_string and my_bitmap. Removed t_ctype.
17
#include <mystrings/m_string.h>
53.2.7 by Monty Taylor
Changes so that removal of duplicate curr_dir from my_sys.h work.
18
#include "my_static.h"
1 by brian
clean slate
19
#ifdef HAVE_PWD_H
20
#include <pwd.h>
21
#endif
22
23
static char * expand_tilde(char * *path);
1165.1.126 by Stewart Smith
make system_filename() static to mysys/mf_pack.cc
24
static size_t system_filename(char * to, const char *from);
1 by brian
clean slate
25
26
/*
27
  remove unwanted chars from dirname
28
29
  SYNOPSIS
30
     cleanup_dirname()
31
     to		Store result here
32
     from	Dirname to fix.  May be same as to
33
34
  IMPLEMENTATION
35
  "/../" removes prev dir
36
  "/~/" removes all before ~
37
  //" is same as "/", except on Win32 at start of a file
38
  "/./" is removed
39
  Unpacks home_dir if "~/.." used
40
  Unpacks current dir if if "./.." used
41
42
  RETURN
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
43
    #  length of new name
1 by brian
clean slate
44
*/
45
1165.1.125 by Stewart Smith
make cleanup_dirname() static to mysys/mf_pack.cc
46
static size_t cleanup_dirname(register char *to, const char *from)
1 by brian
clean slate
47
{
48
  register size_t length;
49
  register char * pos;
266.7.15 by Andy Lester
Added a proper const qualifer.
50
  register const char * from_ptr;
1 by brian
clean slate
51
  register char * start;
52
  char parent[5],				/* for "FN_PARENTDIR" */
53
       buff[FN_REFLEN+1],*end_parentdir;
54
55
  start=buff;
266.7.15 by Andy Lester
Added a proper const qualifer.
56
  from_ptr= from;
1 by brian
clean slate
57
#ifdef FN_DEVCHAR
58
  if ((pos=strrchr(from_ptr,FN_DEVCHAR)) != 0)
59
  {						/* Skip device part */
60
    length=(size_t) (pos-from_ptr)+1;
670.3.1 by Toru Maesaka
Replaced MySQL's my_stpncpy() with libc and c++ calls
61
    start= strncpy(buff,from_ptr,length);
62
    start+= strlen(from_ptr);
63
    from_ptr+=length;
1 by brian
clean slate
64
  }
65
#endif
66
67
  parent[0]=FN_LIBCHAR;
641.4.2 by Toru Maesaka
Second pass of replacing MySQL's my_stpcpy() with appropriate libc calls
68
  length= (size_t)((strcpy(parent+1,FN_PARENTDIR)+strlen(FN_PARENTDIR))-parent);
1 by brian
clean slate
69
  for (pos=start ; (*pos= *from_ptr++) != 0 ; pos++)
70
  {
71
#ifdef BACKSLASH_MBTAIL
482 by Brian Aker
Remove uint.
72
    uint32_t l;
1 by brian
clean slate
73
    if (use_mb(fs) && (l= my_ismbchar(fs, from_ptr - 1, from_ptr + 2)))
74
    {
75
      for (l-- ; l ; *++pos= *from_ptr++, l--);
76
      start= pos + 1; /* Don't look inside multi-byte char */
77
      continue;
78
    }
79
#endif
80
    if (*pos == '/')
81
      *pos = FN_LIBCHAR;
82
    if (*pos == FN_LIBCHAR)
83
    {
212.6.3 by Mats Kindahl
Removing deprecated functions from code and replacing them with C99 equivalents:
84
      if ((size_t) (pos-start) > length &&
85
          memcmp(pos-length,parent,length) == 0)
1 by brian
clean slate
86
      {						/* If .../../; skip prev */
87
	pos-=length;
88
	if (pos != start)
89
	{					 /* not /../ */
90
	  pos--;
91
	  if (*pos == FN_HOMELIB && (pos == start || pos[-1] == FN_LIBCHAR))
92
	  {
93
	    if (!home_dir)
94
	    {
95
	      pos+=length+1;			/* Don't unpack ~/.. */
96
	      continue;
97
	    }
641.4.2 by Toru Maesaka
Second pass of replacing MySQL's my_stpcpy() with appropriate libc calls
98
	    pos= strcpy(buff,home_dir)+strlen(home_dir)-1;	/* Unpacks ~/.. */
1 by brian
clean slate
99
	    if (*pos == FN_LIBCHAR)
100
	      pos--;				/* home ended with '/' */
101
	  }
102
	  if (*pos == FN_CURLIB && (pos == start || pos[-1] == FN_LIBCHAR))
103
	  {
575.4.6 by Monty Taylor
Removed my_getwd.
104
	    if (getcwd(curr_dir,FN_REFLEN))
1 by brian
clean slate
105
	    {
106
	      pos+=length+1;			/* Don't unpack ./.. */
107
	      continue;
108
	    }
641.4.2 by Toru Maesaka
Second pass of replacing MySQL's my_stpcpy() with appropriate libc calls
109
	    pos= strcpy(buff,curr_dir)+strlen(curr_dir)-1;	/* Unpacks ./.. */
1 by brian
clean slate
110
	    if (*pos == FN_LIBCHAR)
111
	      pos--;				/* home ended with '/' */
112
	  }
113
	  end_parentdir=pos;
114
	  while (pos >= start && *pos != FN_LIBCHAR)	/* remove prev dir */
115
	    pos--;
212.6.3 by Mats Kindahl
Removing deprecated functions from code and replacing them with C99 equivalents:
116
	  if (pos[1] == FN_HOMELIB || memcmp(pos,parent,length) == 0)
1 by brian
clean slate
117
	  {					/* Don't remove ~user/ */
641.4.2 by Toru Maesaka
Second pass of replacing MySQL's my_stpcpy() with appropriate libc calls
118
	    pos= strcpy(end_parentdir+1,parent)+strlen(parent);
1 by brian
clean slate
119
	    *pos=FN_LIBCHAR;
120
	    continue;
121
	  }
122
	}
123
      }
124
      else if ((size_t) (pos-start) == length-1 &&
212.6.3 by Mats Kindahl
Removing deprecated functions from code and replacing them with C99 equivalents:
125
	       !memcmp(start,parent+1,length-1))
1 by brian
clean slate
126
	start=pos;				/* Starts with "../" */
127
      else if (pos-start > 0 && pos[-1] == FN_LIBCHAR)
128
      {
129
#ifdef FN_NETWORK_DRIVES
130
	if (pos-start != 1)
131
#endif
132
	  pos--;			/* Remove dupplicate '/' */
133
      }
134
      else if (pos-start > 1 && pos[-1] == FN_CURLIB && pos[-2] == FN_LIBCHAR)
135
	pos-=2;					/* Skip /./ */
136
      else if (pos > buff+1 && pos[-1] == FN_HOMELIB && pos[-2] == FN_LIBCHAR)
137
      {					/* Found ..../~/  */
138
	buff[0]=FN_HOMELIB;
139
	buff[1]=FN_LIBCHAR;
140
	start=buff; pos=buff+1;
141
      }
142
    }
143
  }
641.4.1 by Toru Maesaka
First pass of replacing MySQL's my_stpcpy() with appropriate libc calls
144
  (void) strcpy(to,buff);
51.3.21 by Jay Pipes
Phase 8 - Remove DBUG from mysys
145
  return((size_t) (pos-buff));
1 by brian
clean slate
146
} /* cleanup_dirname */
147
148
149
/*
150
  On system where you don't have symbolic links, the following
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
151
  code will allow you to create a file:
1 by brian
clean slate
152
  directory-name.sym that should contain the real path
153
  to the directory.  This will be used if the directory name
154
  doesn't exists
155
*/
156
157
146 by Brian Aker
my_bool cleanup.
158
bool my_use_symdir=0;	/* Set this if you want to use symdirs */
1 by brian
clean slate
159
160
161
/*
162
  Fixes a directroy name so that can be used by open()
163
164
  SYNOPSIS
165
    unpack_dirname()
166
    to			result-buffer, FN_REFLEN characters. may be == from
167
    from		'Packed' directory name (may contain ~)
168
169
 IMPLEMENTATION
170
  Make that last char of to is '/' if from not empty and
171
  from doesn't end in FN_DEVCHAR
172
  Uses cleanup_dirname and changes ~/.. to home_dir/..
173
174
  Changes a UNIX filename to system filename (replaces / with \ on windows)
175
176
  RETURN
177
   Length of new directory name (= length of to)
178
*/
179
180
size_t unpack_dirname(char * to, const char *from)
181
{
182
  size_t length, h_length;
183
  char buff[FN_REFLEN+1+4],*suffix,*tilde_expansion;
184
185
  (void) intern_filename(buff,from);	    /* Change to intern name */
186
  length= strlen(buff);                     /* Fix that '/' is last */
187
  if (length &&
188
#ifdef FN_DEVCHAR
189
      buff[length-1] != FN_DEVCHAR &&
190
#endif
191
      buff[length-1] != FN_LIBCHAR && buff[length-1] != '/')
192
  {
193
    buff[length]=FN_LIBCHAR;
194
    buff[length+1]= '\0';
195
  }
196
197
  length=cleanup_dirname(buff,buff);
198
  if (buff[0] == FN_HOMELIB)
199
  {
200
    suffix=buff+1; tilde_expansion=expand_tilde(&suffix);
201
    if (tilde_expansion)
202
    {
203
      length-= (size_t) (suffix-buff)-1;
204
      if (length+(h_length= strlen(tilde_expansion)) <= FN_REFLEN)
205
      {
206
	if (tilde_expansion[h_length-1] == FN_LIBCHAR)
207
	  h_length--;
208
	if (buff+h_length < suffix)
629.3.6 by Kristian Nielsen
A couple more fixes of previous bmove()->memcpy(), changed to
209
          memmove(buff+h_length, suffix, length);
1 by brian
clean slate
210
	else
481 by Brian Aker
Remove all of uchar.
211
	  bmove_upp((unsigned char*) buff+h_length+length, (unsigned char*) suffix+length, length);
629.3.6 by Kristian Nielsen
A couple more fixes of previous bmove()->memcpy(), changed to
212
        memmove(buff, tilde_expansion, h_length);
1 by brian
clean slate
213
      }
214
    }
215
  }
51.3.21 by Jay Pipes
Phase 8 - Remove DBUG from mysys
216
  return(system_filename(to,buff));	/* Fix for open */
1 by brian
clean slate
217
} /* unpack_dirname */
218
219
220
	/* Expand tilde to home or user-directory */
221
	/* Path is reset to point at FN_LIBCHAR after ~xxx */
222
223
static char * expand_tilde(char * *path)
224
{
225
  if (path[0][0] == FN_LIBCHAR)
226
    return home_dir;			/* ~/ expanded to home */
227
#ifdef HAVE_GETPWNAM
228
  {
229
    char *str,save;
230
    struct passwd *user_entry;
231
232
    if (!(str=strchr(*path,FN_LIBCHAR)))
376 by Brian Aker
strend remove
233
      str= strchr(*path, '\0');
1 by brian
clean slate
234
    save= *str; *str= '\0';
235
    user_entry=getpwnam(*path);
236
    *str=save;
237
    endpwent();
238
    if (user_entry)
239
    {
240
      *path=str;
241
      return user_entry->pw_dir;
242
    }
243
  }
244
#endif
266.6.8 by Andy Lester
use NULL, not 0
245
  return NULL;
1 by brian
clean slate
246
}
247
248
249
/*
250
  Fix filename so it can be used by open, create
251
252
  SYNOPSIS
253
    unpack_filename()
254
    to		Store result here. Must be at least of size FN_REFLEN.
255
    from	Filename in unix format (with ~)
256
257
  RETURN
258
    # length of to
259
260
  NOTES
261
    to may be == from
262
    ~ will only be expanded if total length < FN_REFLEN
263
*/
264
265
266
size_t unpack_filename(char * to, const char *from)
267
{
268
  size_t length, n_length, buff_length;
269
  char buff[FN_REFLEN];
270
271
  length=dirname_part(buff, from, &buff_length);/* copy & convert dirname */
272
  n_length=unpack_dirname(buff,buff);
273
  if (n_length+strlen(from+length) < FN_REFLEN)
274
  {
641.4.1 by Toru Maesaka
First pass of replacing MySQL's my_stpcpy() with appropriate libc calls
275
    (void) strcpy(buff+n_length,from+length);
1 by brian
clean slate
276
    length= system_filename(to,buff);		/* Fix to usably filename */
277
  }
278
  else
279
    length= system_filename(to,from);		/* Fix to usably filename */
51.3.21 by Jay Pipes
Phase 8 - Remove DBUG from mysys
280
  return(length);
1 by brian
clean slate
281
} /* unpack_filename */
282
283
284
	/* Convert filename (unix standard) to system standard */
285
	/* Used before system command's like open(), create() .. */
286
	/* Returns used length of to; total length should be FN_REFLEN */
287
1165.1.126 by Stewart Smith
make system_filename() static to mysys/mf_pack.cc
288
static size_t system_filename(char * to, const char *from)
1 by brian
clean slate
289
{
629.5.2 by Toru Maesaka
Second pass of replacing MySQL's strmake() with libc calls
290
  return strlen(strncpy(to,from,FN_REFLEN-1));
1 by brian
clean slate
291
} /* system_filename */
292
293
294
	/* Fix a filename to intern (UNIX format) */
295
296
char *intern_filename(char *to, const char *from)
297
{
298
  size_t length, to_length;
299
  char buff[FN_REFLEN];
300
  if (from == to)
301
  {						/* Dirname may destroy from */
641.4.1 by Toru Maesaka
First pass of replacing MySQL's my_stpcpy() with appropriate libc calls
302
    strcpy(buff,from);
1 by brian
clean slate
303
    from=buff;
304
  }
305
  length= dirname_part(to, from, &to_length);	/* Copy dirname & fix chars */
641.4.1 by Toru Maesaka
First pass of replacing MySQL's my_stpcpy() with appropriate libc calls
306
  (void) strcpy(to + to_length,from+length);
1 by brian
clean slate
307
  return (to);
308
} /* intern_filename */