~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to plugin/pbms/src/cslib/CSPath.cc

  • Committer: Jay Pipes
  • Date: 2009-09-15 21:01:42 UTC
  • mto: (1126.2.5 merge)
  • mto: This revision was merged to the branch mainline in revision 1128.
  • Revision ID: jpipes@serialcoder-20090915210142-x8mwiqn1q0vzjspp
Moves Alter_info out into its own header and source file, cleans up some related include mess in sql_lex.h, and renames Alter_info to AlterInfo.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/* Copyright (C) 2008 PrimeBase Technologies GmbH, Germany
2
 
 *
3
 
 * PrimeBase Media Stream for MySQL
4
 
 *
5
 
 * This program is free software; you can redistribute it and/or modify
6
 
 * it under the terms of the GNU General Public License as published by
7
 
 * the Free Software Foundation; either version 2 of the License, or
8
 
 * (at your option) any later version.
9
 
 *
10
 
 * This program is distributed in the hope that it will be useful,
11
 
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12
 
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13
 
 * GNU General Public License for more details.
14
 
 *
15
 
 * You should have received a copy of the GNU General Public License
16
 
 * along with this program; if not, write to the Free Software
17
 
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
18
 
 *
19
 
 * Original author: Paul McCullagh
20
 
 * Continued development: Barry Leslie
21
 
 *
22
 
 * 2007-06-07
23
 
 *
24
 
 * CORE SYSTEM:
25
 
 * Basic file system path.
26
 
 *
27
 
 */
28
 
 
29
 
#include "CSConfig.h"
30
 
 
31
 
#include <string.h>
32
 
#include <stdio.h>
33
 
 
34
 
#include "CSStrUtil.h"
35
 
#include "CSSys.h"
36
 
#include "CSFile.h"
37
 
#include "CSDirectory.h"
38
 
#include "CSPath.h"
39
 
#include "CSGlobal.h"
40
 
 
41
 
/*
42
 
 * ---------------------------------------------------------------
43
 
 * CORE SYSTEM PATH
44
 
 */
45
 
CSLock  CSPath::iRename_lock;
46
 
 
47
 
CSPath *CSPath::iCWD = NULL;
48
 
 
49
 
CSPath::~CSPath()
50
 
{
51
 
        if (iPath)
52
 
                iPath->release();
53
 
}
54
 
 
55
 
CSFile *CSPath::try_CreateAndOpen(CSThread *self, int mode, bool retry)
56
 
{
57
 
        try_(a) {
58
 
                return openFile(mode | CSFile::CREATE); // success, do not try again.
59
 
        }
60
 
        catch_(a) {
61
 
                if (retry || !CSFile::isDirNotFound(&self->myException))
62
 
                        throw_();
63
 
 
64
 
                /* Make sure the parent directory exists: */
65
 
                CSPath  *dir = CSPath::newPath(RETAIN(this), "..");
66
 
                push_(dir);
67
 
                dir->makePath();
68
 
                release_(dir);
69
 
 
70
 
        }
71
 
        cont_(a);
72
 
        return NULL; 
73
 
}
74
 
 
75
 
CSFile *CSPath::createFile(int mode)
76
 
{
77
 
        CSFile  *file = NULL;
78
 
        bool    retry = false;
79
 
 
80
 
        enter_();
81
 
        while (file == NULL) {
82
 
                file = try_CreateAndOpen(self, mode, retry);
83
 
                retry = true;
84
 
        }
85
 
        return_(file);
86
 
}
87
 
 
88
 
/* Copy the contents of one file to another.
89
 
 * The destination need not exist.
90
 
 * If the destination exists, it will be
91
 
 * overwritten if 'overwrite' is true.
92
 
 */
93
 
void CSPath::copyFile(CSPath *in_to_file, bool overwrite)
94
 
