1*8462SApril.Chin@Sun.COM /***********************************************************************
2*8462SApril.Chin@Sun.COM * *
3*8462SApril.Chin@Sun.COM * This software is part of the ast package *
4*8462SApril.Chin@Sun.COM * Copyright (c) 1982-2007 AT&T Intellectual Property *
5*8462SApril.Chin@Sun.COM * and is licensed under the *
6*8462SApril.Chin@Sun.COM * Common Public License, Version 1.0 *
7*8462SApril.Chin@Sun.COM * by AT&T Intellectual Property *
8*8462SApril.Chin@Sun.COM * *
9*8462SApril.Chin@Sun.COM * A copy of the License is available at *
10*8462SApril.Chin@Sun.COM * http://www.opensource.org/licenses/cpl1.0.txt *
11*8462SApril.Chin@Sun.COM * (with md5 checksum 059e8cd6165cb4c31e351f2b69388fd9) *
12*8462SApril.Chin@Sun.COM * *
13*8462SApril.Chin@Sun.COM * Information and Software Systems Research *
14*8462SApril.Chin@Sun.COM * AT&T Research *
15*8462SApril.Chin@Sun.COM * Florham Park NJ *
16*8462SApril.Chin@Sun.COM * *
17*8462SApril.Chin@Sun.COM * Glenn Fowler <gsf@research.att.com> *
18*8462SApril.Chin@Sun.COM * David Korn <dgk@research.att.com> *
19*8462SApril.Chin@Sun.COM * *
20*8462SApril.Chin@Sun.COM ***********************************************************************/
21*8462SApril.Chin@Sun.COM #pragma prototyped
22*8462SApril.Chin@Sun.COM
23*8462SApril.Chin@Sun.COM static const char usage[] =
24*8462SApril.Chin@Sun.COM "[-?\n@(#)$Id: readlink (AT&T Research) 2008-06-08 $\n]"
25*8462SApril.Chin@Sun.COM USAGE_LICENSE
26*8462SApril.Chin@Sun.COM "[+NAME?readlink - read the contents of a symbolic link]"
27*8462SApril.Chin@Sun.COM "[+DESCRIPTION?\breadlink\b returns the contents of the symbolic "
28*8462SApril.Chin@Sun.COM "link referred to by the path argument. Unless the \b-f\b "
29*8462SApril.Chin@Sun.COM "option is specified an error will be returned when the path "
30*8462SApril.Chin@Sun.COM "is not a symbolic link.]"
31*8462SApril.Chin@Sun.COM "[f:canonicalize?The returned value will be an absolute pathname that names "
32*8462SApril.Chin@Sun.COM "the same file, whose resolution does not involve \".\", \"..\", or "
33*8462SApril.Chin@Sun.COM "symbolic links, otherwise only the exact (relative) value will be returned.]"
34*8462SApril.Chin@Sun.COM "[n:no-newline?Supress newline at the end.]"
35*8462SApril.Chin@Sun.COM "[v:verbose?Verbose - print errors.]"
36*8462SApril.Chin@Sun.COM "[+SEE ALSO?\bbasename\b(1),\bdirname\b(2),\breadlink\b(2),\breadpath\n(2)]"
37*8462SApril.Chin@Sun.COM ;
38*8462SApril.Chin@Sun.COM
39*8462SApril.Chin@Sun.COM #include <cmd.h>
40*8462SApril.Chin@Sun.COM
41*8462SApril.Chin@Sun.COM int
b_readlink(int argc,char ** argv,void * context)42*8462SApril.Chin@Sun.COM b_readlink(int argc, char** argv, void* context)
43*8462SApril.Chin@Sun.COM {
44*8462SApril.Chin@Sun.COM register char* s;
45*8462SApril.Chin@Sun.COM register int i;
46*8462SApril.Chin@Sun.COM register char* m;
47*8462SApril.Chin@Sun.COM register char* x;
48*8462SApril.Chin@Sun.COM int canonicalize = 0,
49*8462SApril.Chin@Sun.COM nonewline = 0,
50*8462SApril.Chin@Sun.COM verbose = 0;
51*8462SApril.Chin@Sun.COM char buf[PATH_MAX+2];
52*8462SApril.Chin@Sun.COM int len = 0;
53*8462SApril.Chin@Sun.COM char *filename,
54*8462SApril.Chin@Sun.COM *resolvedname = NULL;
55*8462SApril.Chin@Sun.COM
56*8462SApril.Chin@Sun.COM cmdinit(argc, argv, context, ERROR_CATALOG, 0);
57*8462SApril.Chin@Sun.COM for (;;)
58*8462SApril.Chin@Sun.COM {
59*8462SApril.Chin@Sun.COM switch (optget(argv, usage))
60*8462SApril.Chin@Sun.COM {
61*8462SApril.Chin@Sun.COM case 'f':
62*8462SApril.Chin@Sun.COM canonicalize = opt_info.num;
63*8462SApril.Chin@Sun.COM continue;
64*8462SApril.Chin@Sun.COM case 'n':
65*8462SApril.Chin@Sun.COM nonewline = opt_info.num;
66*8462SApril.Chin@Sun.COM continue;
67*8462SApril.Chin@Sun.COM case 'v':
68*8462SApril.Chin@Sun.COM verbose = opt_info.num;
69*8462SApril.Chin@Sun.COM continue;
70*8462SApril.Chin@Sun.COM case '?':
71*8462SApril.Chin@Sun.COM error(ERROR_usage(2), "%s", opt_info.arg);
72*8462SApril.Chin@Sun.COM continue;
73*8462SApril.Chin@Sun.COM case ':':
74*8462SApril.Chin@Sun.COM error(2, "%s", opt_info.arg);
75*8462SApril.Chin@Sun.COM continue;
76*8462SApril.Chin@Sun.COM }
77*8462SApril.Chin@Sun.COM break;
78*8462SApril.Chin@Sun.COM }
79*8462SApril.Chin@Sun.COM argv += opt_info.index;
80*8462SApril.Chin@Sun.COM argc -= opt_info.index;
81*8462SApril.Chin@Sun.COM if(error_info.errors || argc != 1)
82*8462SApril.Chin@Sun.COM error(ERROR_usage(2),"%s", optusage(NiL));
83*8462SApril.Chin@Sun.COM filename = argv[0];
84*8462SApril.Chin@Sun.COM
85*8462SApril.Chin@Sun.COM if (canonicalize)
86*8462SApril.Chin@Sun.COM {
87*8462SApril.Chin@Sun.COM len = resolvepath(filename, buf, sizeof(buf)-2);
88*8462SApril.Chin@Sun.COM }
89*8462SApril.Chin@Sun.COM else
90*8462SApril.Chin@Sun.COM {
91*8462SApril.Chin@Sun.COM len = readlink(filename, buf, sizeof(buf)-2);
92*8462SApril.Chin@Sun.COM }
93*8462SApril.Chin@Sun.COM
94*8462SApril.Chin@Sun.COM if (len != -1)
95*8462SApril.Chin@Sun.COM resolvedname = buf;
96*8462SApril.Chin@Sun.COM
97*8462SApril.Chin@Sun.COM if (!resolvedname)
98*8462SApril.Chin@Sun.COM {
99*8462SApril.Chin@Sun.COM if (verbose)
100*8462SApril.Chin@Sun.COM error(ERROR_system(1),"%s: readlink failed", filename);
101*8462SApril.Chin@Sun.COM else
102*8462SApril.Chin@Sun.COM return 1;
103*8462SApril.Chin@Sun.COM }
104*8462SApril.Chin@Sun.COM
105*8462SApril.Chin@Sun.COM if (!nonewline)
106*8462SApril.Chin@Sun.COM resolvedname[len++] = '\n';
107*8462SApril.Chin@Sun.COM
108*8462SApril.Chin@Sun.COM sfwrite(sfstdout, resolvedname, len);
109*8462SApril.Chin@Sun.COM
110*8462SApril.Chin@Sun.COM return 0;
111*8462SApril.Chin@Sun.COM }
112