~drizzle-trunk/drizzle/development

« back to all changes in this revision

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

  • Committer: Brian Aker
  • Date: 2009-10-15 00:22:33 UTC
  • mto: (1183.1.11 merge)
  • mto: This revision was merged to the branch mainline in revision 1198.
  • Revision ID: brian@gaz-20091015002233-fa4ao2mbc67wls91
First pass of information engine. OMG, ponies... is it so much easier to
deal with creating and engine.

The list table iterator though... its ass, needs to go. We should also
abstract out share. Very few engines need a custom one. Just say'in

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