Example #1
0
std::string Board::infos()
{
	std::string res = "";

	res += "Type:" BOARD "\n";
	res += "Firmware version:" VERSION_STRING "\n";
	res += "CPU:" + readproc( "/proc/cpuinfo", "model name" ) + std::string( "\n" );
	res += "CPU frequency:" + std::to_string( std::atoi( readproc( "/sys/devices/system/cpu/cpu0/cpufreq/scaling_cur_freq" ).c_str() ) / 1000 ) + std::string( "MHz\n" );
	res += "CPU cores count:" + std::to_string( sysconf( _SC_NPROCESSORS_ONLN ) ) + std::string( "\n" );

	return res;
}
Example #2
0
std::string Board::infos()
{
	std::string res = "";

	res += "Type:" BOARD "\n";
	res += "CPU:" + readproc( "/proc/cpuinfo", "model name" ) + std::string( "\n" );
	res += "CPU frequency:" + std::to_string( std::atoi( readproc( "/sys/devices/system/cpu/cpu0/cpufreq/scaling_cur_freq" ).c_str() ) / 1000 ) + std::string( "MHz\n" );
	res += "CPU cores count:" + std::to_string( sysconf( _SC_NPROCESSORS_ONLN ) ) + std::string( "\n" );

	gDebug() << "res : \"" << res << "\"\n";
	return res;
}
int main(int argc, char *argv[])
{
    //int err;

    if( system("/sbin/insmod ./regression3_mod.o") ) {
        fprintf(stderr, "can't insert regression3_mod.o, bailing out\n");
        exit(1);
    }

    // install handlers to cleanly kill system
    signal(SIGALRM, timeout);
    signal(SIGINT,  cleanup);
    signal(SIGTERM, cleanup);


    fprintf(stderr,
		"\n\nFIFO select read regression tests, indefinite timeout\n"
		    "-----------------------------------------------------\n");
    
    mypid = getpid();
    readproc(NULL);
    system("/sbin/rmmod regression3_mod");

    printf("%-60s : %s\n", "FIFO select read test, indefinite timeout ",
			  any_err ? "failed" : "passed");
    exit(0);
}
Example #4
0
/*
 *	Pidof functionality.
 */
int affix_pidof(char *name, int flags, pid_t pid)
{
	PROC	*p;
	PIDQ	*q;
	int	i,oind;
	pid_t	opid[PIDOF_OMITSZ], spid = 0;
	char	*basec = NULL;

	for (oind = PIDOF_OMITSZ-1; oind > 0; oind--)
		opid[oind] = 0;

	if (flags&PIDOF_SCRIPTS)
		scripts_too++;

	if (flags&PIDOF_OMIT) {
		opid[oind] = pid;
		oind++;
	}
	if (flags&PIDOF_POMIT) {
		opid[oind] = getppid();
		oind++;
	}
	if (flags&PIDOF_BASENAME) {
		char	*ch;

		basec = strdup(name);
		name = basename(basec);
		if ((ch = strchr(name, ' '))) {
			*ch = '\0';
		}
	}
	/* Print out process-ID's one by one. */
	readproc();
	if ((q = pidof(name)) == NULL)
		goto exit;
	while ((p = get_next_from_pid_q(q))) {
		if (flags & PIDOF_OMIT) {
			for (i = 0; i < oind; i++) {
				if (opid[i] == p->pid)
					break;
			}
			/*
			 *	On a match, continue with
			 *	the for loop above.
			 */
			if (i < oind)
				continue;
		}
		if (flags & PIDOF_SINGLE) {
			if (spid)
				continue;
			else
				spid = p->pid;
		}
	}
exit:
	free(basec);
	freeproc();
	return spid;
}
Example #5
0
QueryData genProcesses() {
  QueryData results;

  proc_t* proc_info;
  PROCTAB* proc = openproc(PROC_SELECTS);

  // Populate proc struc for each process.
  while ((proc_info = readproc(proc, NULL))) {
    Row r;

    r["pid"] = boost::lexical_cast<std::string>(proc_info->tid);
    r["name"] = proc_name(proc_info);
    r["cmdline"] = proc_cmdline(proc_info);
    r["path"] = proc_link(proc_info);
    r["on_disk"] = osquery::pathExists(r["path"]).toString();

    r["resident_size"] = boost::lexical_cast<std::string>(proc_info->vm_rss);
    r["phys_footprint"] = boost::lexical_cast<std::string>(proc_info->vm_size);
    r["user_time"] = boost::lexical_cast<std::string>(proc_info->utime);
    r["system_time"] = boost::lexical_cast<std::string>(proc_info->stime);
    r["start_time"] = boost::lexical_cast<std::string>(proc_info->start_time);
    r["parent"] = boost::lexical_cast<std::string>(proc_info->ppid);

    results.push_back(r);
    standard_freeproc(proc_info);
  }

  closeproc(proc);

  return results;
}
Example #6
0
//! Returns locale of a process
char *
get_proc_lang(pid_t pid)
{
    pid_t pids[2];
    pids[0] = pid;
    pids[1] = 0;

    proc_t proc;
    PROCTAB *ptp;
    int i = 0;

    char *lang = NULL;

    ptp = openproc(PROC_FILLENV | PROC_PID, pids);
    while(readproc(ptp, &proc)) {
        while (proc.environ[++i]) {
            if (strncmp(proc.environ[i - 1], "LANG", 4) == 0) {
                lang = strsub(proc.environ[i - 1], 5, 7);
                goto out;
            }
        }
    }

out:
    closeproc(ptp);
    return lang;
}
Example #7
0
QueryData genProcessEnvs(QueryContext& context) {
  QueryData results;

  proc_t* proc_info;
  PROCTAB* proc = openproc(PROC_SELECTS);

  // Populate proc struc for each process.

  while ((proc_info = readproc(proc, NULL))) {
    auto env = proc_env(proc_info);
    for (auto itr = env.begin(); itr != env.end(); ++itr) {
      Row r;
      r["pid"] = INTEGER(proc_info->tid);
      r["name"] = proc_name(proc_info);
      r["path"] = proc_link(proc_info);
      r["key"] = itr->first;
      r["value"] = itr->second;
      results.push_back(r);
    }

    standard_freeproc(proc_info);
  }

  closeproc(proc);

  return results;
}
Example #8
0
QueryData genProcesses(QueryContext& context) {
  QueryData results;

  proc_t* proc_info;
  PROCTAB* proc = openproc(PROC_SELECTS);

  // Populate proc struc for each process.
  while ((proc_info = readproc(proc, NULL))) {
    Row r;

    r["pid"] = INTEGER(proc_info->tid);
    r["uid"] = BIGINT((unsigned int)proc_info->ruid);
    r["gid"] = BIGINT((unsigned int)proc_info->rgid);
    r["euid"] = BIGINT((unsigned int)proc_info->euid);
    r["egid"] = BIGINT((unsigned int)proc_info->egid);
    r["name"] = proc_name(proc_info);
    r["cmdline"] = proc_cmdline(proc_info);
    r["path"] = proc_link(proc_info);
    r["on_disk"] = osquery::pathExists(r["path"]).toString();

    r["resident_size"] = INTEGER(proc_info->vm_rss);
    r["phys_footprint"] = INTEGER(proc_info->vm_size);
    r["user_time"] = INTEGER(proc_info->utime);
    r["system_time"] = INTEGER(proc_info->stime);
    r["start_time"] = INTEGER(proc_info->start_time);
    r["parent"] = INTEGER(proc_info->ppid);

    results.push_back(r);
    standard_freeproc(proc_info);
  }

  closeproc(proc);

  return results;
}
Example #9
0
/* The collector thread is responsible
 * for collecting data about running processes
 * and placing them in a structure that 
 * The analyzer thread can read quickly
 */
