1 ////////////////////////////////////////////////////////////////////////
2 // FILE: fileutils.cpp
3 // AUTHOR: Johannes Winkelmann, jw@tks6.net
4 // COPYRIGHT: (c) 2002-2005 by Johannes Winkelmann
5 // ---------------------------------------------------------------------
6 // This program is free software; you can redistribute it and/or modify
7 // it under the terms of the GNU General Public License as published by
8 // the Free Software Foundation; either version 2 of the License, or
9 // (at your option) any later version.
10 ////////////////////////////////////////////////////////////////////////
11
12 #include <sys/types.h>
13 #include <sys/stat.h>
14 #include <unistd.h>
15 #include <dirent.h>
16 #include <iostream>
17 #include <cstring>
18 #include <algorithm>
19
20 #include "md5.h"
21 #include "httpup.h"
22 #include "fileutils.h"
23
24 using namespace std;
25
26 int FileUtils::deltree(const char* directory)
27 {
28 int ret = 0;
29
30 struct stat info;
31 if (stat(directory, &info)) {
32 // already removed
33 return 0;
34 }
35 if (!S_ISDIR(info.st_mode)) {
36 return unlink(directory);
37 }
38
39 DIR* dir = opendir(directory);
40 struct dirent* entry;
41 while ((entry = readdir(dir)) != 0) {
42 if (entry->d_name[0] == '.' &&
43 (entry->d_name[1] == '.' || entry->d_name[1] == '\0')) {
44 continue;
45 }
46 struct stat info;
47 string pathName = string(directory) + "/" + string(entry->d_name);
48 if (stat(pathName.c_str(), &info) != 0) {
49 cout << entry->d_name << endl;
50 return -1;
51 }
52 if (S_ISDIR(info.st_mode)) {
53 if (deltree(pathName.c_str())) {
54 ret = -1;
55 }
56 rmdir(pathName.c_str());
57 } else {
58 if (unlink(pathName.c_str())) {
59 ret = -1;
60 }
61 }
62 }
63 closedir(dir);
64 if (rmdir(directory)) {
65 ret = -1;
66 }
67
68 return ret;
69 }
70
71 int FileUtils::mktree(const string& directory)
72 {
73 int ret = 0;
74 size_t pos = 0;
75 string fName;
76 while ((pos = directory.find( '/', pos+1)) != string::npos ) {
77 fName = directory.substr(0, pos);
78 struct stat info;
79 if (stat(fName.c_str(), &info)) {
80 if (mkdir(fName.c_str(), 0755)) {
81 ret = -1;
82 }
83 }
84 }
85
86 return ret;
87 }
88
89
90 bool FileUtils::fmd5sum(const string& fileName, unsigned char* result)
91 {
92 struct md5_context ctx;
93 unsigned char buffer[1000];
94
95 FILE* f = fopen(fileName.c_str(), "r");
96 if (!f) {
97 return false;
98 }
99 md5_starts( &ctx );
100 int i = 0;
101 while( ( i = fread( buffer, 1, sizeof( buffer ), f ) ) > 0 ) {
102 md5_update( &ctx, buffer, i );
103 }
104 fclose(f);
105
106 md5_finish( &ctx, result );
107 return true;
108 }
109
110 void FileUtils::listFiles(const string& target)
111 {
112 list<string> files;
113 string newTarget = target;
114
115 if (newTarget != ".") {
116 if (newTarget[newTarget.length()-1] != '/') {
117 newTarget += "/";
118 }
119 }
120
121 string repoFile = newTarget + "/" + HttpUp::REPOCURRENTFILE;
122 FILE* fp = fopen(repoFile.c_str(), "r");
123 if (fp) {
124 char line[512];
125 while (fgets(line, 512, fp)) {
126 line[strlen(line)-1] = '\0';
127 files.push_back(line);
128 }
129 fclose(fp);
130
131 listFilesRec(newTarget, "", files);
132 } else {
133 cerr << "Failed to open " << repoFile << endl;
134 }
135 }
136
137 void FileUtils::listFilesRec(const string& base,
138 const string& offset,
139 list<string>& files)
140 {
141 string newOff = offset;
142 if (newOff.length() > 0) {
143 newOff += "/";
144 }
145
146 DIR* dir = opendir((base + newOff).c_str());
147 if (dir) {
148 struct dirent* d;
149 string name;
150 while ((d = readdir(dir))) {
151
152 name = d->d_name;
153 if (name == HttpUp::REPOCURRENTFILE ||
154 name == HttpUp::URLINFO ||
155 name == "." || name == "..") {
156 continue;
157 }
158
159 if (find(files.begin(), files.end(),
160 newOff + d->d_name) == files.end()) {
161 cout << "? ";
162 } else {
163 cout << "= ";
164 }
165 cout << newOff
166 << d->d_name << endl;
167
168 struct stat buf;
169 if (stat(((base + newOff) + d->d_name).c_str(), &buf) == 0 &&
170 S_ISDIR(buf.st_mode)) {
171 listFilesRec(base, newOff + d->d_name, files);
172 }
173 }
174
175 closedir(dir);
176 }
177 }
|