~ubuntu-branches/ubuntu/precise/boinc/precise

« back to all changes in this revision

Viewing changes to lib/filesys.cpp

Tags: 6.12.8+dfsg-1
* New upstream release.
* Simplified debian/rules

Show diffs side-by-side

added added

removed removed

Lines of Context:
15
15
// You should have received a copy of the GNU Lesser General Public License
16
16
// along with BOINC.  If not, see <http://www.gnu.org/licenses/>.
17
17
 
18
 
#if defined(_WIN32) && !defined(__STDWX_H__) && !defined(_BOINC_WIN_) && !defined(_AFX_STDAFX_H_)
 
18
#if   defined(_WIN32) && !defined(__STDWX_H__)
19
19
#include "boinc_win.h"
 
20
#elif defined(_WIN32) && defined(__STDWX_H__)
 
21
#include "stdwx.h"
 
22
#endif
 
23
 
 
24
#if defined(__MINGW32__)
 
25
#include <fcntl.h>
 
26
#endif
 
27
 
 
28
#ifdef _MSC_VER
 
29
#define getcwd  _getcwd
20
30
#endif
21
31
 
22
32
#if !defined(_WIN32) || defined(__CYGWIN32__)
59
69
#endif
60
70
 
61
71
#ifdef _WIN32
62
 
typedef BOOL (CALLBACK* FreeFn)(LPCTSTR, PULARGE_INTEGER, PULARGE_INTEGER, PULARGE_INTEGER);
 
72
typedef BOOL (CALLBACK* FreeFn)(LPCSTR, PULARGE_INTEGER, PULARGE_INTEGER, PULARGE_INTEGER);
63
73
#endif
64
74
 
65
75
#include "util.h"
66
76
#include "str_util.h"
 
77
#include "str_replace.h"
67
78
#include "error_numbers.h"
68
79
#include "filesys.h"
69
80
 
