options.c revision e188705c4f1c5c8e377c2438114a99acaeaf8a3a
1#include <string.h>
2#include <stdlib.h>
3#include <unistd.h>
4#include <errno.h>
5#include <limits.h>
6
7#include "ltrace.h"
8#include "options.h"
9#include "defs.h"
10
11FILE * output;
12int opt_a = DEFAULT_ACOLUMN;	/* default alignment column for results */
13int opt_d = 0;			/* debug */
14int opt_i = 0;			/* instruction pointer */
15int opt_s = DEFAULT_STRLEN;	/* default maximum # of bytes printed in strings */
16int opt_S = 0;			/* display syscalls */
17int opt_L = 1;			/* display library calls */
18int opt_f = 0;			/* trace child processes as they are created */
19char * opt_u = NULL;		/* username to run command as */
20
21/* List of pids given to option -p: */
22struct opt_p_t * opt_p = NULL;	/* attach to process with a given pid */
23
24static void usage(void)
25{
26	fprintf(stderr, "Usage: ltrace [-dfiLS] [-a column] [-s strlen] [-o filename]\n"
27			"              [-u username] [-p pid] ... [command [arg ...]]\n\n");
28}
29
30static char * search_for_command(char * filename)
31{
32	static char pathname[PATH_MAX];
33	char *path;
34	int m, n;
35
36	if (strchr(filename, '/')) {
37		return filename;
38	}
39	for (path = getenv("PATH"); path && *path; path += m) {
40		if (strchr(path, ':')) {
41			n = strchr(path, ':') - path;
42			m = n + 1;
43		} else {
44			m = n = strlen(path);
45		}
46		strncpy(pathname, path, n);
47		if (n && pathname[n - 1] != '/') {
48			pathname[n++] = '/';
49		}
50		strcpy(pathname + n, filename);
51		if (!access(pathname, X_OK)) {
52			return pathname;
53		}
54	}
55	return filename;
56}
57
58char ** process_options(int argc, char **argv)
59{
60	char *nextchar = NULL;
61
62	output = stderr;
63
64	while(1) {
65		if (!nextchar || !(*nextchar)) {
66			if (!argv[1] || argv[1][0] != '-' || !argv[1][1]) {
67				break;
68			}
69			nextchar = &argv[1][1];
70			argc--; argv++;
71		}
72		switch (*nextchar++) {
73			case 'a':	opt_a = atoi(argv[1]);
74					argc--; argv++;
75					break;
76			case 'd':	opt_d++;
77					break;
78			case 'o':	output = fopen(argv[1], "w");
79					if (!output) {
80						fprintf(stderr, "Can't open %s for output: %s\n", argv[1], strerror(errno));
81						exit(1);
82					}
83					argc--; argv++;
84					break;
85			case 'i':	opt_i++;
86					break;
87			case 's':	opt_s = atoi(argv[1]);
88					argc--; argv++;
89					break;
90			case 'L':	opt_L = 0;
91					break;
92			case 'S':	opt_S = 1;
93					break;
94			case 'f':	opt_f = 1;
95					break;
96			case 'u':	opt_u = argv[1];
97					argc--; argv++;
98					break;
99			case 'p':
100				{
101					struct opt_p_t * tmp = malloc(sizeof(struct opt_p_t));
102					if (!tmp) {
103						perror("malloc");
104						exit(1);
105					}
106					tmp->pid = atoi(argv[1]);
107					argc--; argv++;
108					break;
109				}
110			default:	fprintf(stderr, "Unknown option '%c'\n", *(nextchar-1));
111					usage();
112					exit(1);
113		}
114	}
115
116	if (argc<2) {
117		usage();
118		exit(1);
119	}
120	command = search_for_command(argv[1]);
121	return &argv[1];
122}
123