* moved FbTk/Directory.cc/hh over to FbTk/FileUtil.cc/hh which contain now file and directory - helproutines. * created the FileUtil-namespace which contains file-related functions, moved those functions out of Directory - code * changes to the rest of the files to follow those changes
@@ -1,5 +1,5 @@
-// Directory.cc -// Copyright (c) 2002 - 2003 Henrik Kinnunen (fluxgen at users.sourceforge.net) +// FileUtil.cc +// Copyright (c) 2002 - 2004 Henrik Kinnunen (fluxgen at users.sourceforge.net) // // Permission is hereby granted, free of charge, to any person obtaining a // copy of this software and associated documentation files (the "Software"),@@ -21,13 +21,70 @@ // DEALINGS IN THE SOFTWARE.
// $Id$ -#include "Directory.hh" +#include "FileUtil.hh" #include <sys/stat.h> #include <unistd.h> +#include <iostream> +#include <fstream> + +using std::ifstream; +using std::ofstream; +using std::cerr; +using std::endl; + namespace FbTk { +time_t FileUtil::getLastStatusChangeTimestamp(const char* filename) { + struct stat buf; + if (filename && !stat(filename, &buf)) { + return buf.st_ctime; + } else + return (time_t)-1; +} + +bool FileUtil::isDirectory(const char* filename) { + struct stat buf; + if (!filename || stat(filename, &buf)) + return false; + + return S_ISDIR(buf.st_mode); +} + +bool FileUtil::isRegularFile(const char* filename) { + struct stat buf; + if (!filename || stat(filename, &buf)) + return false; + + return S_ISREG(buf.st_mode); +} + +bool FileUtil::isExecutable(const char* filename) { + struct stat buf; + if (!filename || !stat(filename, &buf)) + return false; + + return buf.st_mode & S_IXUSR || + buf.st_mode & S_IXGRP || + buf.st_mode & S_IXOTH; +} + +bool FileUtil::copyFile(const char* from, const char* to) { + ifstream from_file(from); + ofstream to_file(to); + + if (!to_file.good()) + cerr << "Can't write file '"<<to<<"'."<<endl; + else if (from_file.good()) { + to_file<<from_file.rdbuf(); + return true; + } else + cerr << "Can't copy from '"<<from<<"' to '"<<to<<"'."<<endl; + + return false; +} + Directory::Directory(const char *dir):m_dir(0), m_num_entries(0) { if (dir != 0)@@ -89,30 +146,5 @@
return true; } -bool Directory::isDirectory(const std::string &filename) { - struct stat statbuf; - if (stat(filename.c_str(), &statbuf) != 0) - return false; - - return S_ISDIR(statbuf.st_mode); -} - -bool Directory::isRegularFile(const std::string &filename) { - struct stat statbuf; - if (stat(filename.c_str(), &statbuf) != 0) - return false; - - return S_ISREG(statbuf.st_mode); -} - -bool Directory::isExecutable(const std::string &filename) { - struct stat statbuf; - if (stat(filename.c_str(), &statbuf) != 0) - return false; - - return statbuf.st_mode & S_IXUSR || - statbuf.st_mode & S_IXGRP || - statbuf.st_mode & S_IXOTH; -} }; // end namespace FbTk
@@ -1,5 +1,5 @@
-// Directory.hh -// Copyright (c) 2002 - 2003 Henrik Kinnunen (fluxgen at users.sourceforge.net) +// FileUtil.hh +// Copyright (c) 2002 - 2004 Henrik Kinnunen (fluxgen at users.sourceforge.net) // // Permission is hereby granted, free of charge, to any person obtaining a // copy of this software and associated documentation files (the "Software"),@@ -21,19 +21,49 @@ // DEALINGS IN THE SOFTWARE.
// $Id$ -#ifndef FBTK_DIRECTORY_HH -#define FBTK_DIRECTORY_HH +#ifndef FBTK_FILEUTIL_HH +#define FBTK_FILEUTIL_HH -#include "NotCopyable.hh" - +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif // HAVE_CONFIG_H +#ifdef HAVE_CTIME + #include <ctime> +#else + #include <time.h> +#endif #include <sys/types.h> #include <dirent.h> + #include <string> +#include "NotCopyable.hh" + namespace FbTk { +/// Wrapper for file routines + +namespace FileUtil { + + /// @return true if file is a directory + bool isDirectory(const char* filename); + /// @return true if a file is a regular file + bool isRegularFile(const char* filename); + /// @return true if a file executable for user + bool isExecutable(const char* filename); + + /// gets timestamp of last status change + /// @return timestamp + /// @return -1 (failure) + time_t getLastStatusChangeTimestamp(const char* filename); + + /// copies file 'from' to 'to' + bool copyFile(const char* from, const char* to); + +}; // end of File namespace + /// Wrapper class for DIR * routines -class Directory: private FbTk::NotCopyable { +class Directory : private FbTk::NotCopyable { public: explicit Directory(const char *dir = 0); ~Directory();@@ -52,12 +82,6 @@ /// @param dir the directory name
bool open(const char *dir); /// @return number of entries in the directory size_t entries() const { return m_num_entries; } - /// @return true if file is a directory - static bool isDirectory(const std::string &filename); - /// @return true if a file is a regular file - static bool isRegularFile(const std::string &filename); - /// @return true if a file executable for user - static bool isExecutable(const std::string &filename); private: std::string m_name;@@ -67,4 +91,4 @@ };
} // end namespace FbTk -#endif // FBTK_DIRECTORY_HH +#endif // FBTK_FILEUTIL_HH
@@ -13,7 +13,7 @@ xpm_SOURCE= ImageXPM.hh ImageXPM.cc
endif libFbTk_a_SOURCES = App.hh App.cc Color.cc Color.hh Command.hh \ - Directory.hh Directory.cc \ + FileUtil.hh FileUtil.cc \ EventHandler.hh EventManager.hh EventManager.cc \ FbWindow.hh FbWindow.cc Font.cc Font.hh FontImp.hh \ I18n.cc I18n.hh \
@@ -26,7 +26,7 @@
#include "XrmDatabaseHelper.hh" #include "App.hh" #include "StringUtil.hh" -#include "Directory.hh" +#include "FileUtil.hh" #include "I18n.hh" #include "Image.hh"@@ -87,14 +87,14 @@ bool ThemeManager::load(const std::string &filename, int screen_num) {
std::string location = FbTk::StringUtil::expandFilename(filename); std::string prefix = ""; - if (Directory::isDirectory(filename)) { + if (FileUtil::isDirectory(filename.c_str())) { prefix = location; location.append("/theme.cfg"); - if (!Directory::isRegularFile(location)) { + if (!FileUtil::isRegularFile(location.c_str())) { location = prefix; location.append("/style.cfg"); - if (!Directory::isRegularFile(location)) { + if (!FileUtil::isRegularFile(location.c_str())) { cerr<<"Error loading theme file "<<location<<": not a regular file"<<endl; return false; }
@@ -46,7 +46,7 @@ #include "FbTk/RefCount.hh"
#include "FbTk/MacroCommand.hh" #include "FbTk/SimpleCommand.hh" #include "FbTk/StringUtil.hh" -#include "FbTk/Directory.hh" +#include "FbTk/FileUtil.hh" #include "FbTk/MenuSeparator.hh" #include "FbTk/MenuIcon.hh"@@ -58,12 +58,12 @@ void LayerMenuItem<FluxboxWindow>::click(int button, int time) {
m_object->moveToLayer(m_layernum); } -static void createStyleMenu(FbTk::Menu &parent, const std::string &label, +static void createStyleMenu(FbTk::Menu &parent, const std::string &label, const std::string &directory) { // perform shell style ~ home directory expansion string stylesdir(FbTk::StringUtil::expandFilename(directory)); - if (!FbTk::Directory::isDirectory(stylesdir)) + if (!FbTk::FileUtil::isDirectory(stylesdir.c_str())) return; FbTk::Directory dir(stylesdir.c_str());@@ -81,25 +81,25 @@ for (size_t file_index = 0; file_index < dir.entries(); file_index++) {
std::string style(stylesdir + '/' + filelist[file_index]); // add to menu only if the file is a regular file, and not a // .file or a backup~ file - if ((FbTk::Directory::isRegularFile(style) && + if ((FbTk::FileUtil::isRegularFile(style.c_str()) && (filelist[file_index][0] != '.') && (style[style.length() - 1] != '~')) || - FbTk::Directory::isRegularFile(style + "/theme.cfg") || - FbTk::Directory::isRegularFile(style + "/style.cfg")) + FbTk::FileUtil::isRegularFile((style + "/theme.cfg").c_str()) || + FbTk::FileUtil::isRegularFile((style + "/style.cfg").c_str())) parent.insert(new StyleMenuItem(filelist[file_index], style)); - } + } // update menu graphics parent.updateMenu(); Fluxbox::instance()->saveMenuFilename(stylesdir.c_str()); } -static void createRootCmdMenu(FbTk::Menu &parent, const string &label, +static void createRootCmdMenu(FbTk::Menu &parent, const string &label, const string &directory, const string &cmd) { // perform shell style ~ home directory expansion string rootcmddir(FbTk::StringUtil::expandFilename(directory)); - if (!FbTk::Directory::isDirectory(rootcmddir)) + if (!FbTk::FileUtil::isDirectory(rootcmddir.c_str())) return; FbTk::Directory dir(rootcmddir.c_str());@@ -114,13 +114,13 @@ sort(filelist.begin(), filelist.end(), less<string>());
// for each file in directory add filename and path to menu for (size_t file_index = 0; file_index < dir.entries(); file_index++) { - + string rootcmd(rootcmddir+ '/' + filelist[file_index]); // add to menu only if the file is a regular file, and not a // .file or a backup~ file - if ((FbTk::Directory::isRegularFile(rootcmd) && + if ((FbTk::FileUtil::isRegularFile(rootcmd.c_str()) && (filelist[file_index][0] != '.') && - (rootcmd[rootcmd.length() - 1] != '~'))) + (rootcmd[rootcmd.length() - 1] != '~'))) parent.insert(new RootCmdMenuItem(filelist[file_index], rootcmd, cmd)); } // update menu graphics@@ -172,10 +172,10 @@ const std::string &str_label = pitem.label();
const int screen_number = menu.screenNumber(); _FB_USES_NLS; - + if (str_key == "end") { return; - } else if (str_key == "nop") { + } else if (str_key == "nop") { menu.insert(str_label.c_str()); } else if (str_key == "icons") { FbTk::Menu *submenu = MenuCreator::createMenuType("iconmenu", menu.screenNumber());@@ -195,7 +195,7 @@ } else if (str_key == "exec") {
// execute and hide menu using namespace FbTk; RefCount<Command> exec_cmd(CommandParser::instance().parseLine("exec " + str_cmd)); - RefCount<Command> hide_menu(new SimpleCommand<FbTk::Menu>(menu, + RefCount<Command> hide_menu(new SimpleCommand<FbTk::Menu>(menu, &Menu::hide)); MacroCommand *exec_and_hide = new FbTk::MacroCommand(); exec_and_hide->add(hide_menu);@@ -205,7 +205,7 @@ menu.insert(str_label.c_str(), exec_and_hide_cmd);
} else if (str_key == "macrocmd") { using namespace FbTk; RefCount<Command> macro_cmd(CommandParser::instance().parseLine("macrocmd " + str_cmd)); - RefCount<Command> hide_menu(new SimpleCommand<FbTk::Menu>(menu, + RefCount<Command> hide_menu(new SimpleCommand<FbTk::Menu>(menu, &Menu::hide)); MacroCommand *exec_and_hide = new FbTk::MacroCommand(); exec_and_hide->add(hide_menu);@@ -218,7 +218,7 @@ } else if (str_key == "config") {
BScreen *screen = Fluxbox::instance()->findScreen(screen_number); if (screen != 0) menu.insert(str_label.c_str(), &screen->configMenu()); - } // end of config + } // end of config else if (str_key == "include") { // include // this will make sure we dont get stuck in a loop@@ -229,7 +229,7 @@
safe_counter++; string newfile = FbTk::StringUtil::expandFilename(str_label); - if (FbTk::Directory::isDirectory(newfile)) { + if (FbTk::FileUtil::isDirectory(newfile.c_str())) { // inject every file in this directory into the current menu FbTk::Directory dir(newfile.c_str());@@ -241,7 +241,7 @@
for (size_t file_index = 0; file_index < dir.entries(); file_index++) { std::string thisfile(newfile + '/' + filelist[file_index]); - if (FbTk::Directory::isRegularFile(thisfile) && + if (FbTk::FileUtil::isRegularFile(thisfile.c_str()) && (filelist[file_index][0] != '.') && (thisfile[thisfile.length() - 1] != '~')) { MenuCreator::createFromFile(thisfile, menu, false);@@ -259,7 +259,7 @@ safe_counter--;
} // end of include else if (str_key == "submenu") { - + FbTk::Menu *submenu = MenuCreator::createMenu("", screen_number); if (submenu == 0) return;@@ -274,21 +274,21 @@ submenu->updateMenu();
menu.insert(str_label.c_str(), submenu); // save to screen list so we can delete it later BScreen *screen = Fluxbox::instance()->findScreen(screen_number); - if (screen != 0) + if (screen != 0) screen->saveMenu(*submenu); } // end of submenu else if (str_key == "stylesdir" || str_key == "stylesmenu") { - createStyleMenu(menu, str_label, + createStyleMenu(menu, str_label, str_key == "stylesmenu" ? str_cmd : str_label); } // end of stylesdir else if (str_key == "themesdir" || str_key == "themesmenu") { - createStyleMenu(menu, str_label, + createStyleMenu(menu, str_label, str_key == "themesmenu" ? str_cmd : str_label); } // end of themesdir - else if (str_key == "wallpapers" || str_key == "wallpapermenu" || + else if (str_key == "wallpapers" || str_key == "wallpapermenu" || str_key == "rootcommands") { - createRootCmdMenu(menu, str_label, str_label, + createRootCmdMenu(menu, str_label, str_label, str_cmd == "" ? "fbsetbg" : str_cmd); } // end of wallpapers else if (str_key == "workspaces") {@@ -353,8 +353,8 @@ BScreen *screen = Fluxbox::instance()->findScreen(screen_number);
if (screen == 0) return 0; - FbTk::Menu *menu = new FbMenu(screen->menuTheme(), - screen->imageControl(), + FbTk::Menu *menu = new FbMenu(screen->menuTheme(), + screen->imageControl(), *screen->layerManager(). getLayer(Fluxbox::instance()->getMenuLayer())); if (!label.empty())@@ -390,7 +390,7 @@
std::string label; if (require_begin && !getStart(parser, label)) return 0; - + FbTk::Menu *menu = createMenu(label, screen_number); if (menu != 0) parseMenu(parser, *menu);@@ -416,8 +416,8 @@ return true;
} -bool MenuCreator::createFromFile(const std::string &filename, - FbTk::Menu &inject_into, +bool MenuCreator::createFromFile(const std::string &filename, + FbTk::Menu &inject_into, FluxboxWindow &win, bool require_begin) { std::string real_filename = FbTk::StringUtil::expandFilename(filename); FbMenuParser parser(real_filename);@@ -446,7 +446,7 @@ }
return 0; } -bool MenuCreator::createWindowMenuItem(const std::string &type, +bool MenuCreator::createWindowMenuItem(const std::string &type, const std::string &label, FbTk::Menu &menu, FluxboxWindow &win) {@@ -502,10 +502,10 @@ } else if (type == "layer") {
BScreen *screen = Fluxbox::instance()->findScreen(menu.screenNumber()); if (screen == 0) return false; - FbTk::Menu *submenu = new LayerMenu<FluxboxWindow>(screen->menuTheme(), - screen->imageControl(), + FbTk::Menu *submenu = new LayerMenu<FluxboxWindow>(screen->menuTheme(), + screen->imageControl(), *screen->layerManager(). - getLayer(Fluxbox::instance()->getMenuLayer()), + getLayer(Fluxbox::instance()->getMenuLayer()), &win, false); submenu->disableTitle();
@@ -38,6 +38,7 @@ #include "defaults.hh"
#include "FbTk/I18n.hh" #include "FbTk/Image.hh" +#include "FbTk/FileUtil.hh" #include "FbTk/KeyUtil.hh" #include "FbTk/ImageControl.hh" #include "FbTk/EventManager.hh"@@ -151,24 +152,11 @@
using namespace std; using namespace FbTk; -static Window last_bad_window = None; namespace { -void copyFile(const std::string &from, const std::string &to) { - ifstream from_file(from.c_str()); - ofstream to_file(to.c_str()); - if (! to_file.good()) { - cerr<<"Can't write file: "<<to<<endl; - } else if (from_file.good()) { - to_file<<from_file.rdbuf(); //copy file - } else { - cerr<<"Can't copy from "<<from<<" to "<<to<<endl; - } -} - -} // end anonymous - -static int handleXErrors(Display *d, XErrorEvent *e) { +Window last_bad_window = None; + +int handleXErrors(Display *d, XErrorEvent *e) { if (e->error_code == BadWindow) last_bad_window = e->resourceid; #ifdef DEBUG@@ -183,10 +171,10 @@ (int)e->request_code<<"/"<<(int)e->minor_code<<" resource 0x"<<hex<<(int)e->resourceid<<dec<<endl;
} #endif // !DEBUG - return False; } +} // end anonymous //static singleton var Fluxbox *Fluxbox::s_singleton=0;@@ -573,15 +561,15 @@
// copy key configuration if (create_keys) - copyFile(DEFAULTKEYSFILE, keys_file); + FbTk::FileUtil::copyFile(DEFAULTKEYSFILE, keys_file.c_str()); // copy menu configuration if (create_menu) - copyFile(DEFAULTMENU, menu_file); + FbTk::FileUtil::copyFile(DEFAULTMENU, menu_file.c_str()); // copy init file if (create_init) - copyFile(DEFAULT_INITFILE, init_file); + FbTk::FileUtil::copyFile(DEFAULT_INITFILE, init_file.c_str()); }@@ -1644,10 +1632,11 @@ bool Fluxbox::menuTimestampsChanged() const {
std::list<MenuTimestamp *>::const_iterator it = m_menu_timestamps.begin(); std::list<MenuTimestamp *>::const_iterator it_end = m_menu_timestamps.end(); for (; it != it_end; ++it) { - struct stat buf; + + time_t timestamp = FbTk::FileUtil::getLastStatusChangeTimestamp((*it)->filename.c_str()); - if (! stat((*it)->filename.c_str(), &buf)) { - if ((*it)->timestamp != buf.st_ctime) + if (timestamp >= 0) { + if (timestamp != (*it)->timestamp) return true; } else return true;@@ -1683,13 +1672,12 @@ }
void Fluxbox::real_rereadMenu() { - std::list<MenuTimestamp *>::iterator it = m_menu_timestamps.begin(); - std::list<MenuTimestamp *>::iterator it_end = m_menu_timestamps.end(); - for (; it != it_end; ++it) - delete *it; - - m_menu_timestamps.erase(m_menu_timestamps.begin(), m_menu_timestamps.end()); - for_each(m_screen_list.begin(), m_screen_list.end(), mem_fun(&BScreen::rereadMenu)); + + clearMenuFilenames(); + + for_each(m_screen_list.begin(), + m_screen_list.end(), + mem_fun(&BScreen::rereadMenu)); if(m_show_menu_after_reread) {@@ -1716,13 +1704,13 @@ }
} if (! found) { - struct stat buf; + time_t timestamp = FbTk::FileUtil::getLastStatusChangeTimestamp(filename); - if (! stat(filename, &buf)) { + if (timestamp >= 0) { MenuTimestamp *ts = new MenuTimestamp; ts->filename = filename; - ts->timestamp = buf.st_ctime; + ts->timestamp = timestamp; m_menu_timestamps.push_back(ts); }@@ -1730,12 +1718,10 @@ }
} void Fluxbox::clearMenuFilenames() { - std::list<MenuTimestamp *>::iterator it = m_menu_timestamps.begin(); - std::list<MenuTimestamp *>::iterator it_end = m_menu_timestamps.end(); - for (; it != it_end; ++it) - delete *it; - - m_menu_timestamps.erase(m_menu_timestamps.begin(), m_menu_timestamps.end()); + while(!m_menu_timestamps.empty()) { + delete m_menu_timestamps.back(); + m_menu_timestamps.pop_back(); + } } void Fluxbox::timed_reconfigure() {
@@ -27,7 +27,7 @@ #include "App.hh"
#include "EventManager.hh" #include "Color.hh" #include "KeyUtil.hh" -#include "Directory.hh" +#include "FileUtil.hh" #ifdef HAVE_CONFIG_H #include "config.h"@@ -393,18 +393,18 @@ (*dir.name().rbegin() != '/' ? "/" : "") +
filename; // directories in dirmode ? - if (add_dirs && dir.isDirectory(fncomplete) && + if (add_dirs && FbTk::FileUtil::isDirectory(fncomplete.c_str()) && filename != ".." && filename != ".") { m_apps.push_back(fncomplete); // executables in dirmode ? - } else if (add_dirs && dir.isRegularFile(fncomplete) && - dir.isExecutable(fncomplete) && + } else if (add_dirs && FbTk::FileUtil::isRegularFile(fncomplete.c_str()) && + FbTk::FileUtil::isExecutable(fncomplete.c_str()) && (prefix == "" || fncomplete.substr(0, prefix.size()) == prefix)) { m_apps.push_back(fncomplete); // executables in $PATH ? - } else if (dir.isRegularFile(fncomplete) && - dir.isExecutable(fncomplete) && + } else if (FbTk::FileUtil::isRegularFile(fncomplete.c_str()) && + FbTk::FileUtil::isExecutable(fncomplete.c_str()) && (prefix == "" || filename.substr(0, prefix.size()) == prefix)) { m_apps.push_back(filename);@@ -440,7 +440,7 @@ break;
} if (m_apps[apps_item].find(prefix) == 0) { m_current_apps_item = apps_item; - if (add_dirs && FbTk::Directory::isDirectory(m_apps[m_current_apps_item])) + if (add_dirs && FbTk::FileUtil::isDirectory(m_apps[m_current_apps_item].c_str())) setText(m_apps[m_current_apps_item] + "/"); else setText(m_apps[m_current_apps_item]);