~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/internal/mf_pack.cc

  • Committer: Brian Aker
  • Date: 2010-05-27 01:25:56 UTC
  • mfrom: (1567.1.4 new-staging)
  • Revision ID: brian@gaz-20100527012556-5zgkirkl7swbigd6
Merge of Brian, Paul. PBXT compile issue, and test framework cleanup. 

Show diffs side-by-side

added added

removed removed

Lines of Context:
13
13
   along with this program; if not, write to the Free Software
14
14
   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */
15
15
 
16
 
#include "mysys_priv.h"
17
 
#include <mystrings/m_string.h>
 
16
#include "config.h"
 
17
 
 
18
#include "drizzled/internal/my_sys.h"
 
19
 
 
20
#include <pwd.h>
 
21
 
 
22
#include "drizzled/internal/m_string.h"
18
23
#include "my_static.h"
19
 
#ifdef HAVE_PWD_H
20
 
#include <pwd.h>
21
 
#endif
22
 
#ifdef VMS
23
 
#include <rms.h>
24
 
#include <iodef.h>
25
 
#include <descrip.h>
26
 
#endif /* VMS */
 
24
 
 
25
namespace drizzled
 
26
{
 
27
namespace internal
 
28
{
27
29
 
28
30
static char * expand_tilde(char * *path);
29
 
 
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 */
33
 
 
34
 
void pack_dirname(char * to, const char *from)
35
 
{
36
 
  int cwd_err;
37
 
  size_t d_length,length,buff_length= 0;
38
 
  char * start;
39
 
  char buff[FN_REFLEN];
40
 
 
41
 
  (void) intern_filename(to,from);              /* Change to intern name */
42
 
 
43
 
#ifdef FN_DEVCHAR
44
 
  if ((start=strrchr(to,FN_DEVCHAR)) != 0)      /* Skip device part */
45
 
    start++;
46
 
  else
47
 
#endif
48
 
    start=to;
49
 
 
50
 
  if (!(cwd_err= my_getwd(buff,FN_REFLEN,MYF(0))))
51
 
  {
52
 
    buff_length= strlen(buff);
53
 
    d_length= (size_t) (start-to);
54
 
    if ((start == to ||
55
 
         (buff_length == d_length && !memcmp(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);
59
 
    }
60
 
  }
61
 
 
62
 
  if ((d_length= cleanup_dirname(to,to)) != 0)
63
 
  {
64
 
    length=0;
65
 
    if (home_dir)
66
 
    {
67
 
      length= strlen(home_dir);
68
 
      if (home_dir[length-1] == FN_LIBCHAR)
69
 
        length--;                               /* Don't test last '/' */
70
 
    }
71
 
    if (length > 1 && length < d_length)
72
 
    {                                           /* test if /xx/yy -> ~/yy */
73
 
      if (memcmp(to,home_dir,length) == 0 && to[length] == FN_LIBCHAR)
74
 
      {
75
 
        to[0]=FN_HOMELIB;                       /* Filename begins with ~ */
76
 
        (void) strmov_overlapp(to+1,to+length);
77
 
      }
78
 
    }
79
 
    if (! cwd_err)
80
 
    {                                           /* Test if cwd is ~/... */
81
 
      if (length > 1 && length < buff_length)
82
 
      {
83
 
        if (memcmp(buff,home_dir,length) == 0 && buff[length] == FN_LIBCHAR)
84
 
        {
85
 
          buff[0]=FN_HOMELIB;
86
 
          (void) strmov_overlapp(buff+1,buff+length);
87
 
        }
88
 
      }
89
 
      if (is_prefix(to,buff))
90
 
      {
91
 
        length= strlen(buff);
92
 
        if (to[length])
93
 
          (void) strmov_overlapp(to,to+length); /* Remove everything before */
94
 
        else
95
 
        {
96
 
          to[0]= FN_CURLIB;                     /* Put ./ instead of cwd */
97
 
          to[1]= FN_LIBCHAR;
98
 
          to[2]= '\0';
99
 
        }
100
 
      }
101
 
    }
102
 
  }
103
 
  return;
104
 
} /* pack_dirname */
105
 
 
 
31
static size_t system_filename(char * to, const char *from);
106
32
 
107
33
/*
108
34
  remove unwanted chars from dirname
121
47
  Unpacks current dir if if "./.." used
122
48
 
123
49
  RETURN
124
 
    #  length of new name   
 
50
    #  length of new name
125
51
*/
126
52
 
127
 
size_t cleanup_dirname(register char *to, const char *from)
 
53
static size_t cleanup_dirname(register char *to, const char *from)
128
54
{
129
55
  register size_t length;
130
56
  register char * pos;
132
58
  register char * start;
133
59
  char parent[5],                               /* for "FN_PARENTDIR" */
134
60
       buff[FN_REFLEN+1],*end_parentdir;
135
 
#ifdef BACKSLASH_MBTAIL
136
 
  CHARSET_INFO *fs= fs_character_set();
137
 
#endif
138
61
 
139
62
  start=buff;
140
63
  from_ptr= from;
142
65
  if ((pos=strrchr(from_ptr,FN_DEVCHAR)) != 0)
143
66
  {                                             /* Skip device part */
144
67
    length=(size_t) (pos-from_ptr)+1;
145
 
    start=stpncpy(buff,from_ptr,length); from_ptr+=length;
 
68
    start= strncpy(buff,from_ptr,length);
 
69
    start+= strlen(from_ptr);
 
70
    from_ptr+=length;
146
71
  }
147
72
#endif
148
73
 
149
74
  parent[0]=FN_LIBCHAR;
150
 
  length=(size_t) (stpcpy(parent+1,FN_PARENTDIR)-parent);
 
75
  length= (size_t)((strcpy(parent+1,FN_PARENTDIR)+strlen(FN_PARENTDIR))-parent);
151
76
  for (pos=start ; (*pos= *from_ptr++) != 0 ; pos++)
152
77
  {
153
78
#ifdef BACKSLASH_MBTAIL
154
 
    uint l;
 
79
    uint32_t l;
155
80
    if (use_mb(fs) && (l= my_ismbchar(fs, from_ptr - 1, from_ptr + 2)))
156
81
    {
157
82
      for (l-- ; l ; *++pos= *from_ptr++, l--);
177
102
              pos+=length+1;                    /* Don't unpack ~/.. */
178
103
              continue;
179
104
            }
180
 
            pos=stpcpy(buff,home_dir)-1;        /* Unpacks ~/.. */
 
105
            pos= strcpy(buff,home_dir)+strlen(home_dir)-1;      /* Unpacks ~/.. */
181
106
            if (*pos == FN_LIBCHAR)
182
107
              pos--;                            /* home ended with '/' */
183
108
          }
184
109
          if (*pos == FN_CURLIB && (pos == start || pos[-1] == FN_LIBCHAR))
185
110
          {
186
 
            if (my_getwd(curr_dir,FN_REFLEN,MYF(0)))
 
111
            if (getcwd(curr_dir,FN_REFLEN))
187
112
            {
188
113
              pos+=length+1;                    /* Don't unpack ./.. */
189
114
              continue;
190
115
            }
191
 
            pos=stpcpy(buff,curr_dir)-1;        /* Unpacks ./.. */
 
116
            pos= strcpy(buff,curr_dir)+strlen(curr_dir)-1;      /* Unpacks ./.. */
192
117
            if (*pos == FN_LIBCHAR)
193
118
              pos--;                            /* home ended with '/' */
194
119
          }
197
122
            pos--;
198
123
          if (pos[1] == FN_HOMELIB || memcmp(pos,parent,length) == 0)
199
124
          {                                     /* Don't remove ~user/ */
200
 
            pos=stpcpy(end_parentdir+1,parent);
 
125
            pos= strcpy(end_parentdir+1,parent)+strlen(parent);
201
126
            *pos=FN_LIBCHAR;
202
127
            continue;
203
128
          }
223
148
      }
224
149
    }
225
150
  }
226
 
  (void) stpcpy(to,buff);
 
151
  (void) strcpy(to,buff);
227
152
  return((size_t) (pos-buff));
228
153
} /* cleanup_dirname */
229
154
 
230
155
 
231
156
/*
232
157
  On system where you don't have symbolic links, the following
233
 
  code will allow you to create a file: 
 
158
  code will allow you to create a file:
234
159
  directory-name.sym that should contain the real path
235
160
  to the directory.  This will be used if the directory name
236
161
  doesn't exists
239
164
 
240
165
bool my_use_symdir=0;   /* Set this if you want to use symdirs */
241
166
 
242
 
#ifdef USE_SYMDIR
243
 
void symdirget(char *dir)
244
 
{
245
 
  char buff[FN_REFLEN];
246
 
  char *pos=strend(dir);
247
 
  if (dir[0] && pos[-1] != FN_DEVCHAR && my_access(dir, F_OK))
248
 
  {
249
 
    File file;
250
 
    size_t length;
251
 
    char temp= *(--pos);            /* May be "/" or "\" */
252
 
    stpcpy(pos,".sym");
253
 
    file= my_open(dir, O_RDONLY, MYF(0));
254
 
    *pos++=temp; *pos=0;          /* Restore old filename */
255
 
    if (file >= 0)
256
 
    {
257
 
      if ((length= my_read(file, buff, sizeof(buff), MYF(0))) > 0)
258
 
      {
259
 
        for (pos= buff + length ;
260
 
             pos > buff && (iscntrl(pos[-1]) || isspace(pos[-1])) ;
261
 
             pos --);
262
 
 
263
 
        /* Ensure that the symlink ends with the directory symbol */
264
 
        if (pos == buff || pos[-1] != FN_LIBCHAR)
265
 
          *pos++=FN_LIBCHAR;
266
 
 
267
 
        strmake(dir,buff, (size_t) (pos-buff));
268
 
      }
269
 
      my_close(file, MYF(0));
270
 
    }
271
 
  }
272
 
}
273
 
#endif /* USE_SYMDIR */
274
 
 
275
167
 
276
168
/*
277
169
  Fixes a directroy name so that can be used by open()
321
213
        if (tilde_expansion[h_length-1] == FN_LIBCHAR)
322
214
          h_length--;
323
215
        if (buff+h_length < suffix)
324
 
          memcpy(buff+h_length, suffix, length);
 
216
          memmove(buff+h_length, suffix, length);
325
217
        else
326
 
          bmove_upp((uchar*) buff+h_length+length, (uchar*) suffix+length, length);
327
 
        memcpy(buff, tilde_expansion, h_length);
 
218
          bmove_upp((unsigned char*) buff+h_length+length, (unsigned char*) suffix+length, length);
 
219
        memmove(buff, tilde_expansion, h_length);
328
220
      }
329
221
    }
330
222
  }
331
 
#ifdef USE_SYMDIR
332
 
  if (my_use_symdir)
333
 
    symdirget(buff);
334
 
#endif
335
223
  return(system_filename(to,buff));     /* Fix for open */
336
224
} /* unpack_dirname */
337
225
 