{
95
 
        CSPath                  *to_file = in_to_file;
96
 
        bool                    is_dir;
97
 
        CSFile                  *infile, *outfile;
98
 
 
99
 
        enter_();
100
 
        push_(in_to_file);
101
 
        
102
 
        if (to_file->exists(&is_dir)) {
103
 
                if (is_dir) {
104
 
                        to_file = CSPath::newPath(RETAIN(in_to_file), getNameCString());
105
 
                        push_(to_file);
106
 
                        
107
 
                        if (to_file->exists(&is_dir)) { 
108
 
                                if (!overwrite)
109
 
                                        CSException::throwFileError(CS_CONTEXT, to_file->getCString(), EEXIST);
110
 
                                to_file->remove();
111
 
                        }
112
 
                }
113
 
                else if (!overwrite)
114
 
                        CSException::throwFileError(CS_CONTEXT, to_file->getCString(), EEXIST);
115
 
        }
116
 
 
117
 
        infile = openFile(CSFile::READONLY);
118
 
        push_(infile);
119
 
 
120
 
        outfile = to_file->createFile(CSFile::TRUNCATE);
121
 
        push_(outfile);
122
 
        
123
 
        CSStream::pipe(outfile->getOutputStream(), infile->getInputStream());
124
 
        release_(outfile);
125
 
        release_(infile);
126
 
        
127
 
        if (to_file != in_to_file)
128
 
                release_(to_file);
129
 
                
130
 
        release_(in_to_file);
131
 
        exit_();
132
 
}
133
 
 
134
 
void CSPath::makePath()
135
 
{
136
 
        CSPath  *path;
137
 
        bool    is_dir;
138
 
 
139
 
        enter_();
140
 
        if (iPath->length() <= 1)
141
 
                exit_();
142
 
 
143
 
        if (exists(&is_dir)) {
144
 
                if (!is_dir)
145
 
                        CSException::throwFileError(CS_CONTEXT, iPath, EEXIST);
146
 
                exit_();
147
 
        }
148
 
 
149
 
        path = CSPath::newPath(RETAIN(this), "..");
150
 
        push_(path);
151
 
        
152
 
        path->makePath();
153
 
        makeDir();
154
 
        
155
 
        release_(path);
156
 
 
157
 
        exit_();
158
 
}
159
 
 
160
 
/* Copy the contents of one directory to another.
161
 
 * The destination must be a directory.
162
 
 * The new source directory will be copied to
163
 
 * a directory of the same name in the destination.
164
 
 */
165
 
void CSPath::copyDir(CSPath *in_to_dir, bool overwrite)
166
 
{
167
 
        CSPath          *to_dir = in_to_dir;
168
 
        bool            is_dir;
169
 
        CSDirectory *dir = NULL;
170
 
        CSPath          *path = NULL;
171
 
 
172
 
        enter_();
173
 
        push_(in_to_dir);
174
 
        
175
 
        if (to_dir->exists(&is_dir)) {
176
 
                if (!is_dir)
177
 
                        CSException::throwFileError(CS_CONTEXT, to_dir->getCString(), ENOTDIR);
178
 
                /* Add the source directory name to the destination: */
179
 
                to_dir = CSPath::newPath(RETAIN(in_to_dir), getNameCString());
180
 
                push_(to_dir);
181
 
                
182
 
                if (to_dir->exists(&is_dir)) {
183
 
                        if (!overwrite)
184
 
                                CSException::throwFileError(CS_CONTEXT, to_dir->getCString(), EEXIST);
185
 
                        to_dir->remove();
186
 
                }
187
 
        }
188
 
 
189
 
        /* Make the directory and copy the contents of the source
190
 
         * into it:
191
 
         */
192
 
        to_dir->makePath();
193
 
 
194
 
        dir = openDirectory();
195
 
        push_(dir);
196
 
        while (dir->next()) {
197
 
                self->interrupted();
198
 
                path = CSPath::newPath(RETAIN(this), dir->name());
199
 
                push_(path);
200
 
                if (dir->isFile())
201
 
                        path->copyFile(RETAIN(to_dir), overwrite);
202
 
                else
203
 
                        path->copyDir(RETAIN(to_dir), overwrite);
204
 
                release_(path);
205
 
        }
206
 
        release_(dir);
207
 
        
208
 
        if (to_dir != in_to_dir)
209
 
                release_(to_dir);
210
 
                
211
 
        release_(in_to_dir);
212
 
        
213
 
        exit_();
214
 
}
215
 
 
216
 
 
217
 
bool CSPath::isLink()
218
 
{
219
 
        bool link;
220
 
        enter_();
221
 
 
222
 
        link = sys_isLink(iPath->getCString());
223
 
        
224
 
        return_(link);
225
 
}
226
 
 
227
 
bool CSPath::isEmpty()
228
 
