~ubuntu-branches/ubuntu/edgy/rxtx/edgy

« back to all changes in this revision

Viewing changes to src/fuserImp.c

  • Committer: Bazaar Package Importer
  • Author(s): Mario Joussen
  • Date: 2002-03-06 00:50:09 UTC
  • Revision ID: james.westby@ubuntu.com-20020306005009-8myjehevn1eu3u78
Tags: upstream-1.5.9pre5
ImportĀ upstreamĀ versionĀ 1.5.9pre5

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
#if defined(__MWERKS__)//dima
 
2
#include "CommPortIdentifier.h"
 
3
#else//dima
 
4
#include "gnu_io_CommPortIdentifier.h"
 
5
#endif//dima
 
6
#ifndef __linux__
 
7
JNIEXPORT jstring JNICALL Java_gnu_io_CommPortIdentifier_native_1psmisc_1report_1owner (JNIEnv *env, jobject obj, jstring arg)
 
8
{
 
9
        return (*env)->NewStringUTF(env, "Unknown Application");
 
10
        //return("Unknown Application\n");
 
11
}
 
12
#else
 
13
/* loosly based on fuser.c by Werner Almesberger. */
 
14
 
 
15
/* Copyright 1993-1998 Werner Almesberger. See file COPYING for details. 
 
16
psmisc (fuser, killall and pstree) program code, documentation and
 
17
auxiliary programs are
 
18
Copyright 1993-1998 Werner Almesberger.
 
19
All rights reserved.
 
20
 
 
21
Redistribution and use in source and binary forms of parts of or the
 
22
whole original or derived work are permitted provided that the
 
23
original work is properly attributed to the author. The name of the
 
24
author may not be used to endorse or promote products derived from
 
25
this software without specific prior written permission. This work
 
26
is provided "as is" and without any express or implied warranties.
 
27
*/
 
28
#include <stdio.h>
 
29
#include <string.h>
 
30
#include <dirent.h>
 
31
#include <pwd.h>
 
32
#include <signal.h>
 
33
#include <sys/stat.h>
 
34
#include <linux/major.h>
 
35
#include <unistd.h>
 
36
#include <sys/types.h>
 
37
#include <stdlib.h>
 
38
 
 
39
#define COMM_LEN 16
 
40
#define PROC_BASE  "/proc"
 
41
#define UID_UNKNOWN -1
 
42
#define NAME_FIELD 20 /* space reserved for file name */
 
43
#define REF_FILE   1    /* an open file */
 
44
#define REF_ROOT   2    /* current root */
 
45
#define REF_CWD    4    /* current directory */
 
46
#define REF_EXE    8    /* executable */
 
47
#define REF_MMAP  16    /* mmap'ed file or library */
 
48
#define FLAG_UID   2    /* show uid */
 
49
#define FLAG_VERB  4    /* show verbose output */
 
50
#define FLAG_DEV   8    /* show all processes using this device */
 
51
 
 
52
 
 
53
char returnstring[256];
 
54
void parse_args(const char *);
 
55
typedef struct {
 
56
    const char *name;
 
57
} SPACE_DSC;
 
58
 
 
59
typedef enum { it_proc,it_mount,it_loop,it_swap } ITEM_TYPE;
 
60
 
 
61
typedef struct item_dsc {
 
62
    ITEM_TYPE type;
 
63
    union {
 
64
        struct {
 
65
            pid_t pid;
 
66
            int uid; /* must also accept UID_UNKNOWN */
 
67
            int ref_set;
 
68
        } proc;
 
69
        struct {
 
70
            const char *path;
 
71
        } misc;
 
72
    } u;
 
73
    struct item_dsc *next;
 
74
} ITEM_DSC;
 
75
 
 
76
typedef struct file_dsc {
 
77
    const char *name;  /* NULL if previous entry has name */
 
78
    dev_t dev;
 
79
    ino_t ino;
 
80
    int flags,sig_num;
 
81
    SPACE_DSC *name_space; /* or NULL if no indication */
 
82
    ITEM_DSC *items;
 
83
    struct file_dsc *named,*next;
 
84
} FILE_DSC;
 
85
 
 
86
static SPACE_DSC name_spaces[] = { };
 
87
static FILE_DSC *files = NULL;
 
88
static FILE_DSC *last_named = NULL;
 
89
static int all = 0,found_item = 0;
 
90
 
 
91
static void add_file(const char *path,unsigned long device,unsigned long inode, pid_t pid,int ref)
 