343
231
{
344
232
  if (path[0][0] == FN_LIBCHAR)
345
233
    return home_dir;                    /* ~/ expanded to home */
346
 
#ifdef HAVE_GETPWNAM
 
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)
347
244
  {
348
 
    char *str,save;
349
 
    struct passwd *user_entry;
350
 
 
351
 
    if (!(str=strchr(*path,FN_LIBCHAR)))
352
 
      str=strend(*path);
353
 
    save= *str; *str= '\0';
354
 
    user_entry=getpwnam(*path);
355
 
    *str=save;
356
 
    endpwent();
357
 
    if (user_entry)
358
 
    {
359
 
      *path=str;
360
 
      return user_entry->pw_dir;
361
 
    }
 
245
    *path=str;
 
246
    return user_entry->pw_dir;
362
247
  }
363
 
#endif
364
248
  return NULL;
365
249
}
366
250
 
391
275
  n_length=unpack_dirname(buff,buff);
392
276
  if (n_length+strlen(from+length) < FN_REFLEN)
393
277
  {
394
 
    (void) stpcpy(buff+n_length,from+length);
 
278
    (void) strcpy(buff+n_length,from+length);
395
279
    length= system_filename(to,buff);           /* Fix to usably filename */
396
280
  }
397
281
  else
404
288
        /* Used before system command's like open(), create() .. */
