summaryrefslogtreecommitdiff
path: root/fileutils.cpp
blob: 860df14068320a1c8052dcc1d3004957d6964309 (plain)
    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 }

Generated by cgit