~drizzle-trunk/drizzle/development

« back to all changes in this revision

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

  • Committer: Mark Atwood
  • Date: 2011-12-20 02:32:53 UTC
  • mfrom: (2469.1.1 drizzle-build)
  • Revision ID: me@mark.atwood.name-20111220023253-bvu0kr14kwsdvz7g
mergeĀ lp:~brianaker/drizzle/deprecate-pbms

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