nullop
|
|
response 3 of 5:
|
Dec 17 04:44 UTC 2007 |
Amd I acting like a bigger penis pump than veek by erasing the threads?
Should I do a nharmon and retire this? Onto the next round..
There are times when screens isn't feasible and issuing kill -9 -1 is
way too powerful.
/* Grex Port. Written by cdalten@gmail.com*/
/*Unicorn can run this program up his ass.*/
#include <sys/types.h>
#include <sys/param.h>
#include <sys/stat.h>
#include <sys/sysctl.h>
#include <sys/user.h>
#include <utmp.h>
#include <paths.h>
#include <limits.h>
#include <stdio.h>
#include <unistd.h>
#include <pwd.h>
#include <fcntl.h>
#include <string.h>
#include <time.h>
#include <stdlib.h>
#include <signal.h>
#define MAX_USERS 19
typedef struct {
uid_t uid;
dev_t dev;
pid_t pid;
pid_t ppid;
struct utmp in_login;
}uinfo_t;
uinfo_t uinfo[MAX_USERS];
int get_user_info(char *);
void get_uid(char *, uinfo_t *);
struct kinfo_proc *get_my_pid(uinfo_t *);
struct passwd *get_my_name(void);
int compare (const void *, const void *);
void find_sessions_to_kill(int );
void kill_sessions(int n);
/*Fill in the login field*/
int
get_user_info(char *user)
{
static struct utmp logins;
static int fd;
static char tty[MAXPATHLEN];
static int n;
n = 0;
if(( fd = open(_PATH_UTMP, O_RDONLY)) < 0){
return -1;
}
while(read(fd, &logins, sizeof(logins)) == sizeof(logins)) {
if (strncmp(logins.ut_name, user, UT_NAMESIZE)) {
continue;
}
(void)snprintf(tty, sizeof(tty), "%s/%s", _PATH_DEV,
logins.ut_line);
uinfo[n].in_login = logins;
get_uid(tty, &uinfo[n++]);
}
close(fd);
return n;
}
/*Fill in the uid and dev field*/
void
get_uid(char *tty, uinfo_t *uinfo)
{
struct kinfo_proc *p;
static struct stat s;
static int i;
if(stat(tty, &s) < 0){
fprintf(stderr, "no tty\n");
return;
}
uinfo->dev = s.st_rdev;
uinfo->uid = s.st_uid;
if( (p = get_my_pid(&uinfo[i++])) == NULL ){
fprintf(stderr, "can't get pids\n");
return;
}
free(p);
}
/*Fill in the pid field.
This function is OpenBSD and Grex user level account specific*/
struct kinfo_proc *
get_my_pid(uinfo_t *tty)
{
int mib[4];
static int i;
size_t len;
struct kinfo_proc *p;
mib[0] = CTL_KERN;
mib[1] = KERN_PROC;
mib[2] = KERN_PROC_TTY;
mib[3] = uinfo[i].dev;
len = 0;
if (sysctl(mib, sizeof(mib)/sizeof(int), NULL , &len, NULL, 0) == -1)
{
perror("sysctl test");
return NULL;
}
if((p = malloc(len)) == NULL){
fprintf(stderr, "Out of memory\n");
return NULL;
}
if (sysctl(mib, sizeof(mib)/sizeof(int), p, &len, NULL, 0) == -1)
{
perror("sysctl real");
return NULL;
}
uinfo[i].pid = p->kp_proc.p_pid;
uinfo[i++].ppid = p->kp_eproc.e_ppid;
/*free(p); ?*/
return p;
}
struct passwd *
get_my_name(void)
{
struct passwd *pw;
/*I'm not that sure of the difference between guest and regular
accounts.*/
if((pw = getpwnam(getlogin()))== NULL ){
return NULL;
}
return pw;
}
int
compare (const void *a, const void *b)
{
uinfo_t *ma, *mb;
time_t time1, time2;
ma = (uinfo_t *)a;
mb = (uinfo_t *)b;
time1 = ma->in_login.ut_time;
time2 = mb->in_login.ut_time;
if(time1 < time2)
return -1;
else if(time1 > time2)
return 1;
else
return 0;
}
void
print_session(int count)
{
int i;
for(i = 0; i < count; i++)
printf("name: %s, tty: %s\n", uinfo[i].in_login.ut_name,
uinfo[i].in_login.ut_line);
}
void
find_sessions_to_kill(int count){
qsort(uinfo, count, sizeof(uinfo_t), compare);
print_session(count);
kill_sessions(count);
}
/*I only want to kill interactive sessions */
void
kill_sessions(int count)
{
int i;
for(i = 0; i < (count - 1); i++) {
kill(uinfo[i].ppid, SIGHUP);
if(kill(uinfo[i].ppid, 0) == -1 && errno == EPERM)
kill(uinfo[i].pid, SIGHUP);
}
}
int
main(void)
{
/*add error checking later on */
struct passwd *name;
int n;
if((name = get_my_name()) == NULL){
fprintf(stderr, "Can't get user name\n");
exit(1);
}
/*You don't need su privs to make the system do stupid sheep tricks
that is run by a clueless idiot*/
if((n = get_user_info(name->pw_name)) < 0)
exit(1);
if(n == 1 || n > MAX_USERS){
fprintf(stderr, "only logged in once.\n");
exit(1);
}
find_sessions_to_kill(n);
exit(0);
}
|
nullop
|
|
response 5 of 5:
|
Jan 6 16:38 UTC 2008 |
Vivek,
Most of the error checking was done for a pretty good reason. Actually, when
I think about it, I could give non trivial examples of where the code would
fail and/or have undefine behavior if the error checking was removed. Now,
if you do seem some possible redudant code, please cite the exact lines. I
could have done it because
1)I was being paranoid at the time.
2)I forgot that I did the exact same error checking somewhere else in the
code.
3)Or because of some stupid FreeBSDism.
Now, the only thing that is probably wrong with the code is how it does the
group checks. A while back, I started to investigate this. I gave up once
Unicorn aka Hitler started watching my Grex session. What I mean by 'group
checks' is that the program will preserve background jobs, but won't kill the
process if an external command spawns another shell. Think the GNU
debugger.
|