bbsmount.cc
来自「蒙特卡洛仿真源代码很有参考价值要按照步骤进行操作」· CC 代码 · 共 1,127 行 · 第 1/3 页
CC
1,127 行
// bbsmount.cc for bbsmount - an tool for simple mounting in X11//// Copyright (c) 2001 by Miroslav Jezbera, jezberam@phoenix.inf.upol.cz//// This program is free software; you can redistribute it and/or modify// it under the terms of the GNU General Public License as published by// the Free Software Foundation; either version 2 of the License, or// (at your option) any later version.//// This program is distributed in the hope that it will be useful,// but WITHOUT ANY WARRANTY; without even the implied warranty of// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the// GNU General Public License for more details.//// You should have received a copy of the GNU General Public License// along with this program; if not, write to the Free Software// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.//// (See the included file COPYING / GPL-2.0)//#ifdef HAVE_CONFIG_H# include "config.h"#endif /* HAVE_CONFIG_H */#include <stdio.h>#if STDC_HEADERS# include <stdlib.h># include <string.h>#endif /* STDC_HEADERS */#if HAVE_SIGNAL_H# include <signal.h>#endif /* HAVE_SIGNAL_H */#ifdef TIME_WITH_SYS_TIME# include <time.h># include <sys/time.h>#else /* !TIME_WITH_SYS_TIME */# include <time.h>#endif /* !TIME_WITH_SYS_TIME */#if HAVE_SYS_PARAM_H# include <sys/param.h>#endif /* HAVE_SYS_PARAM_H */#if HAVE_SYS_MOUNT_H# include <sys/mount.h>#endif /* HAVE_SYS_MOUNT_H */#if HAVE_SYS_STATFS_H# include <sys/statfs.h>#endif /* HAVE_SYS_STATFS_H */#if HAVE_SYS_STATVFS_H# include <sys/statvfs.h>#endif /* HAVE_SYS_STATVFS_H */#include <pthread.h>#include <iostream>#include <fstream>#include "bbsmount.hh"#include "i18n.hh"#include "version.h"#include "images/notfound.xpm"#define USE_LARGER_UNIT(x) ((x) > 4096)#define BUFFER_SIZE 1024#if HAVE_STATVFS# define STATFS statvfs#elif HAVE_STATFS# define STATFS statfs#endif /* HAVE_STATVFS */// Global variablesToolWindow *AppWindow;I18n i18n;BToolTip tooltip;bool finish_checking, do_reconfigure = false, is_statfs_filled = false;string mount_point;struct STATFS tooltip_statfs;int debug_level;// Functionsintrun_command_and_report_error(const char *command, string &err_msg){ string err_command = command, tmp_file; int result; char buffer[BUFFER_SIZE]; strcpy(buffer, "/tmp/."PACKAGE".XXXXXX");#if HAVE_MKSTEMP result = mkstemp(buffer); if (result == -1) perror("mkstemp"); else close(result);#elif HAVE_TMPNAM if (!tmpnam(buffer)) perror("tmpnam");#else /* !HAVE_TMPNAM && !HAVE_MKSTEMP */ if (!mktemp(buffer)) perror("mktemp");#endif /* !HAVE_TMPNAM && !HAVE_MKSTEMP */ tmp_file = buffer; err_command += " 2>"; err_command += tmp_file; result = system(err_command.c_str()); if (result) { ifstream err_file(tmp_file.c_str()); err_msg.erase(); do { err_file.read(buffer, BUFFER_SIZE); err_msg.append(buffer, err_file.gcount()); } while (err_file); } if (remove(tmp_file.c_str())) perror("remove"); return result;}void *run_command(void *data){ command_data_type *cd = (command_data_type *)data; int retval; string err_msg; cd->mp->Lock(); retval = run_command_and_report_error(cd->command, err_msg); if (retval == -1) cd->mp->setLastError(err_msg); else cd->mp->clearError(); free(cd->command); cd->mp->Unlock(); free(cd); pthread_exit(NULL); return NULL; // Never reached}intrun_command_in_foreground(const char *command, MountPoint &mp){ int retval; string err_msg; if (strlen(command) == 0) return 0; retval = run_command_and_report_error(command, err_msg); if (retval == -1) mp.setLastError(err_msg); else mp.clearError(); return retval;}intrun_command_in_background(const char *command, MountPoint &mp){ if (strlen(command) == 0) return 0; char *str = strdup(command); // prevents change and compiler warnings command_data_type *data; int retval = 0; pthread_t run; pthread_attr_t attribs; data = (command_data_type *)malloc(sizeof(command_data_type)); if (data == NULL) { fprintf(stderr, "bbsmount: Memory allocation failed!\n"); return -1; } data->command = str; data->mp = ∓ if (pthread_attr_init(&attribs) != 0) { perror("pthread_attr_init"); return -1; } if (pthread_attr_setdetachstate(&attribs, PTHREAD_CREATE_DETACHED) != 0) { perror("pthread_attr_setdetachstate"); pthread_attr_destroy(&attribs); return -1; } if (pthread_create(&run, &attribs, run_command, (void *)data) != 0) { perror("pthread_create"); retval = -1; } if (pthread_attr_destroy(&attribs) != 0) perror("pthread_attr_destroy"); return retval;}set<int>what_is_mounted(const map<string, int> &mount_points){ set<int> result; map<string, int>::const_iterator pointer; char buffer[max_mtab_line_length], md[max_mount_device_point_size], mp[max_mount_device_point_size]; FILE *mtab;#if READ_MOUNT mtab = popen(MOUNT_COMMAND, "r"); if (!mtab) { fprintf(stderr, "Can't read output from mount command!"); return result; }#else /* !READ_MOUNT */ mtab = fopen(MTAB_FILE, "rt"); if (!mtab) { fprintf(stderr, "Can't open mtab file!"); return result; }#endif /* !READ_MOUNT */ while (!feof(mtab)) { if (fgets(buffer, max_mtab_line_length, mtab) > 0) {#if READ_MOUNT sscanf(buffer, "%s on %s", md, mp);#else /* !READ_MOUNT */ sscanf(buffer, "%s %s", md, mp);#endif /* !READ_MOUNT */ pointer = mount_points.find(string(mp)); if (pointer != mount_points.end()) result.insert(pointer->second); } } #if READ_MOUNT pclose(mtab);#else /* !READ_MOUNT */ fclose(mtab);#endif /* !READ_MOUNT */ return result;}boolupdate_mount_points(const map<string, int> &mount_points){ set<int> result; size_t count = AppWindow->GetMountPointsCount(); bool change = false; int counter; result = what_is_mounted(mount_points); for (counter = 0; counter < (int)count; counter++) if (AppWindow->GetMountPoint(counter).IsMounted() != (result.find(counter) != result.end())) { AppWindow->GetMountPoint(counter).SetMounted(result.find(counter) != result.end()); change = true; } return change;}voidcreate_notify_event(void){ XEvent event; memset((void *)&event, 0, sizeof(XExposeEvent)); event.type = Expose; /* How can I notify my thread waiting in XNextEvent, that there is some work ? */ event.xexpose.window = AppWindow->GetRootWindow(); event.xexpose.display = AppWindow->getXDisplay(); event.xexpose.send_event = True; XSendEvent(AppWindow->getXDisplay(), AppWindow->GetRootWindow(), False, NoEventMask, &event); XFlush(AppWindow->getXDisplay());}void *check_mounts(void *param){#if !READ_MOUNT struct stat info; int mtab_size = 0; time_t mtab_time = time(NULL);#endif /* !READ_MOUNT */ int return_value, counter; map<string, int> mount_points; struct STATFS new_stats; for (counter = 0; counter < (int)AppWindow->GetMountPointsCount(); counter++) mount_points[AppWindow->GetMountPoint(counter).GetMountPoint()] = counter; while (!finish_checking) {#if READ_MOUNT if (update_mount_points(mount_points)) create_notify_event();#else /* !READ_MOUNT */ stat(MTAB_FILE, &info); if ((difftime(info.st_mtime, mtab_time) > 0) || (mtab_size != info.st_size)) { mtab_size = info.st_size; mtab_time = info.st_mtime; if (update_mount_points(mount_points)) create_notify_event(); }#endif /* !READ_MOUNT */ if (is_statfs_filled) { if (STATFS(mount_point.c_str(), &new_stats) != 0) perror("Can't get filesystem info!"); else { if (new_stats.f_bfree != tooltip_statfs.f_bfree || new_stats.f_bavail != tooltip_statfs.f_bavail) { memcpy((void *)&tooltip_statfs, (void *)&new_stats, sizeof(struct STATFS)); AppWindow->updateTooltip(); } } } return_value = sleep(AppWindow->GetResources()->app.refresh_time); if (return_value != 0) finish_checking = true; } pthread_exit(NULL); return NULL;}RETSIGTYPEshutdown(int signal){#if DEBUG if (debug_level >= dbg_all_work) printf("Stopping bbsmount.\n");#endif finish_checking = true; do_reconfigure = false; AppWindow->Stop(); create_notify_event();}RETSIGTYPEusersignal(int signal){#if DEBUG if (debug_level >= dbg_all_work) printf("Reconfiguring bbsmount.\n");#endif AppWindow->reconfigure();}ToolWindow::ToolWindow(int argc,char **argv,struct CMDOPTIONS *options) : Basewindow(argc,argv,options){ XrmInitialize(); resource = new Resource(this); CreateWindow(false); configure(); stop = false; tooltip_for_mp = NULL;}ToolWindow::~ToolWindow(void){ XUnmapSubwindows(getXDisplay(), rootwin); FreeAll(); XUnmapWindow(getXDisplay(), rootwin); /* destroy pixmaps */ if (pixmap.frame) getImageControl()->removeImage(pixmap.frame); if (pixmap.draw) getImageControl()->removeImage(pixmap.draw); if (pixmap.draw_pressed) getImageControl()->removeImage(pixmap.draw_pressed); delete resource; XDestroyWindow(getXDisplay(), rootwin); XFlush(getXDisplay());} const MyImage &ToolWindow::GetImage(const int imageidx) const{ return *images[imageidx];}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?