This commit is contained in:
parent
fc09b5b977
commit
fb9d74c195
@ -1,5 +1,5 @@
|
|||||||
--- doc/fuser.1
|
--- doc/fuser.1
|
||||||
+++ doc/fuser.1 2008-05-16 15:18:59.027600905 +0200
|
+++ doc/fuser.1 2008-05-16 15:18:59.000000000 +0200
|
||||||
@@ -80,8 +80,14 @@ List all known signal names.
|
@@ -80,8 +80,14 @@ List all known signal names.
|
||||||
\fIname\fP specifies a file on a mounted file system or a block device that
|
\fIname\fP specifies a file on a mounted file system or a block device that
|
||||||
is mounted. All processes accessing files on that file system are listed.
|
is mounted. All processes accessing files on that file system are listed.
|
||||||
@ -33,7 +33,7 @@
|
|||||||
cannot report on any processes that it doesn't have permission to look at
|
cannot report on any processes that it doesn't have permission to look at
|
||||||
the file descriptor table for. The most common time this problem occurs
|
the file descriptor table for. The most common time this problem occurs
|
||||||
--- src/fuser.c
|
--- src/fuser.c
|
||||||
+++ src/fuser.c 2007-12-19 18:45:34.954694000 +0100
|
+++ src/fuser.c 2008-08-07 14:47:58.126764924 +0200
|
||||||
@@ -32,6 +32,7 @@
|
@@ -32,6 +32,7 @@
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
@ -51,34 +51,41 @@
|
|||||||
static uid_t getpiduid(const pid_t pid);
|
static uid_t getpiduid(const pid_t pid);
|
||||||
static int print_matches(struct names *names_head, const opt_type opts, const int sig_number);
|
static int print_matches(struct names *names_head, const opt_type opts, const int sig_number);
|
||||||
static void kill_matched_proc(struct procs *pptr, const opt_type opts, const int sig_number);
|
static void kill_matched_proc(struct procs *pptr, const opt_type opts, const int sig_number);
|
||||||
@@ -72,13 +73,16 @@ static void add_device(struct device_lis
|
@@ -72,13 +73,15 @@ static void add_device(struct device_lis
|
||||||
void scan_mount_devices(const opt_type opts, struct mountdev_list **mount_devices);
|
void scan_mount_devices(const opt_type opts, struct mountdev_list **mount_devices);
|
||||||
void fill_unix_cache(struct unixsocket_list **unixsocket_head);
|
void fill_unix_cache(struct unixsocket_list **unixsocket_head);
|
||||||
static dev_t find_net_dev(void);
|
static dev_t find_net_dev(void);
|
||||||
-static void scan_procs(struct names *names_head, struct inode_list *ino_head, struct device_list *dev_head);
|
-static void scan_procs(struct names *names_head, struct inode_list *ino_head, struct device_list *dev_head);
|
||||||
+static void scan_procs(const opt_type opts, struct names *names_head, struct inode_list *ino_head, struct device_list *dev_head);
|
+static void scan_procs(const opt_type opts, struct names *names_head, struct inode_list *ino_head, struct device_list *dev_head, struct mountdev_list *mounts);
|
||||||
#ifdef NFS_CHECKS
|
#ifdef NFS_CHECKS
|
||||||
static void scan_knfsd(struct names *names_head, struct device_list *dev_head);
|
static void scan_knfsd(struct names *names_head, struct device_list *dev_head);
|
||||||
#endif /* NFS_CHECKS */
|
#endif /* NFS_CHECKS */
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
static void debug_match_lists(struct names *names_head, struct inode_list *ino_head, struct device_list *dev_head);
|
-static void debug_match_lists(struct names *names_head, struct inode_list *ino_head, struct device_list *dev_head);
|
||||||
|
+static void debug_match_lists(struct names *names_head, struct inode_list *ino_head, struct device_list *dev_head, struct mountdev_list *mounts);
|
||||||
#endif
|
#endif
|
||||||
+static struct nfs_points *mnts;
|
+static struct nfs_points *mnts;
|
||||||
+static void init_nfs(void);
|
|
||||||
+static int check4nfs(const char * path, char * real);
|
+static int check4nfs(const char * path, char * real);
|
||||||
|
|
||||||
static void usage (const char *errormsg)
|
static void usage (const char *errormsg)
|
||||||
{
|
{
|
||||||
@@ -127,7 +131,7 @@ void print_version()
|
@@ -127,7 +130,14 @@ void print_version()
|
||||||
"For more information about these matters, see the files named COPYING.\n"));
|
"For more information about these matters, see the files named COPYING.\n"));
|
||||||
}
|
}
|
||||||
|
|
||||||
-static void scan_procs(struct names *names_head, struct inode_list *ino_head, struct device_list *dev_head)
|
-static void scan_procs(struct names *names_head, struct inode_list *ino_head, struct device_list *dev_head)
|
||||||
+static void scan_procs(const opt_type opts, struct names *names_head, struct inode_list *ino_head, struct device_list *dev_head)
|
+static int islocatedon(const char * path, const char * loc)
|
||||||
|
+{
|
||||||
|
+ if (!path || *path == '\0')
|
||||||
|
+ return 0;
|
||||||
|
+ return (strstr(path, loc) == path);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static void scan_procs(const opt_type opts, struct names *names_head, struct inode_list *ino_head, struct device_list *dev_head, struct mountdev_list *mounts)
|
||||||
{
|
{
|
||||||
DIR *topproc_dir;
|
DIR *topproc_dir;
|
||||||
struct dirent *topproc_dent;
|
struct dirent *topproc_dent;
|
||||||
@@ -137,6 +141,9 @@ static void scan_procs(struct names *nam
|
@@ -137,6 +147,9 @@ static void scan_procs(struct names *nam
|
||||||
pid_t pid, my_pid;
|
pid_t pid, my_pid;
|
||||||
uid_t uid;
|
uid_t uid;
|
||||||
struct stat *cwd_stat, *exe_stat, *root_stat;
|
struct stat *cwd_stat, *exe_stat, *root_stat;
|
||||||
@ -88,7 +95,7 @@
|
|||||||
|
|
||||||
if ( (fd_dirpath = malloc(MAX_PATHNAME)) == NULL)
|
if ( (fd_dirpath = malloc(MAX_PATHNAME)) == NULL)
|
||||||
return;
|
return;
|
||||||
@@ -157,19 +164,30 @@ static void scan_procs(struct names *nam
|
@@ -157,9 +170,10 @@ static void scan_procs(struct names *nam
|
||||||
continue;
|
continue;
|
||||||
uid = getpiduid(pid);
|
uid = getpiduid(pid);
|
||||||
|
|
||||||
@ -101,50 +108,43 @@
|
|||||||
+ exe_stat = get_pidstat(opts, pid, "exe", exe_real);
|
+ exe_stat = get_pidstat(opts, pid, "exe", exe_real);
|
||||||
/* Scan the devices */
|
/* Scan the devices */
|
||||||
for (dev_tmp = dev_head ; dev_tmp != NULL ; dev_tmp = dev_tmp->next) {
|
for (dev_tmp = dev_head ; dev_tmp != NULL ; dev_tmp = dev_tmp->next) {
|
||||||
+ const char* filename = dev_tmp->name->filename;
|
|
||||||
+ size_t len = strlen(filename);
|
|
||||||
if (exe_stat != NULL && exe_stat->st_dev == dev_tmp->device)
|
if (exe_stat != NULL && exe_stat->st_dev == dev_tmp->device)
|
||||||
add_matched_proc(dev_tmp->name, pid, uid, ACCESS_EXE);
|
@@ -168,6 +182,14 @@ static void scan_procs(struct names *nam
|
||||||
if (root_stat != NULL && root_stat->st_dev == dev_tmp->device)
|
|
||||||
add_matched_proc(dev_tmp->name, pid, uid, ACCESS_ROOT);
|
add_matched_proc(dev_tmp->name, pid, uid, ACCESS_ROOT);
|
||||||
if (cwd_stat != NULL && cwd_stat->st_dev == dev_tmp->device)
|
if (cwd_stat != NULL && cwd_stat->st_dev == dev_tmp->device)
|
||||||
add_matched_proc(dev_tmp->name, pid, uid, ACCESS_CWD);
|
add_matched_proc(dev_tmp->name, pid, uid, ACCESS_CWD);
|
||||||
+ if (exe_real[0] != '\0' && !strncmp(&exe_real[0], filename, len))
|
+ if ((dev_tmp->name->name_space & NAMESPACE_NFS) == 0)
|
||||||
|
+ continue;
|
||||||
|
+ if (islocatedon(&exe_real[0], dev_tmp->name->filename))
|
||||||
+ add_matched_proc(dev_tmp->name, pid, uid, ACCESS_EXE);
|
+ add_matched_proc(dev_tmp->name, pid, uid, ACCESS_EXE);
|
||||||
+ if (root_real[0] != '\0' && !strncmp(&root_real[0], filename, len))
|
+ if (islocatedon(&root_real[0], dev_tmp->name->filename))
|
||||||
+ add_matched_proc(dev_tmp->name, pid, uid, ACCESS_ROOT);
|
+ add_matched_proc(dev_tmp->name, pid, uid, ACCESS_ROOT);
|
||||||
+ if (cwd_real[0] != '\0' && !strncmp(&cwd_real[0], filename, len))
|
+ if (islocatedon(&cwd_real[0], dev_tmp->name->filename))
|
||||||
+ add_matched_proc(dev_tmp->name, pid, uid, ACCESS_CWD);
|
+ add_matched_proc(dev_tmp->name, pid, uid, ACCESS_CWD);
|
||||||
}
|
}
|
||||||
for (ino_tmp = ino_head ; ino_tmp != NULL ; ino_tmp = ino_tmp->next) {
|
for (ino_tmp = ino_head ; ino_tmp != NULL ; ino_tmp = ino_tmp->next) {
|
||||||
+ const char* filename = ino_tmp->name->filename;
|
|
||||||
+ size_t len = strlen(filename);
|
|
||||||
if (exe_stat != NULL) {
|
if (exe_stat != NULL) {
|
||||||
if (exe_stat->st_dev == ino_tmp->device && exe_stat->st_ino == ino_tmp->inode) {
|
@@ -186,9 +208,19 @@ static void scan_procs(struct names *nam
|
||||||
add_matched_proc(ino_tmp->name, pid, uid, ACCESS_EXE);
|
|
||||||
@@ -186,6 +204,21 @@ static void scan_procs(struct names *nam
|
|
||||||
add_matched_proc(ino_tmp->name, pid, uid, ACCESS_CWD);
|
add_matched_proc(ino_tmp->name, pid, uid, ACCESS_CWD);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
+ if (exe_real[0] != '\0') {
|
+ if ((ino_tmp->name->name_space & NAMESPACE_NFS) == 0)
|
||||||
+ if (!strncmp(&exe_real[0], filename, len)) {
|
+ continue;
|
||||||
+ add_matched_proc(ino_tmp->name, pid, uid, ACCESS_EXE);
|
+ if (islocatedon(&exe_real[0], ino_tmp->name->filename))
|
||||||
+ }
|
+ add_matched_proc(ino_tmp->name, pid, uid, ACCESS_EXE);
|
||||||
+ }
|
+ if (islocatedon(&root_real[0], ino_tmp->name->filename))
|
||||||
+ if (root_real[0] != '\0') {
|
+ add_matched_proc(ino_tmp->name, pid, uid, ACCESS_ROOT);
|
||||||
+ if (!strncmp(&root_real[0], filename, len)) {
|
+ if (islocatedon(&cwd_real[0], ino_tmp->name->filename))
|
||||||
+ add_matched_proc(ino_tmp->name, pid, uid, ACCESS_ROOT);
|
+ add_matched_proc(ino_tmp->name, pid, uid, ACCESS_CWD);
|
||||||
+ }
|
|
||||||
+ }
|
|
||||||
+ if (cwd_real[0] != '\0') {
|
|
||||||
+ if (!strncmp(&cwd_real[0], filename, len)) {
|
|
||||||
+ add_matched_proc(ino_tmp->name, pid, uid, ACCESS_CWD);
|
|
||||||
+ }
|
|
||||||
+ }
|
|
||||||
}
|
}
|
||||||
|
+#ifndef __linux__
|
||||||
check_dir(pid, "lib", dev_head, ino_head, uid, ACCESS_MMAP);
|
check_dir(pid, "lib", dev_head, ino_head, uid, ACCESS_MMAP);
|
||||||
check_dir(pid, "mmap", dev_head, ino_head, uid, ACCESS_MMAP);
|
check_dir(pid, "mmap", dev_head, ino_head, uid, ACCESS_MMAP);
|
||||||
@@ -325,10 +358,26 @@ int parse_mount(struct names *this_name,
|
+#endif
|
||||||
|
check_dir(pid, "fd", dev_head, ino_head, uid, ACCESS_FILE);
|
||||||
|
check_map(pid, "maps", dev_head, ino_head, uid, ACCESS_MMAP);
|
||||||
|
|
||||||
|
@@ -325,10 +357,26 @@ int parse_mount(struct names *this_name,
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -172,7 +172,7 @@
|
|||||||
if (stat(this_name->filename, &st) != 0) {
|
if (stat(this_name->filename, &st) != 0) {
|
||||||
fprintf(stderr,_("Cannot stat %s: %s\n"), this_name->filename,
|
fprintf(stderr,_("Cannot stat %s: %s\n"), this_name->filename,
|
||||||
strerror(errno));
|
strerror(errno));
|
||||||
@@ -342,34 +391,44 @@ int parse_file(struct names *this_name,
|
@@ -342,34 +390,44 @@ int parse_file(struct names *this_name,
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -224,7 +224,7 @@
|
|||||||
|
|
||||||
if (stat(this_name->filename, &st) != 0) {
|
if (stat(this_name->filename, &st) != 0) {
|
||||||
fprintf(stderr,_("Cannot stat %s: %s\n"), this_name->filename,
|
fprintf(stderr,_("Cannot stat %s: %s\n"), this_name->filename,
|
||||||
@@ -388,6 +447,16 @@ int parse_mounts(struct names *this_name
|
@@ -388,6 +446,16 @@ int parse_mounts(struct names *this_name
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
@ -232,8 +232,8 @@
|
|||||||
+ match_device = -1;
|
+ match_device = -1;
|
||||||
+ for (mountptr = mounts ; mountptr != NULL ; mountptr = mountptr->next) {
|
+ for (mountptr = mounts ; mountptr != NULL ; mountptr = mountptr->next) {
|
||||||
+ if (strcmp(mountptr->dir, real) == 0) {
|
+ if (strcmp(mountptr->dir, real) == 0) {
|
||||||
+ printf("Debug: adding parse_mounts() adding %s\n",
|
+ /*printf("Debug: adding parse_mounts() adding %s\n",
|
||||||
+ this_name->filename);
|
+ this_name->filename);*/
|
||||||
+ add_device(dev_list, this_name, match_device);
|
+ add_device(dev_list, this_name, match_device);
|
||||||
+ }
|
+ }
|
||||||
+ }
|
+ }
|
||||||
@ -241,47 +241,10 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
#ifdef WITH_IPV6
|
#ifdef WITH_IPV6
|
||||||
@@ -652,6 +721,117 @@ void find_net6_sockets(struct inode_list
|
@@ -652,6 +720,80 @@ void find_net6_sockets(struct inode_list
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
+/*
|
|
||||||
+ * Remember all NFS typed partitions.
|
|
||||||
+ */
|
|
||||||
+static void init_nfs(void)
|
|
||||||
+{
|
|
||||||
+ struct stat st;
|
|
||||||
+ struct mntent * ent;
|
|
||||||
+ FILE * mnt;
|
|
||||||
+
|
|
||||||
+ mnts = (struct nfs_points*)0;
|
|
||||||
+
|
|
||||||
+ if (stat("/proc/version", &st) < 0)
|
|
||||||
+ return;
|
|
||||||
+ if ((mnt = setmntent("/proc/mounts", "r")) == (FILE*)0)
|
|
||||||
+ return;
|
|
||||||
+
|
|
||||||
+ while ((ent = getmntent(mnt))) {
|
|
||||||
+ if (!strcasecmp(MNTTYPE_NFS, ent->mnt_type)) {
|
|
||||||
+ struct nfs_points * p = (struct nfs_points*)malloc(sizeof(struct nfs_points));
|
|
||||||
+ if (!p)
|
|
||||||
+ goto out;
|
|
||||||
+ p->name = (char*)malloc(strlen(ent->mnt_dir)+1);
|
|
||||||
+ if (!p->name)
|
|
||||||
+ goto out;
|
|
||||||
+ strcpy(p->name, ent->mnt_dir);
|
|
||||||
+ p->nlen = strlen(p->name);
|
|
||||||
+ if (mnts)
|
|
||||||
+ mnts->prev = p;
|
|
||||||
+ p->next = mnts;
|
|
||||||
+ p->prev = (struct nfs_points*)0;
|
|
||||||
+ mnts = p;
|
|
||||||
+ }
|
|
||||||
+ }
|
|
||||||
+out:
|
|
||||||
+ endmntent(mnt);
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
+/*
|
+/*
|
||||||
+ * Check path is located on a NFS partition.
|
+ * Check path is located on a NFS partition.
|
||||||
+ */
|
+ */
|
||||||
@ -359,7 +322,7 @@
|
|||||||
int main(int argc, char *argv[])
|
int main(int argc, char *argv[])
|
||||||
{
|
{
|
||||||
opt_type opts;
|
opt_type opts;
|
||||||
@@ -664,7 +844,7 @@ int main(int argc, char *argv[])
|
@@ -664,7 +806,7 @@ int main(int argc, char *argv[])
|
||||||
struct device_list *match_devices = NULL;
|
struct device_list *match_devices = NULL;
|
||||||
struct unixsocket_list *unixsockets = NULL;
|
struct unixsocket_list *unixsockets = NULL;
|
||||||
|
|
||||||
@ -368,7 +331,7 @@
|
|||||||
struct ip_connections *tcp_connection_list = NULL;
|
struct ip_connections *tcp_connection_list = NULL;
|
||||||
struct ip_connections *udp_connection_list = NULL;
|
struct ip_connections *udp_connection_list = NULL;
|
||||||
#ifdef WITH_IPV6
|
#ifdef WITH_IPV6
|
||||||
@@ -691,10 +871,6 @@ int main(int argc, char *argv[])
|
@@ -691,10 +833,6 @@ int main(int argc, char *argv[])
|
||||||
textdomain(PACKAGE);
|
textdomain(PACKAGE);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -379,19 +342,18 @@
|
|||||||
/* getopt doesnt like things like -SIGBLAH */
|
/* getopt doesnt like things like -SIGBLAH */
|
||||||
for(optc = 1; optc < argc; optc++) {
|
for(optc = 1; optc < argc; optc++) {
|
||||||
if (argv[optc][0] == '-') { /* its an option */
|
if (argv[optc][0] == '-') { /* its an option */
|
||||||
@@ -782,6 +958,11 @@ int main(int argc, char *argv[])
|
@@ -782,6 +920,10 @@ int main(int argc, char *argv[])
|
||||||
}
|
}
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
+
|
+
|
||||||
+ init_nfs();
|
|
||||||
+ scan_mount_devices(opts, &mount_devices);
|
+ scan_mount_devices(opts, &mount_devices);
|
||||||
+ fill_unix_cache(&unixsockets);
|
+ fill_unix_cache(&unixsockets);
|
||||||
+
|
+
|
||||||
/* File specifications */
|
/* File specifications */
|
||||||
if ( (this_name = malloc(sizeof(struct names))) == NULL)
|
if ( (this_name = malloc(sizeof(struct names))) == NULL)
|
||||||
continue;
|
continue;
|
||||||
@@ -828,8 +1009,8 @@ int main(int argc, char *argv[])
|
@@ -828,8 +970,8 @@ int main(int argc, char *argv[])
|
||||||
break;
|
break;
|
||||||
default: /* FILE */
|
default: /* FILE */
|
||||||
this_name->filename = strdup(argv[optc]);
|
this_name->filename = strdup(argv[optc]);
|
||||||
@ -402,7 +364,7 @@
|
|||||||
if (opts & OPT_MOUNTPOINT || opts & OPT_MOUNTS)
|
if (opts & OPT_MOUNTPOINT || opts & OPT_MOUNTS)
|
||||||
parse_mounts(this_name, mount_devices, &match_devices, opts);
|
parse_mounts(this_name, mount_devices, &match_devices, opts);
|
||||||
break;
|
break;
|
||||||
@@ -857,22 +1038,22 @@ int main(int argc, char *argv[])
|
@@ -857,22 +999,22 @@ int main(int argc, char *argv[])
|
||||||
if (!ipv4_only) {
|
if (!ipv4_only) {
|
||||||
#endif
|
#endif
|
||||||
if (tcp_connection_list != NULL)
|
if (tcp_connection_list != NULL)
|
||||||
@ -423,14 +385,15 @@
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
debug_match_lists(names_head, match_inodes, match_devices);
|
- debug_match_lists(names_head, match_inodes, match_devices);
|
||||||
|
+ debug_match_lists(names_head, match_inodes, match_devices, mount_devices);
|
||||||
#endif
|
#endif
|
||||||
- scan_procs(names_head, match_inodes, match_devices);
|
- scan_procs(names_head, match_inodes, match_devices);
|
||||||
+ scan_procs(opts, names_head, match_inodes, match_devices);
|
+ scan_procs(opts, names_head, match_inodes, match_devices, mount_devices);
|
||||||
#ifdef NFS_CHECKS
|
#ifdef NFS_CHECKS
|
||||||
scan_knfsd(names_head, match_devices);
|
scan_knfsd(names_head, match_devices);
|
||||||
#endif /* NFS_CHECKS */
|
#endif /* NFS_CHECKS */
|
||||||
@@ -978,7 +1159,7 @@ static int print_matches(struct names *n
|
@@ -978,7 +1120,7 @@ static int print_matches(struct names *n
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -439,7 +402,7 @@
|
|||||||
{
|
{
|
||||||
char pathname[256];
|
char pathname[256];
|
||||||
struct stat *st;
|
struct stat *st;
|
||||||
@@ -986,6 +1167,10 @@ static struct stat *get_pidstat(const pi
|
@@ -986,6 +1128,10 @@ static struct stat *get_pidstat(const pi
|
||||||
if ( (st = malloc(sizeof(struct stat))) == NULL)
|
if ( (st = malloc(sizeof(struct stat))) == NULL)
|
||||||
return NULL;
|
return NULL;
|
||||||
snprintf(pathname, 256, "/proc/%d/%s", pid, filename);
|
snprintf(pathname, 256, "/proc/%d/%s", pid, filename);
|
||||||
@ -450,7 +413,14 @@
|
|||||||
if (stat(pathname, st) != 0)
|
if (stat(pathname, st) != 0)
|
||||||
return NULL;
|
return NULL;
|
||||||
else
|
else
|
||||||
@@ -1019,6 +1204,8 @@ static void check_dir(const pid_t pid, c
|
@@ -1012,13 +1158,14 @@ static void check_dir(const pid_t pid, c
|
||||||
|
while ( (direntry = readdir(dirp)) != NULL) {
|
||||||
|
if (direntry->d_name[0] < '0' || direntry->d_name[0] > '9')
|
||||||
|
continue;
|
||||||
|
-
|
||||||
|
snprintf(filepath, MAX_PATHNAME, "/proc/%d/%s/%s",
|
||||||
|
pid, dirname, direntry->d_name);
|
||||||
|
if (stat(filepath, &st) != 0) {
|
||||||
fprintf(stderr, _("Cannot stat file %s: %s\n"),filepath, strerror(errno));
|
fprintf(stderr, _("Cannot stat file %s: %s\n"),filepath, strerror(errno));
|
||||||
} else {
|
} else {
|
||||||
for (dev_tmp = dev_head ; dev_tmp != NULL ; dev_tmp = dev_tmp->next) {
|
for (dev_tmp = dev_head ; dev_tmp != NULL ; dev_tmp = dev_tmp->next) {
|
||||||
@ -459,7 +429,7 @@
|
|||||||
if (st.st_dev == dev_tmp->device) {
|
if (st.st_dev == dev_tmp->device) {
|
||||||
if (access == ACCESS_FILE && (lstat(filepath, &lst)==0) && (lst.st_mode & S_IWUSR)) {
|
if (access == ACCESS_FILE && (lstat(filepath, &lst)==0) && (lst.st_mode & S_IWUSR)) {
|
||||||
add_matched_proc(dev_tmp->name, pid,uid, ACCESS_FILEWR|access);
|
add_matched_proc(dev_tmp->name, pid,uid, ACCESS_FILEWR|access);
|
||||||
@@ -1028,6 +1215,8 @@ static void check_dir(const pid_t pid, c
|
@@ -1028,6 +1175,8 @@ static void check_dir(const pid_t pid, c
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for (ino_tmp = ino_head ; ino_tmp != NULL ; ino_tmp = ino_tmp->next) {
|
for (ino_tmp = ino_head ; ino_tmp != NULL ; ino_tmp = ino_tmp->next) {
|
||||||
@ -468,7 +438,16 @@
|
|||||||
if (st.st_dev == ino_tmp->device && st.st_ino == ino_tmp->inode) {
|
if (st.st_dev == ino_tmp->device && st.st_ino == ino_tmp->inode) {
|
||||||
if (access == ACCESS_FILE && (lstat(filepath, &lst)==0) && (lst.st_mode & S_IWUSR)) {
|
if (access == ACCESS_FILE && (lstat(filepath, &lst)==0) && (lst.st_mode & S_IWUSR)) {
|
||||||
add_matched_proc(ino_tmp->name, pid,uid, ACCESS_FILEWR|access);
|
add_matched_proc(ino_tmp->name, pid,uid, ACCESS_FILEWR|access);
|
||||||
@@ -1059,12 +1248,18 @@ static void check_map(const pid_t pid, c
|
@@ -1039,6 +1188,8 @@ static void check_dir(const pid_t pid, c
|
||||||
|
}
|
||||||
|
} /* while fd_dent */
|
||||||
|
closedir(dirp);
|
||||||
|
+ free(dirpath);
|
||||||
|
+ free(filepath);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void check_map(const pid_t pid, const char *filename, struct device_list *dev_head, struct inode_list *ino_head, const uid_t uid, const char access)
|
||||||
|
@@ -1059,12 +1210,18 @@ static void check_map(const pid_t pid, c
|
||||||
if (sscanf(line, "%*s %*s %*s %x:%x %lld",
|
if (sscanf(line, "%*s %*s %*s %x:%x %lld",
|
||||||
&tmp_maj, &tmp_min, &tmp_inode) == 3) {
|
&tmp_maj, &tmp_min, &tmp_inode) == 3) {
|
||||||
tmp_device = tmp_maj * 256 + tmp_min;
|
tmp_device = tmp_maj * 256 + tmp_min;
|
||||||
@ -489,39 +468,62 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
fclose(fp);
|
fclose(fp);
|
||||||
@@ -1144,6 +1339,7 @@ void scan_mount_devices(const opt_type o
|
@@ -1144,22 +1301,48 @@ void scan_mount_devices(const opt_type o
|
||||||
FILE *mntfp;
|
FILE *mntfp;
|
||||||
struct mntent *mnt_ptr;
|
struct mntent *mnt_ptr;
|
||||||
struct stat st;
|
struct stat st;
|
||||||
+ char real[PATH_MAX+1] = "";
|
-
|
||||||
|
- if ( (mntfp = setmntent("/etc/mtab","r")) == NULL) {
|
||||||
if ( (mntfp = setmntent("/etc/mtab","r")) == NULL) {
|
- fprintf(stderr, _("Cannot open /etc/mtab: %s\n"),
|
||||||
fprintf(stderr, _("Cannot open /etc/mtab: %s\n"),
|
- strerror(errno));
|
||||||
@@ -1151,10 +1347,22 @@ void scan_mount_devices(const opt_type o
|
+
|
||||||
|
+ if (stat("/proc/version", &st) < 0)
|
||||||
|
+ mntfp = setmntent("/etc/mtab","r");
|
||||||
|
+ else
|
||||||
|
+ mntfp = setmntent("/proc/mounts", "r");
|
||||||
|
+ if (mntfp == NULL) {
|
||||||
|
+ fprintf(stderr, _("Cannot open /etc/mtab: %s\n"), strerror(errno));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
while ( (mnt_ptr = getmntent(mntfp)) != NULL) {
|
while ( (mnt_ptr = getmntent(mntfp)) != NULL) {
|
||||||
+ real[0] = '\0';
|
+ if (!strcasecmp(MNTTYPE_NFS, mnt_ptr->mnt_type)) {
|
||||||
+ if (check4nfs(mnt_ptr->mnt_dir, real)) {
|
+ /*
|
||||||
|
+ * Remember all NFS typed partitions.
|
||||||
|
+ */
|
||||||
|
+ struct nfs_points * p = (struct nfs_points*)malloc(sizeof(struct nfs_points));
|
||||||
|
+ if (!p)
|
||||||
|
+ goto out;
|
||||||
|
+ p->name = strdup(mnt_ptr->mnt_dir);
|
||||||
|
+ if (!p->name)
|
||||||
|
+ goto out;
|
||||||
|
+ p->nlen = strlen(p->name);
|
||||||
|
+ if (mnts)
|
||||||
|
+ mnts->prev = p;
|
||||||
|
+ p->next = mnts;
|
||||||
|
+ p->prev = (struct nfs_points*)0;
|
||||||
|
+ mnts = p;
|
||||||
+ if ((opts & (OPT_MOUNTPOINT|OPT_MOUNTS)) == 0) {
|
+ if ((opts & (OPT_MOUNTPOINT|OPT_MOUNTS)) == 0) {
|
||||||
+ add_mount_device(mount_devices, mnt_ptr->mnt_fsname, real, (dev_t)-1);
|
+ add_mount_device(mount_devices, mnt_ptr->mnt_fsname, mnt_ptr->mnt_dir, (dev_t)-1);
|
||||||
+ continue;
|
+ continue;
|
||||||
+ }
|
+ }
|
||||||
+ }
|
|
||||||
+ if ((real[0] != '\0') && (stat(real, &st) == 0)) {
|
|
||||||
+ add_mount_device(mount_devices, mnt_ptr->mnt_fsname, real, st.st_dev);
|
|
||||||
+ continue;
|
|
||||||
+ }
|
+ }
|
||||||
if (stat(mnt_ptr->mnt_dir, &st) == 0) {
|
if (stat(mnt_ptr->mnt_dir, &st) == 0) {
|
||||||
add_mount_device(mount_devices, mnt_ptr->mnt_fsname, mnt_ptr->mnt_dir, st.st_dev);
|
add_mount_device(mount_devices, mnt_ptr->mnt_fsname, mnt_ptr->mnt_dir, st.st_dev);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
+out:
|
||||||
+ endmntent(mntfp);
|
+ endmntent(mntfp);
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
|
/* often not used, doesnt need translation */
|
||||||
|
-static void debug_match_lists(struct names *names_head, struct inode_list *ino_head, struct device_list *dev_head)
|
||||||
|
+static void debug_match_lists(struct names *names_head, struct inode_list *ino_head, struct device_list *dev_head, )
|
||||||
|
{
|
||||||
|
struct names *nptr;
|
||||||
|
struct inode_list *iptr;
|
||||||
--- src/fuser.h
|
--- src/fuser.h
|
||||||
+++ src/fuser.h 2007-12-19 18:50:05.501016000 +0100
|
+++ src/fuser.h 2008-08-07 14:26:47.587191317 +0200
|
||||||
@@ -80,9 +80,16 @@ struct unixsocket_list {
|
@@ -80,9 +80,16 @@ struct unixsocket_list {
|
||||||
struct unixsocket_list *next;
|
struct unixsocket_list *next;
|
||||||
};
|
};
|
||||||
|
148
psmisc-22.6-writeonly.patch
Normal file
148
psmisc-22.6-writeonly.patch
Normal file
@ -0,0 +1,148 @@
|
|||||||
|
--- doc/fuser.1
|
||||||
|
+++ doc/fuser.1 2008-08-07 14:51:18.000000000 +0200
|
||||||
|
@@ -10,6 +10,7 @@ fuser \- identify processes using files
|
||||||
|
.IR space\ ]
|
||||||
|
.RB [ \-k
|
||||||
|
.RB [ \-i ]
|
||||||
|
+.RB [ \-w ]
|
||||||
|
.RB [ \- \fIsignal
|
||||||
|
] ]
|
||||||
|
.RB [ \-muvf ]
|
||||||
|
@@ -74,6 +75,9 @@ other \fBfuser\fP processes. The effecti
|
||||||
|
.IP \fB\-i\fP
|
||||||
|
Ask the user for confirmation before killing a process. This option is
|
||||||
|
silently ignored if \fB\-k\fP is not present too.
|
||||||
|
+.IP \fB\-w\fP
|
||||||
|
+Kill only processes which have write access. This option is
|
||||||
|
+silently ignored if \fB\-k\fP is not present too.
|
||||||
|
.IP \fB\-l\fP
|
||||||
|
List all known signal names.
|
||||||
|
.IP \fB\-m\fP
|
||||||
|
--- src/fuser.c
|
||||||
|
+++ src/fuser.c 2008-08-07 15:49:28.714368021 +0200
|
||||||
|
@@ -66,7 +66,7 @@ static void check_map(const pid_t pid, c
|
||||||
|
static struct stat *get_pidstat(const opt_type opts, const pid_t pid, const char *filename, char *real);
|
||||||
|
static uid_t getpiduid(const pid_t pid);
|
||||||
|
static int print_matches(struct names *names_head, const opt_type opts, const int sig_number);
|
||||||
|
-static void kill_matched_proc(struct procs *pptr, const opt_type opts, const int sig_number);
|
||||||
|
+static int kill_matched_proc(struct procs *pptr, const opt_type opts, const int sig_number);
|
||||||
|
|
||||||
|
int parse_mount(struct names *this_name, struct device_list **dev_list);
|
||||||
|
static void add_device(struct device_list **dev_list, struct names *this_name, dev_t device);
|
||||||
|
@@ -89,7 +89,7 @@ static void usage (const char *errormsg)
|
||||||
|
fprintf(stderr, "%s\n", errormsg);
|
||||||
|
|
||||||
|
fprintf (stderr, _(
|
||||||
|
- "Usage: fuser [ -a | -s | -c ] [ -n SPACE ] [ -SIGNAL ] [ -kimuv ] NAME...\n"
|
||||||
|
+ "Usage: fuser [ -a | -s | -c ] [ -n SPACE ] [ -SIGNAL ] [ -kimuvw ] NAME...\n"
|
||||||
|
" [ - ] [ -n SPACE ] [ -SIGNAL ] [ -kimuv ] NAME...\n"
|
||||||
|
" fuser -l\n"
|
||||||
|
" fuser -V\n"
|
||||||
|
@@ -106,6 +106,7 @@ static void usage (const char *errormsg)
|
||||||
|
" -SIGNAL send this signal instead of SIGKILL\n"
|
||||||
|
" -u display user IDs\n"
|
||||||
|
" -v verbose output\n"
|
||||||
|
+ " -w kill only processes with write access\n"
|
||||||
|
" -V display version information\n"));
|
||||||
|
#ifdef WITH_IPV6
|
||||||
|
fprintf (stderr, _(
|
||||||
|
@@ -901,6 +902,9 @@ int main(int argc, char *argv[])
|
||||||
|
case 'v':
|
||||||
|
opts |= OPT_VERBOSE;
|
||||||
|
break;
|
||||||
|
+ case 'w':
|
||||||
|
+ opts |= OPT_WRITE;
|
||||||
|
+ break;
|
||||||
|
case 'V':
|
||||||
|
print_version();
|
||||||
|
return 0;
|
||||||
|
@@ -1033,6 +1037,7 @@ static int print_matches(struct names *n
|
||||||
|
int len = 0;
|
||||||
|
struct passwd *pwent = NULL;
|
||||||
|
int have_match = 0;
|
||||||
|
+ int have_kill = 0;
|
||||||
|
|
||||||
|
for (nptr = names_head; nptr != NULL ; nptr = nptr->next) {
|
||||||
|
if (opts & OPT_SILENT) {
|
||||||
|
@@ -1103,21 +1108,23 @@ static int print_matches(struct names *n
|
||||||
|
len = 0;
|
||||||
|
first = 0;
|
||||||
|
}
|
||||||
|
- if (opts & OPT_VERBOSE) {
|
||||||
|
- /* put a newline if showing all files and no procs*/
|
||||||
|
- if (nptr->matched_procs == NULL && (opts & OPT_ALLFILES))
|
||||||
|
- putc('\n', stderr);
|
||||||
|
- } else {
|
||||||
|
- if (nptr->matched_procs != NULL || (opts & OPT_ALLFILES))
|
||||||
|
- putc('\n', stderr);
|
||||||
|
- }
|
||||||
|
+ if (opts & OPT_VERBOSE) {
|
||||||
|
+ /* put a newline if showing all files and no procs*/
|
||||||
|
+ if (nptr->matched_procs == NULL && (opts & OPT_ALLFILES))
|
||||||
|
+ putc('\n', stderr);
|
||||||
|
+ } else {
|
||||||
|
+ if (nptr->matched_procs != NULL || (opts & OPT_ALLFILES))
|
||||||
|
+ putc('\n', stderr);
|
||||||
|
+ }
|
||||||
|
} /* be silent */
|
||||||
|
if (opts & OPT_KILL)
|
||||||
|
- kill_matched_proc(nptr->matched_procs, opts, sig_number);
|
||||||
|
+ have_kill = kill_matched_proc(nptr->matched_procs, opts, sig_number);
|
||||||
|
|
||||||
|
} /* next name */
|
||||||
|
- return (have_match==1?0:1);
|
||||||
|
-
|
||||||
|
+ if (opts & OPT_KILL)
|
||||||
|
+ return (have_kill==1?0:1);
|
||||||
|
+ else
|
||||||
|
+ return (have_match==1?0:1);
|
||||||
|
}
|
||||||
|
|
||||||
|
static struct stat *get_pidstat(const opt_type opts, const pid_t pid, const char *filename, char *real)
|
||||||
|
@@ -1403,21 +1410,26 @@ static int ask(const pid_t pid)
|
||||||
|
} /* while */
|
||||||
|
}
|
||||||
|
|
||||||
|
-static void kill_matched_proc(struct procs *proc_head, const opt_type opts, const int sig_number)
|
||||||
|
+static int kill_matched_proc(struct procs *proc_head, const opt_type opts, const int sig_number)
|
||||||
|
{
|
||||||
|
struct procs *pptr;
|
||||||
|
+ int ret = 0;
|
||||||
|
|
||||||
|
for (pptr = proc_head ; pptr != NULL ; pptr = pptr->next ) {
|
||||||
|
if ( (opts & OPT_INTERACTIVE) && (ask(pptr->pid) == 0))
|
||||||
|
continue;
|
||||||
|
+ if ((opts & OPT_WRITE) && ((pptr->access & ACCESS_FILEWR) == 0))
|
||||||
|
+ continue;
|
||||||
|
if ( kill (pptr->pid, sig_number) < 0) {
|
||||||
|
fprintf(stderr, _("Could not kill process %d: %s\n"),
|
||||||
|
pptr->pid,
|
||||||
|
strerror(errno)
|
||||||
|
);
|
||||||
|
+ continue;
|
||||||
|
}
|
||||||
|
-
|
||||||
|
+ ret = 1;
|
||||||
|
}
|
||||||
|
+ return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
static dev_t find_net_dev(void)
|
||||||
|
--- src/fuser.h
|
||||||
|
+++ src/fuser.h 2008-08-07 14:26:48.000000000 +0200
|
||||||
|
@@ -1,6 +1,6 @@
|
||||||
|
|
||||||
|
/* Option Flags */
|
||||||
|
-typedef unsigned char opt_type;
|
||||||
|
+typedef unsigned short opt_type;
|
||||||
|
|
||||||
|
#define OPT_VERBOSE 1
|
||||||
|
#define OPT_ALLFILES 2
|
||||||
|
@@ -10,6 +10,7 @@ typedef unsigned char opt_type;
|
||||||
|
#define OPT_SILENT 32
|
||||||
|
#define OPT_USER 64
|
||||||
|
#define OPT_MOUNTPOINT 128
|
||||||
|
+#define OPT_WRITE 256
|
||||||
|
|
||||||
|
|
||||||
|
struct procs {
|
@ -1,3 +1,9 @@
|
|||||||
|
-------------------------------------------------------------------
|
||||||
|
Thu Aug 7 15:12:14 CEST 2008 - werner@suse.de
|
||||||
|
|
||||||
|
- Refine NFS patch
|
||||||
|
- Add option -w for killing only procs with write access
|
||||||
|
|
||||||
-------------------------------------------------------------------
|
-------------------------------------------------------------------
|
||||||
Fri May 16 17:19:31 CEST 2008 - werner@suse.de
|
Fri May 16 17:19:31 CEST 2008 - werner@suse.de
|
||||||
|
|
||||||
|
18
psmisc.spec
18
psmisc.spec
@ -2,9 +2,16 @@
|
|||||||
# spec file for package psmisc (Version 22.6)
|
# spec file for package psmisc (Version 22.6)
|
||||||
#
|
#
|
||||||
# Copyright (c) 2008 SUSE LINUX Products GmbH, Nuernberg, Germany.
|
# Copyright (c) 2008 SUSE LINUX Products GmbH, Nuernberg, Germany.
|
||||||
# This file and all modifications and additions to the pristine
|
|
||||||
# package are under the same license as the package itself.
|
|
||||||
#
|
#
|
||||||
|
# All modifications and additions to the file contributed by third parties
|
||||||
|
# remain the property of their copyright owners, unless otherwise agreed
|
||||||
|
# upon. The license for this file, and modifications and additions to the
|
||||||
|
# file, is the same license as for the pristine package itself (unless the
|
||||||
|
# license for the pristine package is not an Open Source License, in which
|
||||||
|
# case the license is the MIT License). An "Open Source License" is a
|
||||||
|
# license that conforms to the Open Source Definition (Version 1.9)
|
||||||
|
# published by the Open Source Initiative.
|
||||||
|
|
||||||
# Please submit bugfixes or comments via http://bugs.opensuse.org/
|
# Please submit bugfixes or comments via http://bugs.opensuse.org/
|
||||||
#
|
#
|
||||||
|
|
||||||
@ -19,7 +26,7 @@ Group: System/Monitoring
|
|||||||
PreReq: %fillup_prereq %insserv_prereq
|
PreReq: %fillup_prereq %insserv_prereq
|
||||||
AutoReqProv: on
|
AutoReqProv: on
|
||||||
Version: 22.6
|
Version: 22.6
|
||||||
Release: 28
|
Release: 42
|
||||||
Provides: ps:/usr/bin/killall
|
Provides: ps:/usr/bin/killall
|
||||||
Summary: Utilities for managing processes on your system
|
Summary: Utilities for managing processes on your system
|
||||||
Source: http://switch.dl.sourceforge.net/sourceforge/psmisc/psmisc-%{version}.tar.bz2
|
Source: http://switch.dl.sourceforge.net/sourceforge/psmisc/psmisc-%{version}.tar.bz2
|
||||||
@ -27,6 +34,7 @@ Patch0: %name-%version.dif
|
|||||||
Patch1: %name-22.5-pstree.patch
|
Patch1: %name-22.5-pstree.patch
|
||||||
Patch2: %name-22.6-nfs4fuser.patch
|
Patch2: %name-22.6-nfs4fuser.patch
|
||||||
Patch3: %name-22.6-netunix.patch
|
Patch3: %name-22.6-netunix.patch
|
||||||
|
Patch4: %name-22.6-writeonly.patch
|
||||||
BuildRoot: %{_tmppath}/%{name}-%{version}-build
|
BuildRoot: %{_tmppath}/%{name}-%{version}-build
|
||||||
%define nopeek s390 s390x ia64
|
%define nopeek s390 s390x ia64
|
||||||
|
|
||||||
@ -49,6 +57,7 @@ Authors:
|
|||||||
%patch1 -p0 -b .pstree
|
%patch1 -p0 -b .pstree
|
||||||
%patch2 -p0 -b .nfs4fuser
|
%patch2 -p0 -b .nfs4fuser
|
||||||
%patch3 -p0 -b .netunix
|
%patch3 -p0 -b .netunix
|
||||||
|
%patch4 -p0 -b .wrtonly
|
||||||
%patch0 -p0
|
%patch0 -p0
|
||||||
|
|
||||||
%build
|
%build
|
||||||
@ -91,6 +100,9 @@ rm -rf $RPM_BUILD_ROOT
|
|||||||
%{_mandir}/man1/pstree.1*
|
%{_mandir}/man1/pstree.1*
|
||||||
|
|
||||||
%changelog
|
%changelog
|
||||||
|
* Thu Aug 07 2008 werner@suse.de
|
||||||
|
- Refine NFS patch
|
||||||
|
- Add option -w for killing only procs with write access
|
||||||
* Fri May 16 2008 werner@suse.de
|
* Fri May 16 2008 werner@suse.de
|
||||||
- Add a warning about fusers option -m due NFS locks
|
- Add a warning about fusers option -m due NFS locks
|
||||||
- Strip @ symbol from file names read from /proc/net/unix
|
- Strip @ symbol from file names read from /proc/net/unix
|
||||||
|
Loading…
Reference in New Issue
Block a user