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

« back to all changes in this revision

Viewing changes to CNI/fuserImp.c

  • Committer: Bazaar Package Importer
  • Author(s): Mario Joussen
  • Date: 2006-03-01 18:56:52 UTC
  • mfrom: (1.1.2 upstream) (2.1.1 etch)
  • Revision ID: james.westby@ubuntu.com-20060301185652-ri9941gi01goklvz
Tags: 2.1.7-2
Fixed stupid bug in clean target.
(closes: Bug#354859)

Show diffs side-by-side

added added

removed removed

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