void* collector_thread(void *a)
{
  PROCTAB *proct;
  proc_t  *proc_info;
  int hangup = 0;
  
  while (!hangup)
    {
      pthread_mutex_lock(&procsnap_mutex);
      proct = openproc(PROC_FILLARG | PROC_FILLSTAT | PROC_FILLSTATUS);//PROC_FILLMEM | PROC_FILLSTATUS | PROC_FILLSTAT | PROC_FILLARG);
      if (procsnap == NULL)
	{
	  procsnap = (proc_statistics *) calloc(MAXPROCAVS, sizeof(proc_statistics));
	  if (procsnap == NULL)
	    {
	      printf("Can not allocate memory.");
	      exit(-1);
	    }
	}
      numprocsnap = 0;
      while((proc_info = readproc(proct,NULL)))
	{
	  if (procsnap[numprocsnap]._command == NULL)
	    {
	      if ((procsnap[numprocsnap]._command = (char*)malloc(20*sizeof(char))) == NULL)
		{
		  printf("malloc error, can not allocate memory.\n");
		  exit(-1);
		}

	      if (procsnap[numprocsnap]._command == NULL)
		{
		  printf("Can not allocate memory.");
		  exit(-1);
		}
	    }
	  procsnap[numprocsnap]._pid = proc_info->tid;
	  procsnap[numprocsnap]._uid = proc_info->ruid;
	  strncpy(procsnap[numprocsnap]._command, proc_info->cmd, 20);
	  procsnap[numprocsnap]._rssize = proc_info->rss;
	  procsnap[numprocsnap]._size = proc_info->size;
	  procsnap[numprocsnap]._perc = proc_info->pcpu;
	  procsnap[numprocsnap]._age = 0;
	  procsnap[numprocsnap]._read = 0;
	  freep(proc_info);
	  numprocsnap++;
	}
      closeproc(proct);
      pthread_mutex_unlock(&procsnap_mutex);
      pthread_mutex_lock(&hangup_mutex);
      if (m_hangup)
	hangup = 1;
      pthread_mutex_unlock(&hangup_mutex);
      if (!hangup)
	sleep(1);
    }
  return NULL;
}
Example #10
0
void ProcessManager::WarnExcess()
{
    PROCTAB* proc = openproc(PROC_FILLARG | PROC_FILLSTAT | PROC_FILLMEM);
    proc_t * proc_info;

    Core::DebugLog("Looking for processes that exceed the hard or soft limit", 10);

    while (true)
    {
        proc_info = readproc(proc, NULL);
        if (proc_info == NULL)
        {
            break;
        }
        if (!Configuration::KillRoot && proc_info->euid == 0)
        {
            if (Configuration::Verbosity >= 6)
            {
                Core::DebugLog("Ignoring " + Core::int2String(proc_info->tid) + " owned by root", 6);
            }
            freeproc(proc_info);
            continue;
        }

        if (proc_info->tid == Configuration::pid && !Configuration::KillSelf)
        {
            Core::DebugLog("Ignoring " + Core::int2String(proc_info->tid) + " which is current instance of this daemon", 6);
            freeproc(proc_info);
            continue;
        }

        if (IgnoredId(proc_info->euid))
        {
            Core::DebugLog("Ignoring " + Core::int2String(proc_info->tid) + " owned by ignored account: " + Core::int2String(proc_info->euid), 2);
            freeproc(proc_info);
            continue;
        }

        // check if this process is using most memory
        if ( proc_info->resident * 4 > ((long)Configuration::HardMemoryLimitMB * 1024 ))
        {
            Core::Log("WARNING: Exceeded hard limit - process " + Name(proc_info));
        } else if ( proc_info->resident * 4 > ((long)Configuration::SoftMemoryLimitMB * 1024 ))
        {
            Core::Log("WARNING: Exceeded soft limit - process " + Name(proc_info));
        } else
        {
            if (Configuration::Verbosity > 12)
            {
                Core::DebugLog("Not exceeded any limit " + Name(proc_info));
            }
        }
        freeproc(proc_info);
    }

    closeproc(proc);
    return;
}
Example #11
0
END_TEST

START_TEST(readproc_no_file)
{
	linuxonly;

	ck_assert_int_eq(remove_directory(TESTDIR), 1);
	ck_assert_int_eq(readproc("ethunusual"), 0);
}
Example #12
0
// all processes
IoStatistics getAllProcessesIo() {
    IoStatistics info;
	info.read = 0;
	info.write = 0;

#ifdef ANDROID
	_readSendTransmit(fopen(PROC_NET_DEV, "r"), &info);

	unsigned long read = 0;
	unsigned long write = 0;
	struct hd_driveid *id;
	int res, res2;
	FILE* fd = fopen(PROC_DISKSTATS, "r");
	char dev[100];
	char filename[BUFSIZ];
	if (NULL != fd) {
		do {
			// # reads, #reads merged, #sect read, #ms reading, #writes, #sect written #ms writing #ios in progress #ms ios #weighted ios
			res = fscanf(fd, "%*u %*u %s %*u %*u %lu %*u %*u %lu %*u %*u %*u %*u %*u\n", dev, &read, &write);
			if (res > 0) {
				// prefer sda1 over sda
				res2 = sscanf(dev, "%*a[a-zA-z]%*u");
				if (res2 > 0) {
					sprintf(filename, DEV_DEVID, dev);
					int devFd = open(filename, O_RDONLY|O_NONBLOCK);
					if (devFd >= 0) {
						if (ioctl(devFd, HDIO_GET_IDENTITY, id)) {
							info.read += read * id->sector_bytes;
							info.write += write * id->sector_bytes;
						}
						close(devFd);
					}
				}
			}
		} while (res > 0 && !feof(fd));
		fclose(fd);
	}
#else
	info.read = 0;
	info.write = 0;
	proc_t table;
	PROCTAB* PT = openproc(PROC_FILLMEM | PROC_FILLSTAT);
	if (NULL != PT) {
		info.read = 0;
		info.write = 0;
		while (NULL != readproc(PT, &table)) {
			IoStatistics procStat = _getProcessIo(table.tgid);
			info.read += procStat.read;
			info.write += procStat.write;
		}
		closeproc(PT);
	}
#endif
	return info;
}
Example #13
0
END_TEST