92
{
 
93
    struct stat st;
 
94
    FILE_DSC *file,*next;
 
95
    ITEM_DSC **item,*this;
 
96
    unsigned long mount_dev = 0;
 
97
 
 
98
    if (device) mount_dev = device;
 
99
    for (file = files; file; file = next) {
 
100
        next = file->next;
 
101
        if (file->flags & FLAG_DEV ? mount_dev && mount_dev == file->dev :
 
102
          device == file->dev && inode == file->ino) {
 
103
            if (!file->name) file = file->named;
 
104
            for (item = &file->items; *item; item = &(*item)->next)
 
105
                if ((*item)->type == it_proc && (*item)->u.proc.pid >= pid)
 
106
                    break;
 
107
            if (*item && (*item)->u.proc.pid == pid) this = *item;
 
108
            else {
 
109
                if (!(this = malloc(sizeof(ITEM_DSC)))) {
 
110
                    perror("malloc");
 
111
                    exit(1);
 
112
                }
 
113
                this->type = it_proc;
 
114
                this->u.proc.pid = pid;
 
115
                this->u.proc.uid = UID_UNKNOWN;
 
116
                this->u.proc.ref_set = 0;
 
117
                this->next = *item;
 
118
                *item = this;
 
119
                found_item = 1;
 
120
            }
 
121
            this->u.proc.ref_set |= ref;
 
122
            if ((file->flags & (FLAG_UID | FLAG_VERB)) && this->u.proc.uid == UID_UNKNOWN && lstat(path,&st) >= 0) 
 
123
                this->u.proc.uid = st.st_uid;
 
124
        }
 
125
    }
 
126
}
 
127
 
 
128
static void check_dir(const char *rel,pid_t pid,int type)
 
129
{
 
130
    DIR *dir;
 
131
    struct dirent *de;
 
132
    char path[PATH_MAX+1];
 
133
    struct stat st;
 
134
 
 
135
    if (!(dir = opendir(rel))) return;
 
136
    while ( (de = readdir(dir) ) )
 
137
        if (strcmp(de->d_name,".") && strcmp(de->d_name,"..")) {
 
138
            sprintf(path,"%s/%s",rel,de->d_name);
 
139
            if (stat(path,&st) >= 0)
 
140
               add_file(path,st.st_dev,st.st_ino,pid,type);
 
141
        }
 
142
    (void) closedir(dir);
 
143
}
 
144
 
 
145
 
 
146
extern void scan_fd(void)
 
147
{
 
148
    DIR *dir;
 
149
    struct dirent *de;
 
150
    char path[PATH_MAX+1];
 
151
    pid_t pid;
 
152
    int empty;
 
153
 
 
154
    if (!(dir = opendir(PROC_BASE))) {
 
155
        perror(PROC_BASE);
 
156
        exit(1);
 
157
    }
 
158
    empty = 1;
 
159
    while ( ( de = readdir(dir) ) )
 
160
        if ( ( pid = atoi(de->d_name) ) ) {
 
161
            empty = 0;
 
162
            sprintf(path,"%s/%d",PROC_BASE,pid);
 
163
            if (chdir(path) >= 0) {
 
164
                check_dir("fd",pid,REF_FILE);
 
165
            }
 
166
        }
 
167
    (void) closedir(dir);
 
168
    if (empty) {
 
169
        fprintf(stderr,PROC_BASE " is empty (not mounted ?)\n");
 
170
        exit(1);
 
171
    }
 
172
}
 
173
 
 
174
extern void show_user(const char tstring[],char *rs)
 