405
289
        /* Returns used length of to; total length should be FN_REFLEN */
406
290
 
407
 
size_t system_filename(char * to, const char *from)
 
291
static size_t system_filename(char * to, const char *from)
408
292
{
409
 
#ifndef FN_C_BEFORE_DIR
410
 
  return (size_t) (strmake(to,from,FN_REFLEN-1)-to);
411
 
#else   /* VMS */
412
 
 
413
 
        /* change 'dev:lib/xxx' to 'dev:[lib]xxx' */
414
 
        /* change 'dev:xxx' to 'dev:xxx' */
415
 
        /* change './xxx' to 'xxx' */
416
 
        /* change './lib/' or lib/ to '[.lib]' */
417
 
        /* change '/x/y/z to '[x.y]x' */
418
 
        /* change 'dev:/x' to 'dev:[000000]x' */
419
 
 
420
 
  int libchar_found;
421
 
  size_t length;
422
 
  char * to_pos,from_pos,pos;
423
 
  char buff[FN_REFLEN];
424
 
 
425
 
  libchar_found=0;
426
 
  (void) stpcpy(buff,from);                      /* If to == from */
427
 
  from_pos= buff;
428
 
  if ((pos=strrchr(from_pos,FN_DEVCHAR)))       /* Skip device part */
429
 
  {
430
 
    pos++;
431
 
    to_pos=stpncpy(to,from_pos,(size_t) (pos-from_pos));
432
 
    from_pos=pos;
433
 
  }
434
 
  else
435
 
    to_pos=to;
436
 
 
437
 
  if (from_pos[0] == FN_CURLIB && from_pos[1] == FN_LIBCHAR)
438
 
    from_pos+=2;                                /* Skip './' */
439
 
  if (strchr(from_pos,FN_LIBCHAR))
440
 
  {
441
 
    *(to_pos++) = FN_C_BEFORE_DIR;
442
 
    if (strstr(from_pos,FN_ROOTDIR) == from_pos)
443
 
    {
444
 
      from_pos+=strlen(FN_ROOTDIR);             /* Actually +1 but... */
445
 
      if (! strchr(from_pos,FN_LIBCHAR))
446
 
      {                                         /* No dir, use [000000] */
447
 
        to_pos=stpcpy(to_pos,FN_C_ROOT_DIR);
448
 
        libchar_found++;
449
 
      }
450
 
    }
451
 
    else
452
 
      *(to_pos++)=FN_C_DIR_SEP;                 /* '.' gives current dir */
453
 
 
454
 
    while ((pos=strchr(from_pos,FN_LIBCHAR)))
455
 
    {
456
 
      if (libchar_found++)
457
 
        *(to_pos++)=FN_C_DIR_SEP;               /* Add '.' between dirs */
458
 
      if (strstr(from_pos,FN_PARENTDIR) == from_pos &&
459
 
          from_pos+strlen(FN_PARENTDIR) == pos)
460
 
        to_pos=stpcpy(to_pos,FN_C_PARENT_DIR);  /* Found '../' */
461
 
      else
462
 
        to_pos=stpncpy(to_pos,from_pos,(size_t) (pos-from_pos));
463
 
      from_pos=pos+1;
464
 
    }
465
 
    *(to_pos++)=FN_C_AFTER_DIR;
466
 
  }
467
 
  length= (size_t) (stpcpy(to_pos,from_pos)-to);
468
 
  return(length);
469
 
#endif
 
293
  return strlen(strncpy(to,from,FN_REFLEN-1));
470
294
} /* system_filename */
471
295
 
472
296
 
478
302
  char buff[FN_REFLEN];
479
303
  if (from == to)
480
304
  {                                             /* Dirname may destroy from */
481
 
    stpcpy(buff,from);
 
305
    strcpy(buff,from);
482
306
    from=buff;
483
307
  }
484
308
  length= dirname_part(to, from, &to_length);   /* Copy dirname & fix chars */
485
 
  (void) stpcpy(to + to_length,from+length);
 
309
  (void) strcpy(to + to_length,from+length);
486
310
  return (to);
487
311
} /* intern_filename */
 
312
 
 
313
} /* namespace internal */
 
314
} /* namespace drizzled */