{
229
 
        CSDirectory *dir = NULL;
230
 
        bool            is_dir, result = true;
231
 
 
232
 
        enter_();
233
 
        if (!exists(&is_dir))
234
 
                return_(true);
235
 
 
236
 
        if (!is_dir)
237
 
                return_(false);
238
 
 
239
 
        dir = openDirectory();
240
 
        push_(dir);
241
 
        
242
 
        if (dir->next())
243
 
                result = false;
244
 
 
245
 
        release_(dir);
246
 
        return_(result);
247
 
}
248
 
 
249
 
void CSPath::emptyDir()
250
 
{
251
 
        CSDirectory *dir;
252
 
        CSPath          *path = NULL;
253
 
        bool            is_dir;
254
 
 
255
 
        enter_();
256
 
        if (!exists(&is_dir))
257
 
                exit_();
258
 
 
259
 
        if (!is_dir)
260
 
                CSException::throwFileError(CS_CONTEXT, iPath, ENOTDIR);
261
 
 
262
 
        dir = openDirectory();
263
 
        push_(dir);
264
 
 
265
 
        while (dir->next()) {
266
 
                path = CSPath::newPath(RETAIN(this), dir->name());
267
 
                push_(path);
268
 
                if (dir->isFile())
269
 
                        path->remove();
270
 
                else
271
 
                        path->removeDir();
272
 
                release_(path);
273
 
        }
274
 
 
275
 
        release_(dir);
276
 
        exit_();
277
 
}
278
 
 
279
 
void CSPath::emptyPath()
280
 
{
281
 
        CSDirectory *dir;
282
 
        CSPath          *path = NULL;
283
 
        bool            is_dir;
284
 
 
285
 
        enter_();
286
 
        if (!exists(&is_dir))
287
 
                exit_();
288
 
 
289
 
        if (!is_dir)
290
 
                CSException::throwFileError(CS_CONTEXT, iPath, ENOTDIR);
291
 
 
292
 
        dir = openDirectory();
293
 
        push_(dir);
294
 
 
295
 
        while (dir->next()) {
296
 
                path = CSPath::newPath(RETAIN(this), dir->name());
297
 
                push_(path);
298
 
                if (dir->isFile())
299
 
                        path->remove();
300
 
                else
301
 
                        path->emptyPath();
302
 
                release_(path);
303
 
        }
304
 
 
305
 
        release_(dir);
306
 
        exit_();
307
 
}
308
 
 
309
 
void CSPath::copyTo(CSPath *to_path, bool overwrite)
310
 
{
311
 
        bool is_dir;
312
 
 
313
 
        enter_();
314
 
        push_(to_path);
315
 
        if (!exists(&is_dir))
316
 
                CSException::throwFileError(CS_CONTEXT, iPath, ENOENT);
317
 
 
318
 
        pop_(to_path);
319
 
        if (is_dir)
320
 
                /* The source is a directory. */
321
 
                copyDir(to_path, overwrite);
322
 
        else {
323
 
                /* The source is not a directory: */
324
 
                copyFile(to_path, overwrite);
325
 
        }
326
 
 
327
 
        exit_();
328
 
}
329
 
 
330
 
void CSPath::moveTo(CSPath *in_to_path)
331
 
{
332
 
        CSPath  *to_path = NULL;
333
 
        bool    is_dir;
334
 
 
335
 
        enter_();
336
 
        push_(in_to_path);
337
 
        
338
 
        if (!exists(NULL))
339
 
                CSException::throwFileError(CS_CONTEXT, iPath, ENOENT);
340
 
 
341
 
        if (in_to_path->exists(&is_dir)) {
342
 
                if (is_dir) {
343
 
                        to_path = CSPath::newPath(RETAIN(in_to_path), getNameCString());
344
 
                        push_(to_path);
345
 
                        if (to_path->exists(NULL))
346
 
                                CSException::throwFileError(CS_CONTEXT, to_path->getCString(), EEXIST);
347
 
                        pop_(to_path);
348
 
                }
349
 
                else
350
 
                        CSException::throwFileError(CS_CONTEXT, to_path->getCString(), ENOTDIR);
351
 
        } else
352
 
                to_path = RETAIN(in_to_path);
353
 
                
354
 
        move(to_path);
355
 
 
356
 
        release_(in_to_path);
357
 
        exit_();
358
 
}
359
 
 
360
 
void CSPath::remove()
361
 
