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
23static const char usage[] =
24"[-?\n@(#)$Id: readlink (AT&T Research) 2008-06-08 $\n]"
25USAGE_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
41int
42b_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