START_TEST(readproc_not_found)
{
	linuxonly;

	ck_assert_int_eq(remove_directory(TESTDIR), 1);
	fake_proc_net_dev("w", "ethwrong", 10, 20, 30, 40);

	ck_assert_int_eq(readproc("ethunusual"), 0);
}
Example #14
0
Procinfo::Procinfo(int proc_pid)
{
    if(readproc(proc_pid) < 0)
	pid = -1;		// invalidate object, will be deleted
    selected = FALSE;
    viewed = FALSE;
    details = 0;
    sock_inodes = 0;
    socks_current = FALSE;
    socks.setAutoDelete(TRUE);
}
Example #15
0
int process_list_processes(process_list_t **result) {
  proc_t proc_info;
#ifdef COLLECT_STATS
  size_t proc_count = 0;
  extern stats_t stats;
  struct timeval tv1;
  gettimeofday(&tv1, NULL);
#endif

  PROCTAB *proc =
      openproc(PROC_FILLMEM | PROC_FILLSTAT | PROC_FILLSTATUS | PROC_FILLCOM);

  memset(&proc_info, 0, sizeof(proc_info));
  while (readproc(proc, &proc_info) != NULL) {
    process_t *to_add = calloc(1, sizeof(process_t));
    to_add->tgid = proc_info.tgid;
    to_add->name = proc_info.cmd;
    if (proc_info.cmdline != NULL) {
      to_add->cmdline = strjoinv(" ", proc_info.cmdline);
    }
    to_add->vms = proc_info.vm_size;
    to_add->rss = proc_info.vm_rss;
    to_add->threads_num = proc_info.nlwp;

    to_add->utime = proc_info.utime;
    to_add->stime = proc_info.stime;

    to_add->user = proc_info.euid;
#ifdef COLLECT_STATS
    proc_count++;
#endif

    LL_APPEND((*result)->processes, to_add);
    // printf("%20s:\t%5ld\t%5lld\t%5lld\n", proc_info.cmd, proc_info.resident,
    //       proc_info.utime, proc_info.stime);
  }
  closeproc(proc);

  struct timeval tv;
  gettimeofday(&tv, NULL);
  (*result)->timestamp = 1000000 * tv.tv_sec + tv.tv_usec;

#ifdef COLLECT_STATS
  uint64_t t1 = 1000000 * tv1.tv_sec + tv1.tv_usec;
  stats.ps_dur = (*result)->timestamp - t1;
  stats.ps_times_count += 1;
  stats.ps_last_count = proc_count;
#endif

  return 1;
}
void myproc(){

	//printf(1,"\n%d\n",writeproc("tmp",O_CREATE|O_RDWR));
	int child=fork();
	if(child >= 0) // fork was successful
	    {
		if(child == 0) // child process
		{
	
		    printf(1,"Child Process %d.\n",child);
			int i=0;
			while(1){
				sleep(100);
				printf(1,"%d",i);
				i++;
			}
			
			
			
		}
		else //Parent process
		{
		    printf(1,"Parent process %d.\n",child);
			sleep(400);
writeproc("tmp",O_CREATE|O_RDWR);
			kill(child);
			//if(kill(child)==0){
			//printf(1,"kill succeed! .\n");

readproc("tmp",O_RDONLY);	
			//}
			//else{
	
			//printf(1,"kill failed .\n");
			//}
		}
	    }
	    else // fork failed
	    {
		printf(1,"\n Fork failed, quitting!!!!!!\n");
		exit();
	    }

	//readproc("tmp",O_RDONLY);
printf(1,"\n quitting!!!!!!\n");
	exit();
}
void process_processes(double cpup_limit, unsigned memory_limit, int maxNProc, char* name){
    PROCTAB* proc  = openproc(PROC_FILLMEM | PROC_FILLUSR | PROC_FILLSTAT | PROC_FILLSTATUS);
    userstats = NULL;
    proc_t proc_info;
    memset(&proc_info, 0, sizeof(proc_info));
    while(readproc(proc, &proc_info) != NULL ) {
        if(strcmp(proc_info.suser,"root") != 0){
            struct cur_process *cpp = find_process(proc_info.tid);
            if(cpp != NULL){
                time_t prev_time = cpp->timestamp;
                time_t cur_time = getCurrentTime();
                double diff_in_seconds = difftime(cur_time,prev_time);
                long unsigned int pid_diff = (proc_info.utime + proc_info.stime) - (cpp->utime + cpp->stime);
                double cpu_percentage = pid_diff / diff_in_seconds;
                unsigned memory = proc_info.vm_rss;

                if(cpup_limit > 0 && (strcmp(cpp->user,name) == 0 || isUserOfGroup(cpp->user,name)))
                    checkCPUPLimit(cpup_limit, cpu_percentage, proc_info.suser, proc_info.cmd, proc_info.tid);
                if(memory_limit >0 && (strcmp(cpp->user,name) == 0 || isUserOfGroup(cpp->user, name)))
                    checkMemoryLimit(memory_limit, memory, proc_info.suser, proc_info.cmd, proc_info.tid );
            }else{
                //printf("No Old process found \n");
            }

            struct cur_process *cp = malloc(sizeof(struct cur_process));
            cp->pid = proc_info.tid;
            cp->cutime = proc_info.cutime;
            cp->cstime = proc_info.cstime;
            cp->utime = proc_info.utime;
            cp->stime = proc_info.stime;
            cp->user = proc_info.suser;
            cp->command = proc_info.cmd;
            cp->vm_size = proc_info.vm_rss;
            cp->group = proc_info.rgroup;
            cp->timestamp = getCurrentTime();
            add_process(cp);

            //printf("Group Name %s \n", proc_info.fgroup);
            if(maxNProc > 0 && (strcmp(cp->user,name) == 0 || isUserOfGroup(cp->user,name)))
                countAndValidateNProc(proc_info.suser, maxNProc);
            //printf("%5d\t%20s:\t%5lld\t%5lu\t%s\n",proc_info.tid, proc_info.cmd, proc_info.utime + proc_info.stime, proc_info.vm_size, proc_info.suser);
        }
    }
    closeproc(proc);
}
Example #18
0
END_TEST

