~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
1280.1.10 by Monty Taylor
Put everything in drizzled into drizzled namespace.
16
#include "config.h"
17
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
1241.9.64 by Monty Taylor
Moved remaining non-public portions of mysys and mystrings to drizzled/internal.
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
1165.1.125 by Stewart Smith
make cleanup_dirname() static to mysys/mf_pack.cc
53
static size_t cleanup_dirname(register char *to, const char *from)
1 by brian
clean slate
54
{
55
  register size_t length;
56
  register char * pos;
266.7.15 by Andy Lester
Added a proper const qualifer.
57
  register const char * from_ptr;
1 by brian
clean slate
58
  register char * start;
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 */