{
362
 
        bool is_dir;
363
 
 
364
 
        if (exists(&is_dir)) {
365
 
                if (is_dir) {
366
 
                        emptyDir();
367
 
                        removeDir();
368
 
                }
369
 
                else
370
 
                        removeFile();
371
 
        }
372
 
}
373
 
 
374
 
 
375
 
void CSPath::touch(bool create_path)
376
 
{
377
 
        CSFile *file;
378
 
 
379
 
        enter_();
380
 
        if (create_path)
381
 
                file = createFile(CSFile::READONLY);
382
 
        else
383
 
                file = openFile(CSFile::READONLY | CSFile::CREATE);
384
 
        file->release();
385
 
        exit_();
386
 
}
387
 
 
388
 
CSString *CSPath::getString()
389
 
390
 
        return iPath;
391
 
}
392
 
 
393
 
const char *CSPath::getCString()
394
 
{
395
 
        return iPath->getCString();
396
 
}
397
 
 
398
 
const char *CSPath::getNameCString()
399
 
{
400
 
        const char *str = getCString();
401
 
        
402
 
        return cs_last_name_of_path(str);
403
 
}
404
 
 
405
 
off64_t CSPath::getSize(const char *path)
406
 
{
407
 
        off64_t size;
408
 
 
409
 
        info(path, NULL, &size, NULL);
410
 
        return size;
411
 
}
412
 
 
413
 
off64_t CSPath::getSize()
414
 
{
415
 
        off64_t size;
416
 
 
417
 
        info((bool *) NULL, &size, (CSTime *) NULL);
418
 
        return size;
419
 
}
420
 
 
421
 
bool CSPath::isDir()
422
 
{
423
 
        bool    is_dir;
424
 
 
425
 
        info(&is_dir, (off64_t *) NULL, (CSTime *) NULL);
426
 
        return is_dir;
427
 
}
428
 
 
429
 
bool CSPath::exists(bool *is_dir)
430
 
{
431
 
        if (!sys_exists(iPath->getCString()))
432
 
                return false;
433
 
                
434
 
        if (is_dir)
435
 
                *is_dir = isDir();
436
 
        return true;
437
 
}
438
 
 
439
 
void CSPath::info(const char *path, bool *is_dir, off64_t *size, CSTime *mod_time)
440
 
{
441
 
        sys_stat(path, is_dir, size, mod_time);
442
 
        
443
 
}
444
 
 
445
 
void CSPath::info(bool *is_dir, off64_t *size, CSTime *mod_time)
446
 
{
447
 
        info(iPath->getCString(), is_dir, size, mod_time);
448
 
}
449
 
 
450
 
CSFile *CSPath::openFile(int mode)
451
 
{
452
 
        CSFile *file;
453
 
 
454
 
        enter_();
455
 
        file = CSFile::newFile(RETAIN(this));
456
 
        push_(file);
457
 
        file->open(mode);
458
 
        pop_(file);
459
 
        return_(file);
460
 
}
461
 
 
462
 
void CSPath::removeFile()
463
 
{
464
 
        sys_removeFile(iPath->getCString());
465
 
}
466
 
 
467
 
void CSPath::makeDir()
468
 
{
469
 
        char path[PATH_MAX];
470
 
 
471
 
        cs_strcpy(PATH_MAX, path, iPath->getCString());
472
 
        cs_remove_dir_char(path);
473
 
 
474
 
        sys_makeDir(path);
475
 
}
476
 
 
477
 
CSDirectory *CSPath::openDirectory()
478
 
{
479
 
        CSDirectory *dir;
480
 
 
481
 
        enter_();
482
 
        dir = CSDirectory::newDirectory(RETAIN(this));
483
 
        push_(dir);
484
 
        dir->open();
485
 
        pop_(dir);
486
 
        return_(dir);
487
 
}
488
 
 
489
 
void CSPath::removeDir()
490
 
{                       
491
 
        emptyDir();
492
 
        sys_removeDir(iPath->getCString());
493
 
}
494
 
 
495
 
void CSPath::rename(const char *name)
496
 