START_TEST(readproc_success)
{
	linuxonly;

	ck_assert_int_eq(remove_directory(TESTDIR), 1);
	fake_proc_net_dev("w", "ethwrong", 10, 20, 30, 40);
	fake_proc_net_dev("a", "ethunusual", 1, 2, 3, 4);

	ck_assert_int_eq(readproc("ethunusual"), 1);
	ck_assert_str_eq(ifinfo.name, "ethunusual");
	ck_assert_int_eq(ifinfo.filled, 1);
	ck_assert_int_eq(ifinfo.rx, 1);
	ck_assert_int_eq(ifinfo.tx, 2);
	ck_assert_int_eq(ifinfo.rxp, 3);
	ck_assert_int_eq(ifinfo.txp, 4);
}
Example #19
0
int main(int argc, char *argv[])
{
	int lc;

	tst_parse_opts(argc, argv, options, help);

	if (opt_buffsize) {
		size_t bs;
		bs = atoi(opt_buffsizestr);
		if (bs <= MAX_BUFF_SIZE)
			buffsize = bs;
		else
			tst_brkm(TBROK, cleanup,
				 "Invalid arg for -b (max: %u): %s",
				 MAX_BUFF_SIZE, opt_buffsizestr);
	}
	if (opt_maxmbytes)
		maxbytes = atoi(opt_maxmbytesstr) * 1024 * 1024;

	if (opt_procpath)
		procpath = opt_procpathstr;

	setup();

	for (lc = 0; TEST_LOOPING(lc); lc++) {
		tst_count = 0;

		TEST(readproc(procpath));

		if (TEST_RETURN != 0) {
			tst_resm(TFAIL, "readproc() failed with %ld errors.",
				 TEST_RETURN);
		} else {
			tst_resm(TPASS, "readproc() completed successfully, "
				 "total read: %llu bytes, %u objs", total_read,
				 total_obj);
		}
	}

	cleanup();
	tst_exit();
}
Example #20
0
/*
 *	Pidof functionality.
 */
int main(int argc, char *argv[])
{
	PIDQ_HEAD	*q;
	PROC		*p;
	pid_t		spid;
	int		first = 1;

	/* Print out process-ID's one by one. */
	readproc();
	if ((q = pidof(argv[1])) != NULL) {
		spid = 0;
		while ((p = get_next_from_pid_q(q))) {
			if (!first)
				printf(" ");
			printf("%d", p->pid);
			first = 0;
		}
	}
	printf("\n");
	closelog();
	return(first ? 1 : 0);	
}
Example #21
0
int getifinfo(const char *iface)
{
	char inface[32];

	ifinfo.filled = 0;

	if (strcmp(iface, "default")==0) {
		strncpy(inface, cfg.iface, 32);
	} else {
		strncpy(inface, iface, 32);
	}

#if defined(__linux__)
	/* try getting interface info from /proc */
	if (readproc(inface)!=1) {
		if (debug)
			printf("Failed to use %s as source.\n", PROCNETDEV);

		/* try getting interface info from /sys */
		if (readsysclassnet(inface)!=1) {
			snprintf(errorstring, 512, "Unable to get interface \"%s\" statistics.", inface);
			printe(PT_Error);
			return 0;
		}
	}
#elif defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__) || defined(__APPLE__)  || defined(__FreeBSD_kernel__)
	if (readifaddrs(inface)!=1) {
		snprintf(errorstring, 512, "Unable to get interface \"%s\" statistics.", inface);
		printe(PT_Error);
		return 0;
	}
#else
	return 0;
#endif

	return 1;
}
Example #22
0
int daemon_main(int argc, char *argv[])
{
    int opt;
    bool fork_flag = false;
    bool replace_flag = false;
    bool patch_sepolicy = true;

    enum {
        OPT_ALLOW_ROOT_CLIENT = 1000,
        OPT_NO_PATCH_SEPOLICY = 1001,
        OPT_SIGSTOP_WHEN_READY = 1002,
        OPT_LOG_TO_KMSG = 1003,
        OPT_LOG_TO_STDIO = 1004,
        OPT_NO_UNSHARE = 1005,
    };

    static struct option long_options[] = {
        {"daemonize",          no_argument, 0, 'd'},
        {"replace",            no_argument, 0, 'r'},
        {"help",               no_argument, 0, 'h'},
        {"allow-root-client",  no_argument, 0, OPT_ALLOW_ROOT_CLIENT},
        {"no-patch-sepolicy",  no_argument, 0, OPT_NO_PATCH_SEPOLICY},
        {"sigstop-when-ready", no_argument, 0, OPT_SIGSTOP_WHEN_READY},
        {"log-to-kmsg",        no_argument, 0, OPT_LOG_TO_KMSG},
        {"log-to-stdio",       no_argument, 0, OPT_LOG_TO_STDIO},
        {"no-unshare",         no_argument, 0, OPT_NO_UNSHARE},
        {0, 0, 0, 0}
    };

    int long_index = 0;

    while ((opt = getopt_long(argc, argv, "drh", long_options, &long_index)) != -1) {
        switch (opt) {
        case 'd':
            fork_flag = true;
            break;

        case 'r':
            replace_flag = true;
            break;

        case 'h':
            daemon_usage(0);
            return EXIT_SUCCESS;

        case OPT_ALLOW_ROOT_CLIENT:
            allow_root_client = true;
            break;

        case OPT_NO_PATCH_SEPOLICY:
            patch_sepolicy = false;
            break;

        case OPT_SIGSTOP_WHEN_READY:
            sigstop_when_ready = true;
            break;

        case OPT_LOG_TO_KMSG:
            log_to_kmsg = true;
            break;

        case OPT_LOG_TO_STDIO:
            log_to_stdio = true;
            break;

        case OPT_NO_UNSHARE:
            no_unshare = true;
            break;

        default:
            daemon_usage(1);
            return EXIT_FAILURE;
        }
    }

    // There should be no other arguments
    if (argc - optind != 0) {
        daemon_usage(1);
        return EXIT_FAILURE;
    }

    if (!no_unshare && unshare(CLONE_NEWNS) < 0) {
        fprintf(stderr, "unshare() failed: %s\n", strerror(errno));
        return EXIT_FAILURE;
    }

    if (patch_sepolicy) {
        patch_loaded_sepolicy(SELinuxPatch::MAIN);
    }

    if (!switch_context(MB_EXEC_CONTEXT)) {
        fprintf(stderr, "Failed to switch context; %s may not run properly",
                argv[0]);
    }

    if (replace_flag) {
        PROCTAB *proc = openproc(PROC_FILLCOM | PROC_FILLSTAT);
        if (proc) {
            pid_t curpid = getpid();

            while (proc_t *info = readproc(proc, nullptr)) {
                // NOTE: Can't check 'strcmp(info->cmd, "mbtool") == 0' (which
                // is the basename of /proc/<pid>/cmd) because the binary is not
                // always called "mbtool". For example, when run via SignedExec,
                // it's just called "binary".

                // If we can read the cmdline and argc >= 2
                if (info->cmdline && info->cmdline[0] && info->cmdline[1]) {
                    const char *name = strrchr(info->cmdline[0], '/');
                    if (name) {
                        ++name;
                    } else {
                        name = info->cmdline[0];
                    }

                    if (strcmp(name, "mbtool") == 0               // This is mbtool
                            && strstr(info->cmdline[1], "daemon") // And it's a daemon process
                            && info->tid != curpid) {             // And we're not killing ourself
                        // Kill the daemon process
                        LOGV("Killing PID %d", info->tid);
                        kill(info->tid, SIGTERM);
                    }
                }

                freeproc(info);
            }

            closeproc(proc);
        }

        // Give processes a chance to exit
        usleep(500000);
    }

    if (fork_flag) {
        run_daemon_fork();
    } else {
        return (daemon_init() && run_daemon())
                ? EXIT_SUCCESS : EXIT_FAILURE;
    }
}
Example #23
0
/*
 * NB: this function is recursive
 * returns 0 if no error encountered, otherwise number of errors (objs)
 *
 * REM: Funny enough, while developing this function (actually replacing
 *	streamed fopen by standard open), I hit a real /proc bug.
 *	On a 2.2.13-SuSE kernel, "cat /proc/tty/driver/serial" would fail
 *	with EFAULT, while "cat /proc/tty/driver/serial > somefile" wouldn't.
 *	Okay, this might be due to a slight serial misconfiguration, but still.
 *	Analysis with strace showed up the difference was on the count size
 *	of read (1024 bytes vs 4096 bytes). So I tested further..
 *	read count of 512 bytes adds /proc/tty/drivers to the list
 *	of broken proc files, while 64 bytes reads removes
 *	/proc/tty/driver/serial from the list. Interesting, isn't it?
 *	Now, there's a -b option to this test, so you can try your luck. --SF
 *
 * It's more fun to run this test it as root, as all the files will be accessible!
 * (however, be careful, there might be some bufferoverflow holes..)
 * reading proc files might be also a good kernel latency killer.
 */
