summaryrefslogtreecommitdiff
path: root/fileutils.cpp
blob: 0d993c40a7a6808fdd5e60369309e8c9a1635602 (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 
   18 #include "md5.h"
   19 #include "httpup.h"
   20 #include "fileutils.h"
   21 
   22 using namespace std;
   23 
   24 int FileUtils::deltree(const char* directory)
   25 {
   26     int ret = 0;
   27 
   28     struct stat info;
   29     if (stat(directory, &info)) {
   30         // already removed
   31         return 0;
   32     }
   33     if (!S_ISDIR(info.st_mode)) {
   34         return unlink(directory);
   35     }
   36 
   37     DIR* dir = opendir(directory);
   38     struct dirent* entry;
   39     while ((entry = readdir(dir)) != 0) {
   40         if (entry->d_name[0] == '.' &&
   41             (entry->d_name[1] == '.' || entry->d_name[1] == '\0')) {
   42             continue;
   43         }
   44         struct stat info;
   45         string pathName = string(directory) + "/" + string(entry->d_name);
   46         if (stat(pathName.c_str(), &info) != 0) {
   47             cout << entry->d_name << endl;
   48             return -1;
   49         }
   50         if (S_ISDIR(info.st_mode)) {
   51             if (deltree(pathName.c_str())) {
   52                 ret = -1;
   53             }
   54             rmdir(pathName.c_str());
   55         } else {
   56             if (unlink(pathName.c_str())) {
   57                 ret = -1;
   58             }
   59         }
   60     }
   61     closedir(dir);
   62     if (rmdir(directory)) {
   63         ret = -1;
   64     }
   65 
   66     return ret;
   67 }
   68 
   69 int FileUtils::mktree(const string& directory)
   70 {
   71     int ret = 0;
   72     size_t pos = 0;
   73     string fName;
   74     while ((pos = directory.find( '/', pos+1)) != string::npos ) {
   75         fName = directory.substr(0, pos);
   76         struct stat info;
   77         if (stat(fName.c_str(), &info)) {
   78             if (mkdir(fName.c_str(), 0755)) {
   79                 ret = -1;
   80             }
   81         }
   82     }
   83 
   84     return ret;
   85 }
   86 
   87 
   88 bool FileUtils::fmd5sum(const string& fileName, unsigned char* result)
   89 {
   90     struct md5_context ctx;
   91     unsigned char buffer[1000];
   92 
   93     FILE* f = fopen(fileName.c_str(), "r");
   94     if (!f) {
   95         return false;
   96     }
   97     md5_starts( &ctx );
   98     int i = 0;
   99     while( ( i = fread( buffer, 1, sizeof( buffer ), f ) ) > 0 ) {
  100         md5_update( &ctx, buffer, i );
  101     }
  102     fclose(f);
  103 
  104     md5_finish( &ctx, result );
  105     return true;
  106 }
  107 
  108 void FileUtils::listFiles(const string& target)
  109 {
  110     list<string> files;
  111     string newTarget = target;
  112 
  113     if (newTarget != ".") {
  114         if (newTarget[newTarget.length()-1] != '/') {
  115             newTarget += "/";
  116         }
  117     }
  118 
  119     string repoFile = newTarget + "/" + HttpUp::REPOCURRENTFILE;
  120     FILE* fp = fopen(repoFile.c_str(), "r");
  121     if (fp) {
  122         char line[512];
  123         while (fgets(line, 512, fp)) {
  124             line[strlen(line)-1] = '\0';
  125             files.push_back(line);
  126         }
  127         fclose(fp);
  128 
  129         listFilesRec(newTarget, "", files);
  130     } else {
  131         cerr << "Failed to open " << repoFile << endl;
  132     }
  133 }
  134 
  135 void FileUtils::listFilesRec(const string& base,
  136                              const string& offset,
  137                              list<string>& files)
  138 {
  139     string newOff = offset;
  140     if (newOff.length() > 0) {
  141         newOff += "/";
  142     }
  143 
  144     DIR* dir = opendir((base + newOff).c_str());
  145     if (dir) {
  146         struct dirent* d;
  147         string name;
  148         while ((d = readdir(dir))) {
  149 
  150             name = d->d_name;
  151             if (name == HttpUp::REPOCURRENTFILE ||
  152                 name == HttpUp::URLINFO ||
  153                 name == "." || name == "..") {
  154                 continue;
  155             }
  156 
  157             if (find(files.begin(), files.end(),
  158                      newOff + d->d_name) == files.end()) {
  159                 cout << "? ";
  160             } else {
  161                 cout << "= ";
  162             }
  163             cout << newOff
  164                  << d->d_name << endl;
  165 
  166             struct stat buf;
  167             if (stat(((base + newOff) + d->d_name).c_str(), &buf) == 0 &&
  168                 S_ISDIR(buf.st_mode)) {
  169                 listFilesRec(base, newOff + d->d_name, files);
  170             }
  171         }
  172 
  173         closedir(dir);
  174     }
  175 }

Generated by cgit