{
497
 
        char new_path[PATH_MAX];
498
 
        CSString *tmp_path, *old_path = iPath;
499
 
        
500
 
        enter_();
501
 
        
502
 
        cs_strcpy(PATH_MAX, new_path, iPath->getCString());
503
 
        cs_remove_last_name_of_path(new_path);
504
 
        cs_add_dir_char(PATH_MAX, new_path);
505
 
        cs_strcat(PATH_MAX, new_path, name);
506
 
        
507
 
        lock_(&iRename_lock); // protect against race condition when testing if the new name exists yet or not. 
508
 
        if (sys_exists(new_path))
509
 
                CSException::throwFileError(CS_CONTEXT, new_path, EEXIST);
510
 
        
511
 
        tmp_path = CSString::newString(new_path);
512
 
        push_(tmp_path);
513
 
        
514
 
        sys_rename(iPath->getCString(), new_path);
515
 
                
516
 
        pop_(tmp_path);
517
 
        unlock_(&iRename_lock);
518
 
        
519
 
        old_path = iPath;
520
 
        iPath = tmp_path;
521
 
        
522
 
        old_path->release();
523
 
        exit_();
524
 
}
525
 
 
526
 
void CSPath::move(CSPath *to_path)
527
 
{
528
 
        enter_();
529
 
        lock_(&iRename_lock); // protect against race condition when testing if the new name exists yet or not. 
530
 
        if (to_path->exists())
531
 
                CSException::throwFileError(CS_CONTEXT, to_path->getCString(), EEXIST);
532
 
                
533
 
        /* Cannot move from TD to non-TD: */
534
 
        sys_rename(iPath->getCString(), to_path->getCString());
535
 
        unlock_(&iRename_lock);
536
 
        exit_();
537
 
}
538
 
 
539
 
CSPath *CSPath::getCWD()
540
 
{
541
 
        char path[PATH_MAX];
542
 
 
543
 
        sys_getcwd(path, PATH_MAX);
544
 
        return newPath(path);
545
 
}
546
 
 
547
 
CSPath *CSPath::newPath(const char *path)
548
 
{
549
 
        if (!path)
550
 
                CSException::throwAssertion(CS_CONTEXT, "Initial string may not be NULL");
551
 
        return newPath(CSString::newString(path));
552
 
}
553
 
 
554
 
CSPath *CSPath::newPath(CSString *path)
555
 
{
556
 
        CSPath *p;
557
 
 
558
 
        enter_();
559
 
        push_(path);
560
 
        new_(p, CSPath());
561
 
 
562
 
        /* Adjust the path string so that it does not have
563
 
         * a terminating CS_DIR_CHAR:
564
 
         */
565
 
        if (path->endsWith(CS_DIR_DELIM) && path->length() > 1) {
566
 
                p->iPath = path->left(CS_DIR_DELIM, -1);
567
 
                path->release();
568
 
        }
569
 
        else
570
 
                p->iPath = path;
571
 
        pop_(path);
572
 
        return_(p);
573
 
}
574
 
 
575
 
CSPath *CSPath::newPath(CSPath *cwd, const char *path)
576
 
{
577
 
        char abs_path[PATH_MAX];
578
 
 
579
 
        enter_();
580
 
        cs_make_absolute_path(PATH_MAX, abs_path, path, cwd->getCString());
581
 
        cwd->release();
582
 
        CSPath *p = newPath(abs_path);
583
 
        return_(p);
584
 
}
585
 
 
586
 
CSPath *CSPath::newPath(CSString *cwd, const char *path)
587
 
{
588
 
        char abs_path[PATH_MAX];
589
 
 
590
 
        enter_();
591
 
        cs_make_absolute_path(PATH_MAX, abs_path, path, cwd->getCString());
592
 
        cwd->release();
593
 
        CSPath *p = newPath(abs_path);
594
 
        return_(p);
595
 
}
596
 
 
597
 
CSPath *CSPath::newPath(const char *cwd, CSString *path)
598
 
{
599
 
        char abs_path[PATH_MAX];
600
 
 
601
 
        enter_();
602
 
        cs_make_absolute_path(PATH_MAX, abs_path, path->getCString(), cwd);
603
 
        path->release();
604
 
        CSPath *p = newPath(abs_path);
605
 
        return_(p);
606
 
}
607
 
 
608
 
CSPath *CSPath::newPath(const char *cwd, const char *path)
609
 
{
610
 
        char abs_path[PATH_MAX];
611
 
 
612
 
        enter_();
613
 
        cs_make_absolute_path(PATH_MAX, abs_path, path, cwd);
614
 
        CSPath *p = newPath(abs_path);
615
 
        return_(p);
616
 
}
617