示例#1
0
int main(int argc, char *argv[])
{
   if( argc != 2 )
   {
      std::cout
         << "xstartonce 0.0.2\n"
         << "Usage: xstartonce <hotkey-name>\n"
         << "You need to define hotkeys in ~/.xstartonce in the format \"name=command --params\".";
      return 1;
   }
   Config config;
   loadFile(QDir::home().absoluteFilePath(".xstartonce"), config);
   QString dbPath = QDir::temp().absoluteFilePath("xstartonce-db.%1").arg(userName());
   for(Config::const_iterator i = config.begin(); i != config.end(); ++i)
   {
      qDebug() << i.key();
      if( i.key() == argv[1] )
      {
         qDebug() << "Found key" << i.key();
         ProcList procs;
         if( loadFile(dbPath, procs) )
            for(ProcList::const_iterator j = procs.begin(); j != procs.end(); ++j)
            {
               if( j.key() == i.key() )
               {
                  QString winId = findWindowForPid(qvariant_cast<int>(j.value()));
                  if( !winId.isEmpty() ) 
                  {
                     QProcess proc;
                     QStringList args;
                     args << "-i" << "-a" << winId;
                     qDebug() << "Activating window" << winId;
                     proc.start("wmctrl", args);
                     proc.waitForFinished(2000);
                     return 0;
                  } else {
                     qDebug() << "Could not find window for pid" << j.value();
                     break;
                  }
               }
            }
         int i_pid = startProcess(i.value());
         if( i_pid > 0 )
         {
            QString pid = qvariant_cast<QString>(i_pid);
            procs[i.key()] = pid;
            writeFile(dbPath, procs);
         }
         return 0;
      }
   }
   qDebug() << "No such configuration " << argv[1] << ".";
   return 3;
}
示例#2
0
    void Process::diffProcLists(const ProcList& oldList, const ProcList& newList, int& start, int& end) const {
        const int newSize = newList.size();
        const int oldSize = oldList.size();
        const int size = newSize <= oldSize ? newSize : oldSize;
        bool endDone = false;
        bool startDone = false;
        int x;
        start = 0;
        end = oldList.size() - 1;

        for ( int i = 0; i < size; i++ ) {
            x = size - i - 1;
            if ( !startDone && oldList.at(i) == newList.at(i) ) {
                start++;
            } else {
                startDone = true;
            }

            if ( !endDone && oldList.at(x) == newList.at(x) ) {
                end--;
            } else {
                endDone = true;
            }

            if ( (startDone && endDone) || start > end ) {
                return;
            }
        }
    }
