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