1 /* $MirOS: src/usr.bin/readlink/readlink.c,v 1.6 2008/11/08 23:04:55 tg Exp $ */
2 
3 /*-
4  * Copyright (c) 2005
5  *	Thorsten "mirabilos" Glaser <tg@MirBSD.org>
6  *
7  * Licensee is hereby permitted to deal in this work without restric-
8  * tion, including unlimited rights to use, publicly perform, modify,
9  * merge, distribute, sell, give away or sublicence, provided all co-
10  * pyright notices above, these terms and the disclaimer are retained
11  * in all redistributions or reproduced in accompanying documentation
12  * or other materials provided with binary redistributions.
13  *
14  * Licensor offers the work "AS IS" and WITHOUT WARRANTY of any kind,
15  * express, or implied, to the maximum extent permitted by applicable
16  * law, without malicious intent or gross negligence; in no event may
17  * licensor, an author or contributor be held liable for any indirect
18  * or other damage, or direct damage except proven a consequence of a
19  * direct error of said person and intended use of this work, loss or
20  * other issues arising in any way out of its use, even if advised of
21  * the possibility of such damage or existence of a nontrivial bug.
22  */
23 
24 #include <err.h>
25 #include <errno.h>
26 #include <getopt.h>
27 #include <limits.h>
28 #include <stdio.h>
29 #include <stdlib.h>
30 #include <string.h>
31 #include <unistd.h>
32 
33 __RCSID("$MirOS: src/usr.bin/readlink/readlink.c,v 1.6 2008/11/08 23:04:55 tg Exp $");
34 
35 int main(int, char **);
36 __dead void usage(void);
37 
38 int
main(int argc,char * argv[])39 main(int argc, char *argv[])
40 {
41 	char buf[PATH_MAX];
42 	int ch, nflag = 0, fflag = 0;
43 	size_t i;
44 
45 	while ((ch = getopt(argc, argv, "fn")) != -1)
46 		switch (ch) {
47 		case 'f':
48 			fflag = 1;
49 			break;
50 		case 'n':
51 			nflag = 1;
52 			break;
53 		default:
54 			usage();
55 		}
56 	argc -= optind;
57 	argv += optind;
58 
59 	if (argc != 1)
60 		usage();
61 
62 	if ((i = strlen(argv[0])) > (PATH_MAX - 1))
63 		errx(1, "filename too long, max %d", PATH_MAX - 1);
64 
65 	if (fflag) {
66 		if (realpath(argv[0], buf) == NULL)
67 			err(1, "realpath");
68 	} else {
69 		i = readlink(argv[0], buf, sizeof (buf) - 1);
70 		if ((ssize_t)i < 0)
71 			err(1, "readlink");
72 		buf[i] = '\0';
73 	}
74 
75 	printf("%s%s", buf, nflag ? "" : "\n");
76 	return (0);
77 }
78 
79 __dead void
usage(void)80 usage(void)
81 {
82 	extern const char *__progname;
83 
84 	fprintf(stderr, "usage: %s [-fn] pathname\n", __progname);
85 	exit(1);
86 }
87