
Originally Posted by
Salem
Is this for your own use, or do you intend to publish it in any way.
Because if your 'licence' is anything more restrictive than GPL, then system/exec give you a nice clean line of separation.
Grabbing bits of source code from pkill would be a no-no.
I don't sell software, I program for me and my friends.
Anyway, I have found a solution,.. sort of. This works, as far as finding the proper PID to kill. And the program doesn't fail. And I get the word `Killed` displayed (even though there's no code for it), but it doesn't kill the process. And it doesn't finish the program code. I feel I wasted too much time on this and just need to go back to what I had. Here's the code though:
Code:
// Declare includes.
#include <dirent.h>
#include <errno.h>
#include <libgen.h>
#include <pwd.h>
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <time.h>
// Declare defines.
#define FILENAME_SIZE 100
#define PROGRAM_NAME_SIZE 50
#define PROCESS_NAME_SIZE 50
#define DIRECTORY "/proc/"
#define MARKER "@pts/"
// Declare global variables.
char program_name[PROGRAM_NAME_SIZE + 1] = {0};
// Declare function prototypes.
uid_t get_uid (char *user);
void kick_user (char *user);
void kill_process (char *filename);
void process_proc (uid_t user_id);
int main (int argc, char *argv[])
{
// Get program name for error reporting.
strcpy(program_name, basename(argv[0]));
// Check number of arguments.
if(argc != 2)
{
fprintf(stderr, "Usage: %s USERNAME\n", program_name);
exit(EXIT_FAILURE);
}
// Run process.
kick_user(argv[1]);
// Exit cleanly.
exit(EXIT_SUCCESS);
}
void kick_user (char *user)
{
// Declare variables.
uid_t user_id = {0};
// Get UID from username.
user_id = get_uid(user);
// Process folders in the '/proc' directory
process_proc(user_id);
}
uid_t get_uid (char *user)
{
// Declare variables.
struct passwd *pwd = NULL;
// Set errno in case of error.
errno = 0;
// Get record for user.
if((pwd = getpwnam(user)) == NULL)
if(errno != 0)
{
fprintf(stderr, "%s: kill_user error: getpwnam failed (%s) (%s)\n", program_name, strerror(errno), user);
exit(EXIT_FAILURE);
}
// Return UID.
return(pwd->pw_uid);
}
void process_proc (uid_t user_id)
{
// Declare variables.
DIR *dp = NULL;
struct stat buf = {0};
struct dirent *entry = NULL;
char filename[FILENAME_SIZE + 1] = {0};
// Open directory for reading.
if((dp = opendir(DIRECTORY)) == NULL)
{
fprintf(stderr, "%s: kill_user error: opendir failed (%s) (%s)\n", program_name, strerror(errno), DIRECTORY);
exit(EXIT_FAILURE);
}
// Loop through all entries.
while((entry = readdir(dp)) != NULL)
{
if(entry->d_type == DT_DIR)
{
// Build filename.
sprintf(filename, "%s%s", DIRECTORY, entry->d_name);
// Get file info.
if(stat(filename, &buf) == -1)
continue;
// If UIDs match, check the process.
if(buf.st_uid == user_id)
kill_process(filename);
}
}
}
void kill_process (char *filename)
{
// Declare variables.
FILE *fp = NULL;
pid_t pid = {0};
char new_filename[FILENAME_SIZE + 1] = {0};
char process_name[PROCESS_NAME_SIZE + 1] = {0};
// Build new filename.
sprintf(new_filename, "%s/cmdline", filename);
// Open cmdline for process name.
if((fp = fopen(new_filename, "r")) == NULL)
{
fprintf(stderr, "%s: kill_process error: fopen failed (%s) (%s)\n", program_name, strerror(errno), filename);
exit(EXIT_FAILURE);
}
// Get process name.
if(fgets(process_name, PROCESS_NAME_SIZE, fp) == NULL)
{
fprintf(stderr, "%s: kill_process error: fgets failed\n", program_name);
exit(EXIT_FAILURE);
}
// Close process name file.
fclose(fp);
// Check process name.
if(strstr(process_name, MARKER) == NULL)
// Return when they don't match.
return;
// Get PID fron filename.
pid = (pid_t) atoi(filename);
printf("PID: %s\n", basename(filename));
// Kick user from system.
// if(kill(pid, SIGTERM) == -1)
if(kill(pid, SIGKILL) == -1)
{
fprintf(stderr, "%s: kill_process error: kill failed (%s) (%s)\n", program_name, strerror(errno), basename(filename));
exit(EXIT_FAILURE);
}
puts("Doesn't get the here.\n");
}