File: fileutils.cc

package info (click to toggle)
wvstreams 4.0.2-4
  • links: PTS
  • area: main
  • in suites: sarge
  • size: 6,420 kB
  • ctags: 6,518
  • sloc: cpp: 52,544; sh: 5,770; ansic: 810; makefile: 461; tcl: 114; perl: 18
file content (138 lines) | stat: -rw-r--r-- 3,423 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
/*
 * Worldvisions Weaver Software:
 *   Copyright (C) 1997-2002 Net Integration Technologies, Inc.
 * 
 * Various useful file utilities.
 *
 */
#include "fileutils.h"
#include "wvfile.h"
#include <string.h>
#include <unistd.h>
#include <sys/stat.h>
#include <utime.h>
#include <fnmatch.h>

bool mkdirp(WvStringParm _dir, int create_mode)
{
    if (!access(_dir, X_OK))
        return true;

    // You're trying to make a nothing directory eh?
    assert(!!_dir);

    WvString dir(_dir);
    char *p = dir.edit();

    while ((p = strchr(++p, '/')))
    {
        *p = '\0';
        if (access(dir.cstr(), X_OK) && mkdir(dir.cstr(), create_mode))
            return false;
        *p = '/';
    }

    // You're probably creating the directory to write to it? Maybe this should
    // look for R_OK&X_OK instead of X_OK&W_OK...
    return  !(access(dir.cstr(), X_OK&W_OK) && mkdir(dir.cstr(), create_mode));
}


bool fcopy(WvStringParm src, WvStringParm dst)
{
    struct stat buf;
    if (stat(src, &buf))
        return false;

    WvFile in(src, O_RDONLY);
    unlink(dst);

    int oldmode = umask(0);
    WvFile out(dst, O_CREAT|O_WRONLY, buf.st_mode & 007777);
    umask(oldmode);

    in.autoforward(out);
    while (in.isok() && out.isok())
    {
	/* This used to be a select(0), but really, if select() returns
	 * false, it'll keep doing it until the end of time. If you're
	 * going into an infinite loop, better save the CPU a bit, since
	 * you can still find out about it with strace... */
        if (in.select(-1, true, false))
            in.callback();
    }
    if (!out.isok())
        return false;

    struct utimbuf utim;
    utim.actime = utim.modtime = buf.st_mtime;
    if (utime(dst, &utim))
        return false;

    return true;
}


bool fcopy(WvStringParm srcdir, WvStringParm dstdir, WvStringParm relname)
{
    return fcopy(WvString("%s/%s", srcdir, relname),
        WvString("%s/%s", dstdir, relname));
}


bool samedate(WvStringParm file1, WvStringParm file2)
{
    struct stat buf;
    struct stat buf2;

    if (stat(file1, &buf) || stat(file2, &buf2))
        return false;

    if (buf.st_mtime == buf2.st_mtime || buf.st_ctime == buf2.st_ctime)
        return true;

    return false;
}


bool samedate(WvStringParm dir1, WvStringParm dir2, WvStringParm relname)
{
    return samedate(WvString("%s/%s", dir1, relname),
        WvString("%s/%s", dir2, relname));
}


// runs fnmatch against everything in patterns.  We also interpret 
// CVS-style '!' patterns, which makes us very fancy.
bool wvfnmatch(WvStringList& patterns, WvStringParm name, int flags)
{
    WvStringList::Iter i(patterns);
    bool match = false;

    for (i.rewind(); i.next(); )
    {
        // if we hit JUST a '!', reset any matches found so far.
        if (*i == "!") {
            match = false;
            continue;
        }

        // if we hit something that starts with '!', we unmatch anything
        // found so far.
        if (i->cstr()[0] == '!')
        {
            if (!match)
                continue;   // nothing to unmatch, so why try?
            if (fnmatch(*i+1, name, flags) == 0)    // matches
                match = false;                      // unmatch it.
        }
        else
        {
            // just a straightforward matching case.
            if (fnmatch(*i, name, flags) == 0)  // matches
                match = true;
        }
    }

    return match;
}