static long readproc(const char *obj)
{
	DIR *dir = NULL;	/* pointer to a directory */
	struct dirent *dir_ent;	/* pointer to directory entries */
	char dirobj[PATH_MAX];	/* object inside directory to modify */
	struct stat statbuf;	/* used to hold stat information */
	int fd, tmperr, i;
	ssize_t nread;
	static char buf[MAX_BUFF_SIZE];	/* static kills reentrancy, but we don't care about the contents */
	unsigned long long file_total_read = 0;

	/* Determine the file type */
	if (lstat(obj, &statbuf) < 0) {

		/* permission denied is not considered as error */
		if (errno != EACCES) {
			tst_resm(TFAIL | TERRNO, "%s: lstat", obj);
			return 1;
		}
		return 0;

	}

	/* Prevent loops, but read /proc/self. */
	if (S_ISLNK(statbuf.st_mode) && strcmp(obj, selfpath))
		return 0;

	total_obj++;

	/* Take appropriate action, depending on the file type */
	if (S_ISDIR(statbuf.st_mode) || !strcmp(obj, selfpath)) {

		/* object is a directory */

		/*
		 * Skip over the /proc/irq directory, unless the user
		 * requested that we read the directory because it could
		 * map to a broken driver which effectively `hangs' the
		 * test.
		 */
		if (!opt_readirq && !strcmp("/proc/irq", obj)) {
			return 0;
			/* Open the directory to get access to what is in it */
		} else if ((dir = opendir(obj)) == NULL) {
			if (errno != EACCES) {
				tst_resm(TFAIL | TERRNO, "%s: opendir", obj);
				return 1;
			}
			return 0;
		} else {

			long ret_val = 0;

			/* Loop through the entries in the directory */
			for (dir_ent = (struct dirent *)readdir(dir);
			     dir_ent != NULL;
			     dir_ent = (struct dirent *)readdir(dir)) {

				/* Ignore ".", "..", "kcore", and
				 * "/proc/<pid>" (unless this is our
				 * starting point as directed by the
				 * user).
				 */
				if (strcmp(dir_ent->d_name, ".") &&
				    strcmp(dir_ent->d_name, "..") &&
				    strcmp(dir_ent->d_name, "kcore") &&
				    (fnmatch("[0-9]*", dir_ent->d_name,
					     FNM_PATHNAME) ||
				     strcmp(obj, procpath))) {

					if (opt_verbose) {
						fprintf(stderr, "%s\n",
							dir_ent->d_name);
					}

					/* Recursively call this routine to test the
					 * current entry */
					snprintf(dirobj, PATH_MAX,
						 "%s/%s", obj, dir_ent->d_name);
					ret_val += readproc(dirobj);

				}

			}

			/* Close the directory */
			if (dir)
				(void)closedir(dir);

			return ret_val;

		}

	} else {		/* if it's not a dir, read it! */

		if (!S_ISREG(statbuf.st_mode))
			return 0;

#ifdef DEBUG
		fprintf(stderr, "%s", obj);
#endif

		/* is O_NONBLOCK enough to escape from FIFO's ? */
		fd = open(obj, O_RDONLY | O_NONBLOCK);
		if (fd < 0) {
			tmperr = errno;

			if (!found_errno("open", obj, tmperr)) {

				errno = tmperr;

				if (errno != EACCES) {
					tst_resm(TFAIL | TERRNO,
						 "%s: open failed", obj);
					return 1;
				}

			}
			return 0;

		}

		/* Skip write-only files. */
		if ((statbuf.st_mode & S_IRUSR) == 0 &&
		    (statbuf.st_mode & S_IWUSR) != 0) {
			tst_resm(TINFO, "%s: is write-only.", obj);
			return 0;
		}

		/* Skip files does not honor O_NONBLOCK. */
		for (i = 0; error_nonblock[i][0] != '\0'; i++) {
			if (!strcmp(obj, error_nonblock[i])) {
				tst_resm(TINFO, "%s: does not honor "
					 "O_NONBLOCK", obj);
				return 0;
			}
		}

		file_total_read = 0;
		do {

			nread = read(fd, buf, buffsize);

			if (nread < 0) {

				tmperr = errno;
				(void)close(fd);

				/* ignore no perm (not root) and no
				 * process (terminated) errors */
				if (!found_errno("read", obj, tmperr)) {

					errno = tmperr;

					if (errno != EACCES && errno != ESRCH) {
						tst_resm(TFAIL | TERRNO,
							 "read failed: "
							 "%s", obj);
						return 1;
					}
					return 0;

				}

			} else
				file_total_read += nread;

			if (opt_verbose) {
#ifdef DEBUG
				fprintf(stderr, "%ld", nread);
#endif
				fprintf(stderr, ".");
			}

			if ((maxbytes > 0) && (file_total_read > maxbytes)) {
				tst_resm(TINFO, "%s: reached maxmbytes (-m)",
					 obj);
				break;
			}
		} while (0 < nread);
		total_read += file_total_read;

		if (opt_verbose)
			fprintf(stderr, "\n");

		if (0 <= fd)
			(void)close(fd);

	}

	/* It's better to assume success by default rather than failure. */
	return 0;

}
Example #24
0
/* Main for either killall or pidof. */
int main(int argc, char **argv)
{
	PROC		*p;
	int		pid, sid = -1;
	pid_t		opid[KILLALL_OMITSZ];
	int		i, oind, omit = 0;
	int		sig = SIGKILL;

	/* return non-zero if no process was killed */
	int		retval = 2;

	/* Get program name. */
	if ((progname = strrchr(argv[0], '/')) == NULL)
		progname = argv[0];
	else
		progname++;

	/* Now connect to syslog. */
	openlog(progname, LOG_CONS|LOG_PID, LOG_DAEMON);

	/* Were we called as 'pidof' ? */
	if (strcmp(progname, "pidof") == 0)
		return main_pidof(argc, argv);

	/* Right, so we are "killall". */
	for (oind = KILLALL_OMITSZ-1; oind > 0; oind--)
		opid[oind] = 0;

	if (argc > 1) {
		for (i = 1; i < argc; i++) {
			if (argv[i][0] == '-') (argv[i])++;
			if (argv[i][0] == 'o') {
				if (++i >= argc) usage();
				if (oind >= KILLALL_OMITSZ -1) {
					nsyslog(LOG_ERR,"omit pid buffer size "
						"%d exceeded!\n",
						KILLALL_OMITSZ);
					closelog();
					exit(1);
				}
				if ((opid[oind] = atoi(argv[i])) < 1) {
					nsyslog(LOG_ERR,
						"illegal omit pid value "
						"(%s)!\n", argv[i]);
					closelog();
					exit(1);
				}
				oind++;
				omit = 1;
			}
			else if ((sig = atoi(argv[1])) <= 0 || sig > 31)
				usage();
		}
	}

	/* First get the /proc filesystem online. */
	mount_proc();

	/*
	 *	Ignoring SIGKILL and SIGSTOP do not make sense, but
	 *	someday kill(-1, sig) might kill ourself if we don't
	 *	do this. This certainly is a valid concern for SIGTERM-
	 *	Linux 2.1 might send the calling process the signal too.
	 */
	signal(SIGTERM, SIG_IGN);
	signal(SIGSTOP, SIG_IGN);
	signal(SIGKILL, SIG_IGN);

	/* lock us into memory */
	mlockall(MCL_CURRENT | MCL_FUTURE);

	/* Now stop all processes. */
	kill(-1, SIGSTOP);
	sent_sigstop = 1;

	/* Read /proc filesystem */
	if (readproc(NO_STAT) < 0) {
		kill(-1, SIGCONT);
		return(1);
	}

	/* Now kill all processes except init (pid 1) and our session. */
	sid = (int)getsid(0);
	pid = (int)getpid();
	for (p = plist; p; p = p->next) {
		if (p->pid == 1 || p->pid == pid || p->sid == sid || p->kernel)
			continue;
		if (omit) {
			for (i = 0; i < oind; i++)
				if (opid[i] == p->pid)
					break;
			/* On a match, continue with the for loop above. */
			if (i < oind)
				continue;
		}
		kill(p->pid, sig);
		retval = 0;
	}

	/* And let them continue. */
	kill(-1, SIGCONT);

	/* Done. */
	closelog();

	/* Force the kernel to run the scheduler */
	usleep(1);

	return retval;
}
Example #25
0
int daemon_main(int argc, char *argv[])
{
    int opt;
    bool fork_flag = false;
    bool replace_flag = false;

    static struct option long_options[] = {
        {"daemonize", no_argument, 0, 'd'},
        {"replace",   no_argument, 0, 'r'},
        {"help",      no_argument, 0, 'h'},
        {0, 0, 0, 0}
    };

    int long_index = 0;

    while ((opt = getopt_long(argc, argv, "drh", long_options, &long_index)) != -1) {
        switch (opt) {
        case 'd':
            fork_flag = true;
            break;

        case 'r':
            replace_flag = true;
            break;

        case 'h':
            daemon_usage(0);
            return EXIT_SUCCESS;

        default:
            daemon_usage(1);
            return EXIT_FAILURE;
        }
    }

    // There should be no other arguments
    if (argc - optind != 0) {
        daemon_usage(1);
        return EXIT_FAILURE;
    }

    // Patch SELinux policy to make init permissive
    patch_loaded_sepolicy();

    // Allow untrusted_app to connect to our daemon
    patch_sepolicy_daemon();

    // Set version property if we're the system mbtool (i.e. launched by init)
    // Possible to override this with another program by double forking, letting
    // 2nd child reparent to init, and then calling execve("/mbtool", ...), but
    // meh ...
    if (getppid() == 1) {
        if (!util::set_property("ro.multiboot.version", get_mbtool_version())) {
            std::printf("Failed to set 'ro.multiboot.version' to '%s'\n",
                        get_mbtool_version());
        }
    }

    if (replace_flag) {
        PROCTAB *proc = openproc(PROC_FILLCOM | PROC_FILLSTAT);
        if (proc) {
            pid_t curpid = getpid();

            while (proc_t *info = readproc(proc, nullptr)) {
                if (strcmp(info->cmd, "mbtool") == 0          // This is mbtool
                        && info->cmdline                      // And we can see the command line
                        && info->cmdline[1]                   // And argc > 1
                        && strstr(info->cmdline[1], "daemon") // And it's a daemon process
                        && info->tid != curpid) {             // And we're not killing ourself
                    // Kill the daemon process
                    std::printf("Killing PID %d\n", info->tid);
                    kill(info->tid, SIGTERM);
                }

                freeproc(info);
            }

            closeproc(proc);
        }

        // Give processes a chance to exit
        usleep(500000);
    }

    // Set up logging
    if (!util::mkdir_parent(MULTIBOOT_LOG_DAEMON, 0775) && errno != EEXIST) {
        fprintf(stderr, "Failed to create parent directory of %s: %s\n",
                MULTIBOOT_LOG_DAEMON, strerror(errno));
        return EXIT_FAILURE;
    }

    autoclose::file fp(autoclose::fopen(MULTIBOOT_LOG_DAEMON, "w"));
    if (!fp) {
        fprintf(stderr, "Failed to open log file %s: %s\n",
                MULTIBOOT_LOG_DAEMON, strerror(errno));
        return EXIT_FAILURE;
    }

    fix_multiboot_permissions();

    // mbtool logging
    log::log_set_logger(std::make_shared<log::StdioLogger>(fp.get(), true));

    if (fork_flag) {
        run_daemon_fork();
    } else {
        return run_daemon() ? EXIT_SUCCESS : EXIT_FAILURE;
    }
}
Example #26
0
//! Kill process which is eating most
void ProcessManager::KillHighest(bool hard)
{
    PROCTAB* proc = openproc(PROC_FILLARG | PROC_FILLSTAT | PROC_FILLMEM);
    proc_t* proc_info;
    // zero out the allocated proc_info memory
    //memset(&proc_info, 0, sizeof(proc_info));

    proc_t highest;
    long current_highest = 0;
    int current_score = -100;

    Core::DebugLog("Looking for a best candidate");

    while (true)
    {
        proc_info = readproc(proc, NULL);
        if (proc_info == NULL)
        {
            break;
        }
        if (!Configuration::KillRoot && (int)proc_info->euid == 0)
        {
            if (Configuration::Verbosity >= 6)
            {
                Core::DebugLog("Ignoring " + Core::int2String(proc_info->tid) + " owned by root", 6);
            }
            freeproc(proc_info);
            continue;
        }

        if (IgnoredId(proc_info->euid))
        {
            Core::DebugLog("Ignoring " + Core::int2String(proc_info->tid) + " owned by ignored account: " + Core::int2String(proc_info->euid), 2);
            freeproc(proc_info);
            continue;
        }

        if (proc_info->tid == Configuration::pid && !Configuration::KillSelf)
        {
            Core::DebugLog("Ignoring " + Core::int2String(proc_info->tid) + " which is current instance of this daemon", 6);
            freeproc(proc_info);
            continue;
        }

        int score = 0;

        // if it's a root process, decrease the score by 10

        if (proc_info->euser == 0)
        {
            score -= 10;
        }

        score = score + (int)proc_info->nice;

        int badness_score = Core::GetOom(proc_info->tid);

        if (badness_score <= -17)
        {
            // ignore process
            freeproc(proc_info);
            continue;
        }

        if (badness_score != 0)
        {
            score = score + badness_score;
        }

        // check if this process is using most memory
        if ( proc_info->resident * 4 > current_highest )
        {
            current_highest = proc_info->resident * 4;
            score += 10;
        }

        // if this process has highest score, we flag it for kill
        if ( score >= current_score )
        {
            highest = *proc_info;
            current_score = score;
        } else
        {
            if (Configuration::Verbosity >= 12)
            {
                Core::DebugLog("Process " + Name(proc_info) + "is eating less than highest candidate", 12);
            }
        }
        freeproc(proc_info);
    }

    if (current_score == -100)
    {
        Core::ErrorLog("Unable to find any process to kill. System is running OOM and I can't do anything to fix it.");
        closeproc(proc);
        return;
    }

    Core::Log("Most preferred process has score " + Core::int2String(current_score) + " : " + Name(&highest) +  " killing now");

    if (KillExec(&highest) == 0)
    {
        KillProc((pid_t)highest.tid, hard);
        Exec(&highest);
    }else
    {
        Core::Log("Not killed " + Name(&highest) + " because the test command returned different value");
    }

    closeproc(proc);
    return;
}
Example #27
0
static void select_procs(void)
{
  static size_t size = 0;
  PROCTAB* ptp;
  proc_t* task;
  size_t match;
  char* cmd_arg0;
  char* cmd_arg0_base;
  char* cmd_arg1;
  char* cmd_arg1_base;
  char* program_base;
  char* root_link;
  char* exe_link;
  char* exe_link_base;
  
  program_base = basename(program);  /* get the input base name */
  ptp = openproc(PROC_FILLCOM | PROC_FILLSTAT);
  
  while ((task = readproc(ptp, NULL)))
    {
      if (epidof_root)
	{
	  /* get the /proc/<pid>/root symlink value */
	  root_link = pid_link(task->XXXID, "root");
	  match = !strcmp(epidof_root, root_link);
	  xfree(root_link);
	  
	  if (!match) /* root check failed */
	    {
	      freeproc(task);
	      continue;
	    }
	}
      
      if (!is_omitted(task->XXXID) && task->cmdline)
	{
	  cmd_arg0 = task->cmdline[0];
	  
	  /* processes starting with '-' are login shells */
	  if (*cmd_arg0 == '-')
	    cmd_arg0++;
	  
	  cmd_arg0_base = basename(cmd_arg0);           /* get the argv0 basename */
	  exe_link      = pid_link(task->XXXID, "exe");  /* get the /proc/<pid>/exe symlink value */
	  exe_link_base = basename(exe_link);           /* get the exe_link basename */
	  match = 0;
	  
#define __test(p, c)  (!strcmp(p, c##_base) || !strcmp(p, c) || !strcmp(p##_base, c))
	  
	  if (__test(program, cmd_arg0) || __test(program, exe_link))
	    match = 1;
	  else if (opt_scripts_too && task->cmdline[1])
	    {
	      cmd_arg1 = task->cmdline[1];
	      cmd_arg1_base = basename(cmd_arg1);
	      
	      /* if script, then task->cmd = argv1, otherwise task->cmd = argv0 */
	      if (task->cmd &&
		  !strncmp(task->cmd, cmd_arg1_base, strlen(task->cmd)) &&
		  __test(program, cmd_arg1))
		match = 1;
	    }
	  
#undef __test
	  
	  xfree(exe_link);
	  
	  if (match && environment_test(task->XXXID, *argv))
	    {
	      if (proc_count == size)
		procs = xrealloc(procs, __grow(size) * sizeof(*procs));
	      procs[proc_count++] = task->XXXID;
	    }
	}
      freeproc(task);
    }
  closeproc(ptp);
}
Example #28
0
File: mcp.c Project: BrandonCao/mcp
int main(int argc, char *argv[]){

	FILE *file = fopen(argv[1],"r");	
	int i, len, sig,status;
	int numPrograms = 0;
	int runningProcess = 1; 
	wordexp_t wordStruct;
	wordexp_t wordArray[MAXLEN];
	char buffer[MAXLEN][MAXLEN];
	char line[MAXLEN];
	sigset_t sigSet;
	pid_t pid[numPrograms];
	pid_t tempChild;
	pid_t procPID[numPrograms];
	signal(SIGALRM,signalHandler);
	sigemptyset(&sigSet);
	sigaddset(&sigSet, SIGUSR1);
	sigprocmask(SIG_BLOCK,&sigSet,NULL);
	PROCTAB* proc;
	proc_t* procInfo;
	proc_t info;

	

	if( file != NULL){
		/***PART 1***/
		char* get;
		while((get = fgets(line, sizeof(line),file)) != NULL) {
			len = strlen(line);
			if(line[len-1] == '\n'){
				line[len-1] = '\0';
			}
			memset(&wordStruct, 0, sizeof(wordStruct));
			strcpy(buffer[numPrograms], line);
			wordexp(buffer[numPrograms],&wordStruct,0);
			wordArray[numPrograms] = wordStruct;
			numPrograms++;
	
		}
			
		for(i = 0; i < numPrograms; ++i){
			/***fork child process***/
			tempChild = fork();
			if(tempChild < 0){
				perror("failed to fork\n");
				exit(1);
			}
			if(tempChild ==0){
				/***part 2***/
				sigwait(&sigSet,&sig); 
				if(execvp(wordArray[i].we_wordv[0], wordArray[i].we_wordv) == -1){
					perror("Execution failed\n");
				}
			}
			else if ( tempChild > 0) {
				pid[i] = tempChild;
				wordfree(&(wordArray[i]));
			}			
		}
				
		/***Wake up child process***/
		for(i = 0; i < numPrograms; ++i){
			kill(pid[i],SIGUSR1);
			printf("Process %d signaled SIGUSR1\n",pid[i]);
		
		}
		
		/**Stop child process**/
		for(i = 0; i < numPrograms; ++i){
			kill(pid[i],SIGSTOP);
			printf("Process %d signaled SIGSTOP\n",pid[i]);		
		}
		
/***************************************
 * 
 * This while loop was used in part 2 of the mcp project
 * but removed.
 
  removed from part 2
		 * for(i = 0; i < numPrograms; ++i){
		 * 	kill(pid[i],SIGCONT);
		 * printf("Child %d is continuing\n",i);
		 * waitpid(-1,&pid[i],0);
		 *} 

 * 
 *****************************************/ 

	
		/**************
		 * Got idea of this while loop from office hours
		 * 
		 * 
		 * while flag{
		 * 
		 * 	flag = false;
		 * for id in pids:
		 * 	if running ID
		 *	flag == true
		 * 	//ran process
		 * 
		 * }
		 * 
		 ***************/
		 
		 /**flag **/
		while(runningProcess == 1 ){
			runningProcess = 0;
			
			for( i = 0; i < numPrograms; ++i){
				if(waitpid(pid[i], &status, WNOHANG) == 0){	
					
					runningProcess = 1;
					printf("Process %d resumed\n",pid[i]);
					printf("----------------------\n");
					kill(pid[i],SIGCONT);
					/**PART 4**/
					proc = openproc(PROC_FILLMEM | PROC_FILLSTAT | PROC_FILLSTATUS| PROC_PID,pid);
					memset(&info, 0, sizeof(info));
					printf("%20s:\t%s\t%5s\n", "COMMAND","PRIORITY","PPID(PID of parent)");
					printf("%20s\t%s\t%5s\n", "--------","--------","----");
					
					while((procInfo = readproc(proc,&info)) != NULL){
						printf("%20s:\t%lu\t\t%5i\n",
						info.cmd, info.priority,info.ppid);
					}
			
					closeproc(proc);
					
					/**PART 3 alarm handler**/
					alarm(1);
					
					/**Interupts the MCP**/
					while(alarmHandler == 0){
						;
					}
					alarmHandler = 0;
					kill(pid[i],SIGSTOP);
					
					printf("----------------------\n");
					printf("Stopping process %d \n",pid[i]);
					printf("----------------------\n");
					
					}
					
				}
		}
	}
	
	
	
	printf("\nChild processes complete\nProgram Complete\n");
	fclose(file);
						
}
Example #29
0
/*
 *	Pidof functionality.
 */