120
131
//
121
132
int dir_scan(char* p, DIRREF dirp, int p_len) {
122
133
#ifdef _WIN32
123
 
    WIN32_FIND_DATA data;
 
134
    WIN32_FIND_DATAA data;
124
135
    while (1) {
125
136
        if (dirp->first) {
126
137
            dirp->first = false;
127
 
            dirp->handle = FindFirstFile(dirp->path, &data);
 
138
            dirp->handle = FindFirstFileA(dirp->path, &data);
128
139
            if (dirp->handle == INVALID_HANDLE_VALUE) {
129
140
                return ERR_READDIR;
130
141
            } else {
136
147
                return 0;
137
148
            }
138
149
        } else {
139
 
            if (FindNextFile(dirp->handle, &data)) {
 
150
            if (FindNextFileA(dirp->handle, &data)) {
140
151
                if (!strcmp(data.cFileName, ".")) continue;
141
152
                if (!strcmp(data.cFileName, "..")) continue;
142
153
                if (p) strlcpy(p, data.cFileName, p_len);
179
190
#endif
180
191
}
181
192
 
 
193
bool is_dir_empty(const char *p) {
 
194
    char file[256];
 
195
 
 
196
    DIRREF dir = dir_open(p);
 
197
    if (!dir) return true;
 
198
 
 
199
    if (!dir_scan(file, dir, sizeof(file))) {
 
200
        dir_close(dir);
 
201
        return false;
 
202
    }
 
203
 
 
204
    return true;
 
205
}
 
206
 
182
207
DirScanner::DirScanner(string const& path) {
183
208
#ifdef _WIN32
184
209
    first = true;
196
221
//
197
222
bool DirScanner::scan(string& s) {
198
223
#ifdef _WIN32
199
 
    WIN32_FIND_DATA data;
 
224
    WIN32_FIND_DATAA data;
200
225
    while (1) {
201
226
        if (first) {
202
227
            first = false;
203
 
            handle = FindFirstFile(dir.c_str(), &data);
 
228
            handle = FindFirstFileA(dir.c_str(), &data);
204
229
            if (handle == INVALID_HANDLE_VALUE) {
205
230
                return false;
206
231
            } else {
209
234
                return true;
210
235
            }
211
236
        } else {
212
 
            if (FindNextFile(handle, &data)) {
 
237
            if (FindNextFileA(handle, &data)) {
213
238
                if (data.cFileName[0] == '.') continue;
214
239
                s = data.cFileName;
215
240
                return true;
250
275
 
251
276
static int boinc_delete_file_aux(const char* path) {
252
277
#ifdef _WIN32
253
 
    if (!DeleteFile(path)) {
 
278
    if (!DeleteFileA(path)) {
254
279
        return ERR_UNLINK;
255
280
    }
256
281
#else
350
375
    char path2[_MAX_PATH];
351
376
    sprintf(path2, "%s/*", dirpath);
352
377
    size = 0.0;
353
 
    WIN32_FIND_DATA findData;
354
 
    HANDLE hFind = ::FindFirstFile(path2, &findData);
 
378
    WIN32_FIND_DATAA findData;
 
379
    HANDLE hFind = ::FindFirstFileA(path2, &findData);
355
380
    if (INVALID_HANDLE_VALUE == hFind) return ERR_OPENDIR;
356
381
    do {
357
382
        if (findData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) {
367
392
        } else {
368
393
            size += findData.nFileSizeLow + ((__int64)(findData.nFileSizeHigh) << 32);
369
394
        }
370
 
    } while (FindNextFile(hFind, &findData));
 
395
    } while (FindNextFileA(hFind, &findData));
371
396
        ::FindClose(hFind);
372
397
#else
373
398
    char filename[256], subdir[256];
495
520
 
496
521
int boinc_copy(const char* orig, const char* newf) {
497
522
#ifdef _WIN32
498
 
    if (!CopyFile(orig, newf, FALSE)) {     // FALSE means overwrite OK
 
523
    if (!CopyFileA(orig, newf, FALSE)) {     // FALSE means overwrite OK
499
524
        return GetLastError();
500
525
    }
501
526
    return 0;
504
529
    sprintf(cmd, "copy \"%s\" \"%s\"", orig, newf);
505
530
    return system(cmd);
506
531
#else
507
 
    char cmd[1024];
508
 
    sprintf(cmd, "cp \"%s\" \"%s\"", orig, newf);
509
 
    return system(cmd);
 
532
    // POSIX requires that shells run from an application will use the 
 
533
    // real UID and GID if different from the effective UID and GID.  
 
534
    // Mac OS 10.4 did not enforce this, but OS 10.5 does.  Since 
 
535
    // system() invokes a shell, it may not properly copy the file's 
 
536
    // ownership or permissions when called from the BOINC Client 
 
537
    // under sandbox security, so we copy the file directly.
 
538
    FILE *src, *dst;
 
539
    int m, n;
 
540
    int retval = 0;
 
541
    struct stat sbuf;
 
542
    unsigned char buf[65536];
 
543
    src = boinc_fopen(orig, "r");
 
544
    if (!src) return ERR_FOPEN;
 
545
    dst = boinc_fopen(newf, "w");
 
546
    if (!dst) {
 
547
        fclose(src);
 
548
        return ERR_FOPEN;
 
549
    }
 
550
    while (1) {
 
551
        n = fread(buf, 1, sizeof(buf), src);
 
552
        if (n <= 0) break;
 
553
        m = fwrite(buf, 1, n, dst);
 
554
        if (m != n) {
 
555
            retval = ERR_FWRITE;
 
556
            break;
 
557
        }
 
558
    }
 
559
    fclose(src);
 
560
    fclose(dst);
 
561
    // Copy file's ownership, permissions to the extent we are allowed
 
562
    lstat(orig, &sbuf);             // Get source file's info
 
563
    chown(newf, sbuf.st_uid, sbuf.st_gid);
 
564
    chmod(newf, sbuf.st_mode);
 
565
    return retval;
510
566
#endif
511
567
}
512
568
 
513
569
static int boinc_rename_aux(const char* old, const char* newf) {
514
570
#ifdef _WIN32
515
 
    boinc_delete_file(newf);
516
 
    if (MoveFile(old, newf)) return 0;
 
571
    if (MoveFileExA(old, newf, MOVEFILE_REPLACE_EXISTING|MOVEFILE_WRITE_THROUGH)) return 0;
517
572
    return GetLastError();
518
573
#else
519
 
    return rename(old, newf);
 
574
    int retval = rename(old, newf);
 
575
    if (retval) return ERR_RENAME;
 
576
    return 0;
520
577
#endif
521
578
}
522
579
 
540
597
int boinc_mkdir(const char* path) {
541
598
    if (is_dir(path)) return 0;
542
599
#ifdef _WIN32
543
 
    if (!CreateDirectory(path, NULL)) {
 
600
    if (!CreateDirectoryA(path, NULL)) {
544
601
        return GetLastError();
545
602
    }
546
 
    return 0;
547
603
#else
548
604
    mode_t old_mask = umask(0);
549
605
    int retval = mkdir(path, 0771);
550
606
    umask(old_mask);
551
 
    return retval;
 
607
    if (retval) return ERR_MKDIR;
552
608
#endif
 
609
    return 0;
553
610
}
554
611
 
555
612
int boinc_rmdir(const char* name) {
556
613
#ifdef _WIN32
557
 
    if (!RemoveDirectory(name)) {
 
614
    if (!RemoveDirectoryA(name)) {
558
615
        return ERR_RMDIR;
559
616
    }
560
617
#else
605
662
#ifndef _WIN32
606
663
    fd = -1;
607
664
#endif
 
665
    locked = false;
608
666
}
 
667
 
609
668
FILE_LOCK::~FILE_LOCK() {
610
669
#ifndef _WIN32
611
670
    if (fd >= 0) close(fd);
614
673
 
615
674
int FILE_LOCK::lock(const char* filename) {
616
675
#if defined(_WIN32) && !defined(__CYGWIN32__)
617
 
    handle = CreateFile(
 
676
    handle = CreateFileA(
618
677
        filename, GENERIC_WRITE,
619
678
        0, 0, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0
620
679
    );
621
680
    if (handle == INVALID_HANDLE_VALUE) {
622
 
        return -1;
 
681
        return GetLastError();
623
682
    }
624
 
    return 0;
625
 
 
626
683
#else
627
684
    if (fd<0) {
628
 
        fd = open(
629
 
            filename, O_WRONLY|O_CREAT, S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH
630
 
        );
 
685
        fd = open(filename, O_WRONLY|O_CREAT, S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|S_IROTH);
631
686
    }
632
687
    if (fd<0) {
633
 
        return -1;
 
688
        return ERR_OPEN;
634
689
    }
635
690
 
636
691
    struct flock fl;
637
 
    fl.l_type=F_WRLCK;
638
 
    fl.l_whence=SEEK_SET;
639
 
    fl.l_start=0;
640
 
    fl.l_len=0;
641
 
    if (-1 != fcntl(fd, F_SETLK, &fl)) return 0;
642
 
    return -1;
 
692
    fl.l_type = F_WRLCK;
 
693
    fl.l_whence = SEEK_SET;
 
694
    fl.l_start = 0;
 
695
    fl.l_len = 0;
 
696
    if (fcntl(fd, F_SETLK, &fl) == -1) {
 
697
        return ERR_FCNTL;
 
698
    }
643
699
#endif
 
700
    locked = true;
 
701
    return 0;
644
702
}
645
703
 
646
704
int FILE_LOCK::unlock(const char* filename) {
 
705
    int retval = 0;
647
706
#if defined(_WIN32) && !defined(__CYGWIN32__)
648
707
    if (!CloseHandle(handle)) {
649
 
        perror("FILE_LOCK::unlock(): close failed.");
 
708
        retval = GetLastError();
650
709
    }
651
710
#else
652
711
    if (close(fd)) {
653
 
        perror("FILE_LOCK::unlock(): close failed.");
 
712
        retval = -1;
654
713
    }
 
714
    fd = -1;
655
715
#endif
656
716
    boinc_delete_file(filename);
 
717
    locked = false;
657
718
    return 0;
658
719
}
659
720
 
661
722
#ifdef _WIN32
662
723
    getcwd(path, 256);
663
724
#else
664
 
    char* p __attribute__ ((unused)) = getcwd(path, 256);
 
725
    char* p 
 
726
#ifdef __GNUC__
 
727
      __attribute__ ((unused))
 
728
#endif
 
729
      = getcwd(path, 256);
665
730
#endif
666
731
}
667
732
 
675
740
 
676
741
// get total and free space on current filesystem (in bytes)
677
742
//
678
 
int get_filesystem_info(double &total_space, double &free_space, char* path) {
679
743
#ifdef _WIN32
 
744
int get_filesystem_info(double &total_space, double &free_space, char*) {
680
745
    char buf[256];
681
746
    boinc_getcwd(buf);
682
747
    FreeFn pGetDiskFreeSpaceEx;
683
748
    pGetDiskFreeSpaceEx = (FreeFn)GetProcAddress(
684
 
        GetModuleHandle("kernel32.dll"), "GetDiskFreeSpaceExA"
 
749
        GetModuleHandleA("kernel32.dll"), "GetDiskFreeSpaceExA"
685
750
    );
686
751
    if (pGetDiskFreeSpaceEx) {
687
752
        ULARGE_INTEGER TotalNumberOfFreeBytes;
701
766
        DWORD dwBytesPerSect;
702
767
        DWORD dwFreeClusters;
703
768
        DWORD dwTotalClusters;
704
 
        GetDiskFreeSpace(
 
769
        GetDiskFreeSpaceA(
705
770
            buf, &dwSectPerClust, &dwBytesPerSect, &dwFreeClusters,
706
771
            &dwTotalClusters
707
772
        );
709
774
        total_space = (double)dwTotalClusters * dwSectPerClust * dwBytesPerSect;
710
775
    }
711
776
#else
 
777
int get_filesystem_info(double &total_space, double &free_space, char* path) {
712
778
#ifdef STATFS
713
779
    struct STATFS fs_info;
714
780
 
754
820
 
755
821
#endif
756
822
 
757
 
const char *BOINC_RCSID_636c8d709b = "$Id: filesys.cpp 16388 2008-11-02 20:09:59Z davea $";