175
{
 
176
    const ITEM_DSC *item;
 
177
    FILE *f;
 
178
    const struct passwd *pw;
 
179
    const char *user,*scan;
 
180
    char tmp[10],path[PATH_MAX+1],comm[COMM_LEN+1];
 
181
    int dummy;
 
182
    int keeper;
 
183
    pid_t self;
 
184
    const char *name;
 
185
    int uid;
 
186
    char temp[80];
 
187
 
 
188
    parse_args(tstring);
 
189
    scan_fd();
 
190
    if (seteuid(getuid()) < 0) { 
 
191
        sprintf(rs, "%s", "Unknown Linux Application");
 
192
        return; 
 
193
    }
 
194
    self = getpid();
 
195
    if (!files->name || !(files->items || all))
 
196
    {
 
197
         sprintf(rs, "%s", "Unknown Linux Application");
 
198
         return; 
 
199
    }
 
200
    scan = files->name;
 
201
    strcat(returnstring," ");
 
202
    item = files->items;
 
203
    sprintf(path,PROC_BASE "/%d/stat",item->u.proc.pid);
 
204
    strcpy(comm,"???");
 
205
    if ( ( f = fopen(path,"r") ) ) {
 
206
        (void) fscanf(f,"%d (%[^)]",&dummy,comm);
 
207
        (void) fclose(f);
 
208
    }
 
209
    name = comm;
 
210
    uid = item->u.proc.uid;
 
211
    if (uid == UID_UNKNOWN) user = "???";
 
212
    else if ( ( pw = getpwuid(uid) ) ) user = pw->pw_name;
 
213
    else {
 
214
        sprintf(tmp,"%d",uid);
 
215
        user = tmp;
 
216
    }
 
217
    strcat(returnstring,user);
 
218
    strcat(returnstring," PID = ");
 
219
    sprintf(temp,"%6d ",item->u.proc.pid);
 
220
    strcat(returnstring,temp);
 
221
    strcat(returnstring,"Program = ");
 
222
    if (name)
 
223
    {
 
224
         for (scan = name; *scan; scan++)
 
225
         {
 
226
              if (*scan == '\\') 
 
227
              {
 
228
                  sprintf(temp,"\\\\");
 
229
                  strcat(returnstring,temp);
 
230
              }
 
231
              else if (*scan > ' ' && *scan <= '~')
 
232
              {
 
233
                  keeper=strlen(returnstring);
 
234
                  returnstring[keeper]= *scan;
 
235
                  returnstring[keeper+1]= '\0';
 
236
              }
 
237
              else { 
 
238
                  sprintf(temp,"\\%03o", (int) scan);
 
239
                  strcat(returnstring,temp);
 
240
              }
 
241
         }
 
242
    }
 
243
    strcpy(rs,returnstring);
 
244
}
 
245
static void enter_item(const char *name,int flags,int sig_number,dev_t dev, ino_t ino,SPACE_DSC *name_space)
 
246
{
 
247
    static FILE_DSC *last = NULL;
 
248
    FILE_DSC *new;
 
249
 
 
250
    if (!(new = malloc(sizeof(FILE_DSC)))) {
 
251
        perror("malloc");
 
252
        exit(1);
 
253
    }
 
254
    if (last_named && !strcmp(last_named->name,name) &&
 
255
      last_named->name_space == name_space) new->name = NULL;
 
256
    else if (!(new->name = strdup(name))) {
 
257
            perror("strdup");
 
258
            exit(1);
 
259
        }
 
260
    new->flags = flags;
 
261
    new->sig_num = sig_number;
 
262
    new->items = NULL;
 
263
    new->next = NULL;
 
264
    new->dev = dev;
 
265
    new->ino = ino;
 
266
    new->name_space = name_space;
 
267
    if (last) last->next = new;
 
268
    else files = new;
 
269
    last = new;
 
270
    new->named = last_named;
 
271
    if (new->name) last_named = new;
 
272
}
 
273
 void parse_args(const char *argv)
 
274
{
 
275
    SPACE_DSC *name_space;
 
276
    int flags,sig_number,no_files;
 
277
    SPACE_DSC *this_name_space;
 
278
    struct stat st;
 
279
 
 
280
    flags = 0;
 
281
    sig_number = SIGKILL;
 
282
    name_space = name_spaces;
 
283
    no_files = 1;
 
284
    flags |= FLAG_UID;
 
285
    no_files = 0;
 
286
    last_named = NULL;
 
287
    this_name_space = name_space;
 
288
    if (this_name_space == name_spaces) {
 
289
       if (stat(argv,&st) < 0) {
 
290
          perror(argv);
 
291
          exit(0);
 
292
       }
 
293
       if (!S_ISSOCK(st.st_mode) || (flags & FLAG_DEV))
 
294
          enter_item(argv,flags,sig_number,st.st_dev,st.st_ino,NULL);
 
295
    }
 
296
}
 
297
 
 
298
 
 
299
JNIEXPORT jstring JNICALL Java_gnu_io_CommPortIdentifier_native_1psmisc_1report_1owner (JNIEnv *env, jobject obj, jstring arg)
 
300
{
 
301
        char returnstring[256];
 
302
        const char *str = (*env)->GetStringUTFChars(env, arg, 0);
 
303
        show_user(str,returnstring);
 
304
        (*env)->ReleaseStringUTFChars(env, arg, str);
 
305
        return (*env)->NewStringUTF(env, returnstring);
 
306
}
 
307
#endif /* __linux__ */