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