xref: /onnv-gate/usr/src/lib/libcmd/common/readlink.c (revision 8462:6e341f5569ba)
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