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