18cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd/** 28cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd * @file oprof_start_util.cpp 38cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd * Miscellaneous helpers for the GUI start 48cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd * 58cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd * @remark Copyright 2002 OProfile authors 68cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd * @remark Read the file COPYING 78cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd * 88cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd * @author Philippe Elie 98cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd * @author John Levon 108cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd */ 118cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 128cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd#include <dirent.h> 138cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd#include <unistd.h> 148cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd#include <glob.h> 158cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 168cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd#include <cerrno> 178cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd#include <vector> 188cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd#include <cmath> 198cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd#include <sstream> 208cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd#include <iostream> 218cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd#include <fstream> 228cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd#include <cstdlib> 238cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 248cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd#include <qfiledialog.h> 258cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd#include <qmessagebox.h> 268cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 278cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd#include "op_file.h" 288cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd#include "file_manip.h" 298cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd#include "child_reader.h" 308cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd#include "op_libiberty.h" 318cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 328cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd#include "oprof_start.h" 338cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd#include "oprof_start_util.h" 348cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 358cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Doddusing namespace std; 368cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 378cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Doddnamespace { 388cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 398cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd// return the ~ expansion suffixed with a '/' 408cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Doddstring const get_config_dir() 418cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd{ 428cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd return "/root"; 438cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd} 448cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 458cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Doddstring daemon_pid; 468cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 478cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd} // namespace anon 488cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 498cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodddaemon_status::daemon_status() 508cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd : running(false), 518cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd nr_interrupts(0) 528cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd{ 538cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd int HZ; 548cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd if (!daemon_pid.empty()) { 558cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd string proc_filename = string("/proc/") + daemon_pid + "/exe"; 568cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd string const exec = op_realpath(proc_filename); 578cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd if (exec == proc_filename) 588cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd daemon_pid.erase(); 598cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd else 608cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd running = true; 618cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd } 628cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 638cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd if (daemon_pid.empty()) { 648cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd DIR * dir; 658cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd struct dirent * dirent; 668cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 678cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd if (!(dir = opendir("/proc"))) { 688cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd perror("oprofiled: /proc directory could not be opened. "); 698cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd exit(EXIT_FAILURE); 708cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd } 718cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 728cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd while ((dirent = readdir(dir))) { 738cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd string const exec = 748cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd op_realpath(string("/proc/") 758cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd + dirent->d_name + "/exe"); 768cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd string const name = op_basename(exec); 778cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd if (name != "oprofiled") 788cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd continue; 798cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 808cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd daemon_pid = dirent->d_name; 818cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd running = true; 828cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd } 838cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 848cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd closedir(dir); 858cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd } 868cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 878cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd HZ = sysconf(_SC_CLK_TCK); 888cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd if (HZ == -1) { 898cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd perror("oprofiled: Unable to determine clock ticks per second. "); 908cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd exit(EXIT_FAILURE); 918cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd } 928cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 938cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd if (daemon_pid.empty()) 948cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd return; 958cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 968cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd nr_interrupts = 0; 978cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 988cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd switch (op_get_interface()) { 998cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd case OP_INTERFACE_24: 1008cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd { 1018cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd ifstream ifs3("/proc/sys/dev/oprofile/nr_interrupts"); 1028cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd if (ifs3) 1038cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd ifs3 >> nr_interrupts; 1048cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd } 1058cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd break; 1068cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd case OP_INTERFACE_26: 1078cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd { 1088cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd static unsigned int old_sum_interrupts; 1098cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd unsigned int sum_interrupts = 0; 1108cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd glob_t file_names; 1118cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 1128cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd file_names.gl_offs = 0; 1138cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd glob("/dev/oprofile/stats/cpu*/sample_received", 1148cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd GLOB_DOOFFS, NULL, &file_names); 1158cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 1168cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd for (size_t i = 0; i < file_names.gl_pathc; ++i) { 1178cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd ifstream ifs3(file_names.gl_pathv[i]); 1188cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd if (ifs3) { 1198cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd unsigned int file_interrupts; 1208cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd ifs3 >> file_interrupts; 1218cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd sum_interrupts += file_interrupts; 1228cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd } 1238cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd } 1248cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd if (old_sum_interrupts > sum_interrupts) 1258cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd // occur if we stop/restart daemon. 1268cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd old_sum_interrupts = 0; 1278cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd nr_interrupts = sum_interrupts - old_sum_interrupts; 1288cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd old_sum_interrupts = sum_interrupts; 1298cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd globfree(&file_names); 1308cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd } 1318cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd break; 1328cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd default: 1338cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd break; 1348cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd } 1358cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd} 1368cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 1378cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 1388cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd/** 1398cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd * get_config_filename - get absolute filename of file in user $HOME 1408cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd * @param filename the relative filename 1418cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd * 1428cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd * Get the absolute path of a file in a user's home directory. 1438cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd */ 1448cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Doddstring const get_config_filename(string const & filename) 1458cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd{ 1468cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd return get_config_dir() + "/" + filename; 1478cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd} 1488cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 1498cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 1508cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd/** 1518cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd * check_and_create_config_dir - make sure config dir is accessible 1528cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd * 1538cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd * Returns %true if the dir is accessible. 1548cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd */ 1558cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Doddbool check_and_create_config_dir() 1568cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd{ 1578cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd string dir = get_config_filename(".oprofile"); 1588cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 1598cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd char * name = xstrdup(dir.c_str()); 1608cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 1618cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd if (create_dir(name)) { 1628cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd ostringstream out; 1638cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd out << "unable to create " << dir << " directory "; 1648cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd out << "cause: " << strerror(errno); 1658cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd QMessageBox::warning(0, 0, out.str().c_str()); 1668cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 1678cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd free(name); 1688cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 1698cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd return false; 1708cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd } 1718cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 1728cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd free(name); 1738cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd return true; 1748cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd} 1758cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 1768cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 1778cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd/** 1788cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd * format - re-format a string 1798cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd * @param orig string to format 1808cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd * @param maxlen width of line 1818cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd * 1828cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd * Re-formats a string to fit into a certain width, 1838cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd * breaking lines at spaces between words. 1848cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd * 1858cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd * Returns the formatted string 1868cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd */ 1878cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Doddstring const format(string const & orig, uint const maxlen) 1888cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd{ 1898cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd string text(orig); 1908cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 1918cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd istringstream ss(text); 1928cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd vector<string> lines; 1938cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 1948cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd string oline; 1958cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd string line; 1968cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 1978cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd while (getline(ss, oline)) { 1988cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd if (line.size() + oline.size() < maxlen) { 1998cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd lines.push_back(line + oline); 2008cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd line.erase(); 2018cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd } else { 2028cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd lines.push_back(line); 2038cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd line.erase(); 2048cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd string s; 2058cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd string word; 2068cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd istringstream oss(oline); 2078cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd while (oss >> word) { 2088cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd if (line.size() + word.size() > maxlen) { 2098cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd lines.push_back(line); 2108cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd line.erase(); 2118cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd } 2128cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd line += word + " "; 2138cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd } 2148cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd } 2158cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd } 2168cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 2178cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd if (line.size()) 2188cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd lines.push_back(line); 2198cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 2208cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd string ret; 2218cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 2228cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd for(vector<string>::const_iterator it = lines.begin(); it != lines.end(); ++it) 2238cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd ret += *it + "\n"; 2248cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 2258cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd return ret; 2268cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd} 2278cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 2288cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 2298cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd/** 2308cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd * do_exec_command - execute a command 2318cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd * @param cmd command name 2328cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd * @param args arguments to command 2338cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd * 2348cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd * Execute a command synchronously. An error message is shown 2358cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd * if the command returns a non-zero status, which is also returned. 2368cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd * 2378cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd * The arguments are verified and will refuse to execute if they contain 2388cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd * shell metacharacters. 2398cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd */ 2408cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Doddint do_exec_command(string const & cmd, vector<string> const & args) 2418cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd{ 2428cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd ostringstream err; 2438cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd bool ok = true; 2448cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 2458cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd // verify arguments 2468cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd for (vector<string>::const_iterator cit = args.begin(); 2478cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd cit != args.end(); ++cit) { 2488cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd if (verify_argument(*cit)) 2498cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd continue; 2508cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 2518cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd QMessageBox::warning(0, 0, 2528cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd string( 2538cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd "Could not execute: Argument \"" + *cit + 2548cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd "\" contains shell metacharacters.\n").c_str()); 2558cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd return EINVAL; 2568cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd } 2578cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 2588cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd child_reader reader(cmd, args); 2598cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd if (reader.error()) 2608cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd ok = false; 2618cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 2628cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd if (ok) 2638cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd reader.get_data(cout, err); 2648cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 2658cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd int ret = reader.terminate_process(); 2668cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd if (ret) { 2678cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd string error = reader.error_str() + "\n"; 2688cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd error += "Failed: \n" + err.str() + "\n"; 2698cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd string cmdline = cmd; 2708cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd for (vector<string>::const_iterator cit = args.begin(); 2718cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd cit != args.end(); ++cit) { 2728cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd cmdline += " " + *cit + " "; 2738cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd } 2748cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd error += "\n\nCommand was :\n\n" + cmdline + "\n"; 2758cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 2768cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd QMessageBox::warning(0, 0, format(error, 50).c_str()); 2778cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd } 2788cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 2798cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd return ret; 2808cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd} 2818cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 2828cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 2838cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd/** 2848cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd * do_open_file_or_dir - open file/directory 2858cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd * @param base_dir directory to start at 2868cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd * @param dir_only directory or filename to select 2878cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd * 2888cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd * Select a file or directory. The selection is returned; 2898cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd * an empty string if the selection was cancelled. 2908cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd */ 2918cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Doddstring const do_open_file_or_dir(string const & base_dir, bool dir_only) 2928cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd{ 2938cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd QString result; 2948cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 2958cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd if (dir_only) { 2968cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd result = QFileDialog::getExistingDirectory(base_dir.c_str(), 0, 2978cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd "open_file_or_dir", "Get directory name", true); 2988cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd } else { 2998cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd result = QFileDialog::getOpenFileName(base_dir.c_str(), 0, 0, 3008cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd "open_file_or_dir", "Get filename"); 3018cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd } 3028cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 3038cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd if (result.isNull()) 3048cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd return string(); 3058cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd else 3068cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd return result.latin1(); 3078cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd} 3088cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 3098cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd/** 3108cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd * verify_argument - check string for potentially dangerous characters 3118cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd * 3128cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd * This function returns false if the string contains dangerous shell 3138cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd * metacharacters. 3148cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd * 3158cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd * WWW Security FAQ dangerous chars: 3168cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd * 3178cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd * & ; ` ' \ " | * ? ~ < > ^ ( ) [ ] { } $ \n \r 3188cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd * 3198cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd * David Wheeler: ! # 3208cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd * 3218cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd * We allow '-' because we disallow whitespace. We allow ':' and '=' 3228cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd */ 3238cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Doddbool verify_argument(string const & str) 3248cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd{ 3258cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd if (str.find_first_not_of( 3268cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd "ABCDEFGHIJKLMNOPQRSTUVWXYZ" 3278cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd "abcdefghijklmnopqrstuvwxyz0123456789_:=-+%,./") 3288cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd != string::npos) 3298cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd return false; 3308cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd return true; 3318cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd} 332