int main_pidof(int argc, char **argv)
{
	PIDQ_HEAD	*q;
	PROC		*p;
	pid_t		opid[PIDOF_OMITSZ], spid;
	int		f;
	int		first = 1;
	int		i, oind, opt, flags = 0;
	int		chroot_check = 0;
	struct stat	st;
	char		tmp[512];

	for (oind = PIDOF_OMITSZ-1; oind > 0; oind--)
		opid[oind] = 0;
	opterr = 0;

	while ((opt = getopt(argc,argv,"hco:sx")) != EOF) switch (opt) {
		case '?':
			nsyslog(LOG_ERR,"invalid options on command line!\n");
			closelog();
			exit(1);
		case 'c':
			if (geteuid() == 0) chroot_check = 1;
			break;
		case 'o':
			if (oind >= PIDOF_OMITSZ -1) {
				nsyslog(LOG_ERR,"omit pid buffer size %d "
					"exceeded!\n", PIDOF_OMITSZ);
				closelog();
				exit(1);
			}
			if (strcmp("%PPID",optarg) == 0)
				opid[oind] = getppid();
			else if ((opid[oind] = atoi(optarg)) < 1) {
				nsyslog(LOG_ERR,
					"illegal omit pid value (%s)!\n",
					optarg);
				closelog();
				exit(1);
			}
			oind++;
			flags |= PIDOF_OMIT;
			break;
		case 's':
			flags |= PIDOF_SINGLE;
			break;
		case 'x':
			scripts_too++;
			break;
		default:
			/* Nothing */
			break;
	}
	argc -= optind;
	argv += optind;

	/* Check if we are in a chroot */
	if (chroot_check) {
		snprintf(tmp, 512, "/proc/%d/root", getpid());
		if (stat(tmp, &st) < 0) {
			nsyslog(LOG_ERR, "stat failed for %s!\n", tmp);
			closelog();
			exit(1);
		}
	}

	/* Print out process-ID's one by one. */
	readproc(DO_STAT);
	for(f = 0; f < argc; f++) {
		if ((q = pidof(argv[f])) != NULL) {
			spid = 0;
			while ((p = get_next_from_pid_q(q))) {
				if (flags & PIDOF_OMIT) {
					for (i = 0; i < oind; i++)
						if (opid[i] == p->pid)
							break;
					/*
					 *	On a match, continue with
					 *	the for loop above.
					 */
					if (i < oind)
						continue;
				}
				if (flags & PIDOF_SINGLE) {
					if (spid)
						continue;
					else
						spid = 1;
				}
				if (chroot_check) {
					struct stat st2;
					snprintf(tmp, 512, "/proc/%d/root",
						 p->pid);
					if (stat(tmp, &st2) < 0 ||
					    st.st_dev != st2.st_dev ||
					    st.st_ino != st2.st_ino) {
						continue;
					}
				}
				if (!first)
					printf(" ");
				printf("%d", p->pid);
				first = 0;
			}
		}
	}
	if (!first)
		printf("\n");
	closelog();
	return(first ? 1 : 0);
}