nexmon – Blame information for rev 1
?pathlinks?
Rev | Author | Line No. | Line |
---|---|---|---|
1 | office | 1 | /* source: filan_main.c */ |
2 | /* Copyright Gerhard Rieger */ |
||
3 | /* Published under the GNU General Public License V.2, see file COPYING */ |
||
4 | |||
5 | const char copyright[] = "filan by Gerhard Rieger - see http://www.dest-unreach.org/socat/"; |
||
6 | |||
7 | #include "config.h" |
||
8 | #include "xioconfig.h" |
||
9 | #include "sysincludes.h" |
||
10 | |||
11 | #include "mytypes.h" |
||
12 | #include "compat.h" |
||
13 | #include "error.h" |
||
14 | #include "sycls.h" |
||
15 | #include "filan.h" |
||
16 | |||
17 | |||
18 | #define WITH_HELP 1 |
||
19 | |||
20 | static void filan_usage(FILE *fd); |
||
21 | |||
22 | |||
23 | int main(int argc, const char *argv[]) { |
||
24 | const char **arg1, *a; |
||
25 | const char *filename = NULL, *waittimetxt; |
||
26 | unsigned int m = 0; /* first FD (default) */ |
||
27 | unsigned int n = FD_SETSIZE; /* last excl. */ |
||
28 | unsigned int i; |
||
29 | int style = 0; |
||
30 | struct timespec waittime = { 0, 0 }; |
||
31 | FILE *fdout = stdout; |
||
32 | const char *outfname = NULL; |
||
33 | unsigned long fildes; |
||
34 | |||
35 | diag_set('p', strchr(argv[0], '/') ? strrchr(argv[0], '/')+1 : argv[0]); |
||
36 | |||
37 | arg1 = argv+1; --argc; |
||
38 | while (arg1[0] && (arg1[0][0] == '-')) { |
||
39 | switch (arg1[0][1]) { |
||
40 | #if WITH_HELP |
||
41 | case '?': case 'h': |
||
42 | filan_usage(stdout); exit(0); |
||
43 | #endif |
||
44 | #if LATER |
||
45 | case 'V': filan_version(stdout); exit(0); |
||
46 | #endif |
||
47 | case 'L': filan_followsymlinks = true; break; |
||
48 | case 'd': diag_set('d', NULL); break; |
||
49 | case 's': style = 1; break; |
||
50 | case 'r': filan_rawoutput = true; break; |
||
51 | case 'i': if (arg1[0][2]) { |
||
52 | a = *arg1+2; |
||
53 | } else { |
||
54 | ++arg1, --argc; |
||
55 | if ((a = *arg1) == NULL) { |
||
56 | Error("option -i requires an argument"); |
||
57 | filan_usage(stderr); exit(1); |
||
58 | } |
||
59 | } |
||
60 | m = strtoul(a, (char **)&a, 0); |
||
61 | n = m; |
||
62 | break; |
||
63 | case 'n': if (arg1[0][2]) { |
||
64 | a = *arg1+2; |
||
65 | } else { |
||
66 | ++arg1, --argc; |
||
67 | if ((a = *arg1) == NULL) { |
||
68 | Error("option -n requires an argument"); |
||
69 | filan_usage(stderr); exit(1); |
||
70 | } |
||
71 | } |
||
72 | n = strtoul(a, (char **)&a, 0); |
||
73 | break; |
||
74 | case 'f': if (arg1[0][2]) { |
||
75 | filename = *arg1+2; |
||
76 | } else { |
||
77 | ++arg1, --argc; |
||
78 | if ((filename = *arg1) == NULL) { |
||
79 | Error("option -f requires an argument"); |
||
80 | filan_usage(stderr); exit(1); |
||
81 | } |
||
82 | } |
||
83 | break; |
||
84 | case 'T': if (arg1[0][2]) { |
||
85 | waittimetxt = *arg1+2; |
||
86 | } else { |
||
87 | ++arg1, --argc; |
||
88 | if ((waittimetxt = *arg1) == NULL) { |
||
89 | Error("option -T requires an argument"); |
||
90 | filan_usage(stderr); exit(1); |
||
91 | } |
||
92 | } |
||
93 | { |
||
94 | double waittimedbl; |
||
95 | waittimedbl = strtod(waittimetxt, NULL); |
||
96 | waittime.tv_sec = waittimedbl; |
||
97 | waittime.tv_nsec = (waittimedbl-waittime.tv_sec) * 1000000000; |
||
98 | } |
||
99 | break; |
||
100 | case 'o': if (arg1[0][2]) { |
||
101 | outfname = *arg1+2; |
||
102 | } else { |
||
103 | ++arg1, --argc; |
||
104 | if ((outfname = *arg1) == NULL) { |
||
105 | Error("option -o requires an argument"); |
||
106 | filan_usage(stderr); exit(1); |
||
107 | } |
||
108 | } |
||
109 | break; |
||
110 | case '\0': break; |
||
111 | default: |
||
112 | diag_set_int('e', E_FATAL); |
||
113 | Error1("unknown option %s", arg1[0]); |
||
114 | #if WITH_HELP |
||
115 | filan_usage(stderr); |
||
116 | #endif |
||
117 | exit(1); |
||
118 | } |
||
119 | #if 0 |
||
120 | if (arg1[0][1] == '\0') |
||
121 | break; |
||
122 | #endif |
||
123 | ++arg1; --argc; |
||
124 | } |
||
125 | if (argc != 0) { |
||
126 | Error1("%d superfluous arguments", argc); |
||
127 | filan_usage(stderr); |
||
128 | exit(1); |
||
129 | } |
||
130 | if (outfname) { |
||
131 | /* special cases */ |
||
132 | if (!strcmp(outfname,"stdin")) { fdout=stdin; } |
||
133 | else if (!strcmp(outfname,"stdout")) { fdout=stdout; } |
||
134 | else if (!strcmp(outfname,"stderr")) { fdout=stderr; } |
||
135 | /* file descriptor */ |
||
136 | else if (*outfname == '+') { |
||
137 | a = outfname+1; |
||
138 | fildes = strtoul(a, (char **)&a, 0); |
||
139 | if ((fdout = fdopen(fildes, "w")) == NULL) { |
||
140 | Error2("can't fdopen file descriptor %lu: %s\n", fildes, strerror(errno)); |
||
141 | exit(1); |
||
142 | } |
||
143 | } else { |
||
144 | /* file name */ |
||
145 | if ((fdout = fopen(outfname, "w")) == NULL) { |
||
146 | Error2("can't fopen '%s': %s\n", |
||
147 | outfname, strerror(errno)); |
||
148 | exit(1); |
||
149 | } |
||
150 | } |
||
151 | } |
||
152 | |||
153 | Nanosleep(&waittime, NULL); |
||
154 | |||
155 | if (style == 0) { |
||
156 | /* this style gives detailled infos, but requires a file descriptor */ |
||
157 | if (filename) { |
||
158 | #if LATER /* this is just in case that S_ISSOCK does not work */ |
||
159 | struct stat buf; |
||
160 | int fd; |
||
161 | |||
162 | if (Stat(filename, &buf) < 0) { |
||
163 | Error3("stat(\"%s\", %p): %s", filename, &buf, strerror(errno)); |
||
164 | } |
||
165 | /* note: when S_ISSOCK was undefined, it always gives 0 */ |
||
166 | if (S_ISSOCK(buf.st_mode)) { |
||
167 | Error("cannot analyze UNIX domain socket"); |
||
168 | } |
||
169 | #endif |
||
170 | filan_file(filename, fdout); |
||
171 | } else { |
||
172 | if (m == n) { |
||
173 | ++n; |
||
174 | } |
||
175 | for (i = m; i < n; ++i) { |
||
176 | filan_fd(i, fdout); |
||
177 | } |
||
178 | } |
||
179 | } else { |
||
180 | /* this style gives only type and path / socket addresses, and works from |
||
181 | file descriptor or filename (with restrictions) */ |
||
182 | if (filename) { |
||
183 | /* filename: NULL means yet unknown; "" means no name at all */ |
||
184 | #if LATER |
||
185 | int fd; |
||
186 | if ((fd = |
||
187 | Open(filename, O_RDONLY|O_NOCTTY|O_NONBLOCK |
||
188 | #ifdef O_LARGEFILE |
||
189 | |O_LARGEFILE |
||
190 | #endif |
||
191 | , 0700)) |
||
192 | < 0) { |
||
193 | Debug2("open(\"%s\", O_RDONLY|O_NOCTTY|O_NONBLOCK|O_LARGEFILE, 0700): %s", |
||
194 | filename, strerror(errno)); |
||
195 | } |
||
196 | fdname(filename, fd, fdout, NULL); |
||
197 | #endif |
||
198 | fdname(filename, -1, fdout, NULL); |
||
199 | } else { |
||
200 | if (m == n) { |
||
201 | fdname("", m, fdout, NULL); |
||
202 | } else { |
||
203 | for (i = m; i < n; ++i) { |
||
204 | fdname("", i, fdout, "%5u "); |
||
205 | } |
||
206 | } |
||
207 | } |
||
208 | } |
||
209 | if (outfname && fdout != stdout && fdout != stderr) { |
||
210 | fclose(fdout); |
||
211 | } |
||
212 | return 0; |
||
213 | } |
||
214 | |||
215 | |||
216 | #if WITH_HELP |
||
217 | static void filan_usage(FILE *fd) { |
||
218 | fputs(copyright, fd); fputc('\n', fd); |
||
219 | fputs("Analyze file descriptors of the process\n", fd); |
||
220 | fputs("Usage:\n", fd); |
||
221 | fputs("filan [options]\n", fd); |
||
222 | fputs(" options:\n", fd); |
||
223 | #if LATER |
||
224 | fputs(" -V print version information to stdout, and exit\n", fd); |
||
225 | #endif |
||
226 | #if WITH_HELP |
||
227 | fputs(" -?|-h print this help text\n", fd); |
||
228 | fputs(" -d increase verbosity (use up to 4 times)\n", fd); |
||
229 | #endif |
||
230 | #if 0 |
||
231 | fputs(" -ly[facility] log to syslog, using facility (default is daemon)\n", fd); |
||
232 | fputs(" -lf<logfile> log to file\n", fd); |
||
233 | fputs(" -ls log to stderr (default if no other log)\n", fd); |
||
234 | #endif |
||
235 | fputs(" -i<fdnum> only analyze this fd\n", fd); |
||
236 | fprintf(fd, " -n<fdnum> analyze all fds from 0 up to fdnum-1 (default: %u)\n", FD_SETSIZE); |
||
237 | fputs(" -s simple output with just type and socket address or path\n", fd); |
||
238 | /* fputs(" -c alternate device visualization\n", fd);*/ |
||
239 | fputs(" -f<filename> analyze file system entry\n", fd); |
||
240 | fputs(" -T<seconds> wait before analyzing, useful to connect with debugger\n", fd); |
||
241 | fputs(" -r raw output for time stamps and rdev\n", fd); |
||
242 | fputs(" -L follow symbolic links instead of showing their properties\n", fd); |
||
243 | fputs(" -o<filename> output goes to filename, that can be:\n", fd); |
||
244 | fputs(" a regular file name, the output goes to that\n", fd); |
||
245 | fputs(" +<filedes> , output goes to the file descriptor (which must be open writable)\n", fd); |
||
246 | fputs(" the 3 special names stdin stdout and stderr\n", fd); |
||
247 | } |
||
248 | #endif /* WITH_HELP */ |