static void
refresh_list (ProcData *procdata, const pid_t* pid_list, const guint n)
{
    typedef std::list<ProcInfo*> ProcList;
    ProcList addition;

    GtkTreeModel *model = gtk_tree_view_get_model (GTK_TREE_VIEW (procdata->tree));
    guint i;

    // Add or update processes in the process list
    for(i = 0; i < n; ++i) {
        ProcInfo *info = ProcInfo::find(pid_list[i]);

        if (!info) {
            info = new ProcInfo(pid_list[i]);
            ProcInfo::all[info->pid] = info;
            addition.push_back(info);
        }

        update_info (procdata, info);
    }


    // Remove dead processes from the process list and from the
    // tree. children are queued to be readded at the right place
    // in the tree.

    const std::set<pid_t> pids(pid_list, pid_list + n);

    ProcInfo::Iterator it(ProcInfo::begin());

    while (it != ProcInfo::end()) {
        ProcInfo * const info = it->second;
        ProcInfo::Iterator next(it);
        ++next;

        if (pids.find(info->pid) == pids.end()) {
            procman_debug("ripping %d", info->pid);
            remove_info_from_tree(procdata, model, info, addition);
            addition.remove(info);
            ProcInfo::all.erase(it);
            delete info;
        }

        it = next;
    }

    // INVARIANT
    // pid_list == ProcInfo::all + addition


    if (procdata->config.show_tree) {

        // insert process in the tree. walk through the addition list
        // (new process + process that have a new parent). This loop
        // handles the dependencies because we cannot insert a process
        // until its parent is in the tree.

        std::set<pid_t> in_tree(pids);

        for (ProcList::iterator it(addition.begin()); it != addition.end(); ++it)
            in_tree.erase((*it)->pid);


        while (not addition.empty()) {
            procman_debug("looking for %d parents", int(addition.size()));
            ProcList::iterator it(addition.begin());

            while (it != addition.end()) {
                procman_debug("looking for %d's parent with ppid %d",
                              int((*it)->pid), int((*it)->ppid));


                // inserts the process in the treeview if :
                // - it is init
                // - its parent is already in tree
                // - its parent is unreachable
                //
                // rounds == 2 means that addition contains processes with
                // unreachable parents
                //
                // FIXME: this is broken if the unreachable parent becomes active
                // i.e. it gets active or changes ower
                // so we just clear the tree on __each__ update
                // see proctable_update_list (ProcData * const procdata)


                if ((*it)->ppid == 0 or in_tree.find((*it)->ppid) != in_tree.end()) {
                    insert_info_to_tree(*it, procdata);
                    in_tree.insert((*it)->pid);
                    it = addition.erase(it);
                    continue;
                }

                ProcInfo *parent = ProcInfo::find((*it)->ppid);
                // if the parent is unreachable
                if (not parent) {
                    // or std::find(addition.begin(), addition.end(), parent) == addition.end()) {
                    insert_info_to_tree(*it, procdata, true);
                    in_tree.insert((*it)->pid);
                    it = addition.erase(it);
                    continue;
                }

                ++it;
            }
        }
    }
    else {
        // don't care of the tree
        for (ProcList::iterator it(addition.begin()); it != addition.end(); ++it)
            insert_info_to_tree(*it, procdata);
    }


    for (ProcInfo::Iterator it(ProcInfo::begin()); it != ProcInfo::end(); ++it)
        update_info_mutable_cols(it->second);
}
示例#4
0
// Display all processes and relevant network traffic using show function
void do_refresh()
{
	int rows; // number of terminal rows
	int cols; // number of terminal columns
	unsigned int proglen; // max length of the "PROGRAM" column

	getmaxyx(stdscr, rows, cols);	 /* find the boundaries of the screeen */
	if (cols < 60) {
		clear();
		mvprintw(0,0, "The terminal is too narrow! Please make it wider.\nI'll wait...");
		return;
	}

	if (cols > PROGNAME_WIDTH) cols = PROGNAME_WIDTH;

	proglen = cols - 53;

	refreshconninode();
	if (DEBUG || tracemode)
	{
		std::cout << "\nRefreshing:\n";
	}
	else
	{
		clear();
		mvprintw (0, 0, "%s", caption->c_str());
		attron(A_REVERSE);
		mvprintw (2, 0, "  PID USER     %-*.*s  DEV        SENT      RECEIVED       ", proglen, proglen, "PROGRAM");
		attroff(A_REVERSE);
	}
	ProcList * curproc = processes;
	ProcList * previousproc = NULL;
	int nproc = processes->size();
	/* initialise to null pointers */
	Line * lines [nproc];
	int n = 0, i = 0;
	double sent_global = 0;
	double recv_global = 0;

#ifndef NDEBUG
	// initialise to null pointers
	for (int i = 0; i < nproc; i++)
		lines[i] = NULL;
#endif

	while (curproc != NULL)
	{
		// walk though its connections, summing up their data, and
		// throwing away connections that haven't received a package
		// in the last PROCESSTIMEOUT seconds.
		assert (curproc != NULL);
		assert (curproc->getVal() != NULL);
		assert (nproc == processes->size());

		/* remove timed-out processes (unless it's one of the the unknown process) */
		if ((curproc->getVal()->getLastPacket() + PROCESSTIMEOUT <= curtime.tv_sec)
				&& (curproc->getVal() != unknowntcp)
				&& (curproc->getVal() != unknownudp)
				&& (curproc->getVal() != unknownip))
		{
			if (DEBUG)
				std::cout << "PROC: Deleting process\n";
			ProcList * todelete = curproc;
			Process * p_todelete = curproc->getVal();
			if (previousproc)
			{
				previousproc->next = curproc->next;
				curproc = curproc->next;
			} else {
				processes = curproc->getNext();
				curproc = processes;
			}
			delete todelete;
			delete p_todelete;
			nproc--;
			//continue;
		}
		else
		{
			// add a non-timed-out process to the list of stuff to show
			float value_sent = 0,
				value_recv = 0;

			if (viewMode == VIEWMODE_KBPS)
			{
				//std::cout << "kbps viemode" << std::endl;
				getkbps (curproc->getVal(), &value_recv, &value_sent);
			}
			else if (viewMode == VIEWMODE_TOTAL_KB)
			{
				//std::cout << "total viemode" << std::endl;
				gettotalkb(curproc->getVal(), &value_recv, &value_sent);
			}
			else if (viewMode == VIEWMODE_TOTAL_MB)
			{
				//std::cout << "total viemode" << std::endl;
				gettotalmb(curproc->getVal(), &value_recv, &value_sent);
			}
			else if (viewMode == VIEWMODE_TOTAL_B)
			{
				//std::cout << "total viemode" << std::endl;
				gettotalb(curproc->getVal(), &value_recv, &value_sent);
			}
			else
			{
				forceExit(false, "Invalid viewMode: %d", viewMode);
			}
			uid_t uid = curproc->getVal()->getUid();
#ifndef NDEBUG
			struct passwd * pwuid = getpwuid(uid);
			assert (pwuid != NULL);
			// value returned by pwuid should not be freed, according to
			// Petr Uzel.
			//free (pwuid);
#endif
			assert (curproc->getVal()->pid >= 0);
			assert (n < nproc);

			lines[n] = new Line (curproc->getVal()->name, value_recv, value_sent,
					curproc->getVal()->pid, uid, curproc->getVal()->devicename);
			previousproc = curproc;
			curproc = curproc->next;
			n++;
#ifndef NDEBUG
			assert (nproc == processes->size());
			if (curproc == NULL)
				assert (n-1 < nproc);
			else
				assert (n < nproc);
#endif
		}
	}

	/* sort the accumulated lines */
	qsort (lines, nproc, sizeof(Line *), GreatestFirst);

	/* print them */
	for (i=0; i<nproc; i++)
	{
		if (i+3 < rows)
			lines[i]->show(i+3, proglen);
		recv_global += lines[i]->recv_value;
		sent_global += lines[i]->sent_value;
		delete lines[i];
	}
	if (tracemode || DEBUG) {
		/* print the 'unknown' connections, for debugging */
		ConnList * curr_unknownconn = unknowntcp->connections;
		while (curr_unknownconn != NULL) {
			std::cout << "Unknown connection: " <<
				curr_unknownconn->getVal()->refpacket->gethashstring() << std::endl;

			curr_unknownconn = curr_unknownconn->getNext();
		}
	}

	if ((!tracemode) && (!DEBUG)){
		attron(A_REVERSE);
		int totalrow = std::min(rows-1, 3+1+i);
		mvprintw (totalrow, 0, "  TOTAL        %-*.*s        %10.3f  %10.3f ", proglen, proglen, " ", sent_global, recv_global);
		if (viewMode == VIEWMODE_KBPS)
		{
			mvprintw (3+1+i, cols - 7, "KB/sec ");
		} else if (viewMode == VIEWMODE_TOTAL_B) {
			mvprintw (3+1+i, cols - 7, "B      ");
		} else if (viewMode == VIEWMODE_TOTAL_KB) {
			mvprintw (3+1+i, cols - 7, "KB     ");
		} else if (viewMode == VIEWMODE_TOTAL_MB) {
			mvprintw (3+1+i, cols - 7, "MB     ");
		}
		attroff(A_REVERSE);
		mvprintw (totalrow+1, 0, "");
		refresh();
	}
}
示例#5
0
文件: cui.cpp 项目: digihaven/nethogs
// Display all processes and relevant network traffic using show function
void do_refresh()
{
	refreshconninode();
	refreshcount++;

	ProcList * curproc = processes;
	ProcList * previousproc = NULL;
	int nproc = processes->size();
	/* initialise to null pointers */
	Line * lines [nproc];
	int n = 0;

#ifndef NDEBUG
	// initialise to null pointers
	for (int i = 0; i < nproc; i++)
		lines[i] = NULL;
#endif

	while (curproc != NULL)
	{
		// walk though its connections, summing up their data, and
		// throwing away connections that haven't received a package
		// in the last PROCESSTIMEOUT seconds.
		assert (curproc != NULL);
		assert (curproc->getVal() != NULL);
		assert (nproc == processes->size());

		/* remove timed-out processes (unless it's one of the the unknown process) */
		if ((curproc->getVal()->getLastPacket() + PROCESSTIMEOUT <= curtime.tv_sec)
				&& (curproc->getVal() != unknowntcp)
				&& (curproc->getVal() != unknownudp)
				&& (curproc->getVal() != unknownip))
		{
			if (DEBUG)
				std::cout << "PROC: Deleting process\n";
			ProcList * todelete = curproc;
			Process * p_todelete = curproc->getVal();
			if (previousproc)
			{
				previousproc->next = curproc->next;
				curproc = curproc->next;
			} else {
				processes = curproc->getNext();
				curproc = processes;
			}
			delete todelete;
			delete p_todelete;
			nproc--;
			//continue;
		}
		else
		{
			// add a non-timed-out process to the list of stuff to show
			float value_sent = 0,
				value_recv = 0;

			if (viewMode == VIEWMODE_KBPS)
			{
				//std::cout << "kbps viemode" << std::endl;
				getkbps (curproc->getVal(), &value_recv, &value_sent);
			}
			else if (viewMode == VIEWMODE_TOTAL_KB)
			{
				//std::cout << "total viemode" << std::endl;
				gettotalkb(curproc->getVal(), &value_recv, &value_sent);
			}
			else if (viewMode == VIEWMODE_TOTAL_MB)
			{
				//std::cout << "total viemode" << std::endl;
				gettotalmb(curproc->getVal(), &value_recv, &value_sent);
			}
			else if (viewMode == VIEWMODE_TOTAL_B)
			{
				//std::cout << "total viemode" << std::endl;
				gettotalb(curproc->getVal(), &value_recv, &value_sent);
			}
			else
			{
				forceExit(false, "Invalid viewMode: %d", viewMode);
			}
			uid_t uid = curproc->getVal()->getUid();
#ifndef NDEBUG
			struct passwd * pwuid = getpwuid(uid);
			assert (pwuid != NULL);
			// value returned by pwuid should not be freed, according to
			// Petr Uzel.
			//free (pwuid);
#endif
			assert (curproc->getVal()->pid >= 0);
			assert (n < nproc);

			lines[n] = new Line (curproc->getVal()->name, value_recv, value_sent,
					curproc->getVal()->pid, uid, curproc->getVal()->devicename);
			previousproc = curproc;
			curproc = curproc->next;
			n++;
#ifndef NDEBUG
			assert (nproc == processes->size());
			if (curproc == NULL)
				assert (n-1 < nproc);
			else
				assert (n < nproc);
#endif
		}
	}

	/* sort the accumulated lines */
	qsort (lines, nproc, sizeof(Line *), GreatestFirst);

	if (tracemode || DEBUG)
		show_trace(lines, nproc);
	else
		show_ncurses(lines, nproc);

	if (refreshlimit != 0 && refreshcount >= refreshlimit)
		quit_cb(0);
}
示例#6
0
static void
refresh_list (GsmApplication *app, const pid_t* pid_list, const guint n)
{
    typedef std::list<ProcInfo*> ProcList;
    ProcList addition;

    GtkTreeModel    *model = gtk_tree_model_filter_get_model (GTK_TREE_MODEL_FILTER (
                             gtk_tree_model_sort_get_model(GTK_TREE_MODEL_SORT (
                             gtk_tree_view_get_model (GTK_TREE_VIEW(app->tree))))));
    guint i;

    // Add or update processes in the process list
    for(i = 0; i < n; ++i) {
        ProcInfo *info = app->processes.find(pid_list[i]);

        if (!info) {
            info = app->processes.add(pid_list[i]);
            addition.push_back(info);
        }

        update_info (app, info);
    }


    // Remove dead processes from the process list and from the
    // tree. children are queued to be readded at the right place
    // in the tree.

    const std::set<pid_t> pids(pid_list, pid_list + n);

    auto it = std::begin(app->processes);
    while (it != std::end(app->processes)) {
        auto& info = it->second;
        if (pids.find(info.pid) == pids.end()) {
            procman_debug("ripping %d", info.pid);
            remove_info_from_tree(app, model, info, addition);
            addition.remove(&info);
            it = app->processes.erase(it);
        } else {
            ++it;
        }
    }

    // INVARIANT
    // pid_list == ProcInfo::all + addition


    if (app->settings->get_boolean (GSM_SETTING_SHOW_DEPENDENCIES)) {

        // insert process in the tree. walk through the addition list
        // (new process + process that have a new parent). This loop
        // handles the dependencies because we cannot insert a process
        // until its parent is in the tree.

        std::set<pid_t> in_tree(pids);

        for (ProcList::iterator it(addition.begin()); it != addition.end(); ++it)
            in_tree.erase((*it)->pid);


        while (not addition.empty()) {
            procman_debug("looking for %d parents", int(addition.size()));
            ProcList::iterator it(addition.begin());

            while (it != addition.end()) {
                procman_debug("looking for %d's parent with ppid %d",
                              int((*it)->pid), int((*it)->ppid));


                // inserts the process in the treeview if :
                // - it has no parent (ppid = -1),
                //   ie it is for example the [kernel] on FreeBSD
                // - it is init
                // - its parent is already in tree
                // - its parent is unreachable
                //
                // rounds == 2 means that addition contains processes with
                // unreachable parents
                //
                // FIXME: this is broken if the unreachable parent becomes active
                // i.e. it gets active or changes ower
                // so we just clear the tree on __each__ update
                // see proctable_update (ProcData * const procdata)


                if ((*it)->ppid <= 0 or in_tree.find((*it)->ppid) != in_tree.end()) {
                    insert_info_to_tree(*it, app);
                    in_tree.insert((*it)->pid);
                    it = addition.erase(it);
                    continue;
                }

                ProcInfo *parent = app->processes.find((*it)->ppid);
                // if the parent is unreachable
                if (not parent) {
                    // or std::find(addition.begin(), addition.end(), parent) == addition.end()) {
                    insert_info_to_tree(*it, app, true);
                    in_tree.insert((*it)->pid);
                    it = addition.erase(it);
                    continue;
                }

                ++it;
            }
        }
    }
    else {
        // don't care of the tree
        for (auto& v : addition) insert_info_to_tree(v, app);
    }


    for (auto& v : app->processes) update_info_mutable_cols(&v.second);
}
示例#7
0
static void nethogsmonitor_handle_update(NethogsMonitorCallback cb) {
  refreshconninode();
  refreshcount++;

  ProcList *curproc = processes;
  ProcList *previousproc = NULL;
  int nproc = processes->size();

  while (curproc != NULL) {
    // walk though its connections, summing up their data, and
    // throwing away connections that haven't received a package
    // in the last PROCESSTIMEOUT seconds.
    assert(curproc != NULL);
    assert(curproc->getVal() != NULL);
    assert(nproc == processes->size());

    /* remove timed-out processes (unless it's one of the unknown process)
     */
    if ((curproc->getVal()->getLastPacket() + PROCESSTIMEOUT <=
         curtime.tv_sec) &&
        (curproc->getVal() != unknowntcp) &&
        (curproc->getVal() != unknownudp) && (curproc->getVal() != unknownip)) {
      if (DEBUG)
        std::cout << "PROC: Deleting process\n";

      NethogsRecordMap::iterator it = monitor_record_map.find(curproc);
      if (it != monitor_record_map.end()) {
        NethogsMonitorRecord &data = it->second;
        (*cb)(NETHOGS_APP_ACTION_REMOVE, &data);
        monitor_record_map.erase(curproc);
      }

      ProcList *todelete = curproc;
      Process *p_todelete = curproc->getVal();
      if (previousproc) {
        previousproc->next = curproc->next;
        curproc = curproc->next;
      } else {
        processes = curproc->getNext();
        curproc = processes;
      }
      delete todelete;
      delete p_todelete;
      nproc--;
      // continue;
    } else {
      const u_int32_t uid = curproc->getVal()->getUid();
      u_int32_t sent_bytes;
      u_int32_t recv_bytes;
      float sent_kbs;
      float recv_kbs;
      curproc->getVal()->getkbps(&recv_kbs, &sent_kbs);
      curproc->getVal()->gettotal(&recv_bytes, &sent_bytes);

      // notify update
      bool const new_data =
          (monitor_record_map.find(curproc) == monitor_record_map.end());
      NethogsMonitorRecord &data = monitor_record_map[curproc];

      bool data_change = false;
      if (new_data) {
        data_change = true;
        static int record_id = 0;
        ++record_id;
        memset(&data, 0, sizeof(data));
        data.record_id = record_id;
        data.name = curproc->getVal()->name;
        data.pid = curproc->getVal()->pid;
      }

      data.device_name = curproc->getVal()->devicename;

#define NHM_UPDATE_ONE_FIELD(TO, FROM)                                         \
  if ((TO) != (FROM)) {                                                        \
    TO = FROM;                                                                 \
    data_change = true;                                                        \
  }

      NHM_UPDATE_ONE_FIELD(data.uid, uid)
      NHM_UPDATE_ONE_FIELD(data.sent_bytes, sent_bytes)
      NHM_UPDATE_ONE_FIELD(data.recv_bytes, recv_bytes)
      NHM_UPDATE_ONE_FIELD(data.sent_kbs, sent_kbs)
      NHM_UPDATE_ONE_FIELD(data.recv_kbs, recv_kbs)

#undef NHM_UPDATE_ONE_FIELD

      if (data_change) {
        (*cb)(NETHOGS_APP_ACTION_SET, &data);
      }

      // next
      previousproc = curproc;
      curproc = curproc->next;
    }
  }
}
示例#8
0
 void Process::sort(ProcList& list) {
     switch ( fSortBy ) {
         case 0: qSort(list.begin(), list.end(), CPUComparer()); break;
         case 1: qSort(list.begin(), list.end(), NameComparer()); break;
     }
 }