No specific user configuration
[platform/upstream/bash.git] / examples / loadables / realpath.c
1 /*
2  * realpath -- canonicalize pathnames, resolving symlinks
3  *
4  * usage: realpath [-csv] pathname [pathname...]
5  *
6  * options:     -c      check whether or not each resolved path exists
7  *              -s      no output, exit status determines whether path is valid
8  *              -v      produce verbose output
9  *
10  *
11  * exit status: 0       if all pathnames resolved
12  *              1       if any of the pathname arguments could not be resolved
13  *
14  *
15  * Bash loadable builtin version
16  *
17  * Chet Ramey
18  * chet@po.cwru.edu
19  */
20
21 /*
22    Copyright (C) 1999-2009 Free Software Foundation, Inc.
23
24    This file is part of GNU Bash.
25    Bash is free software: you can redistribute it and/or modify
26    it under the terms of the GNU General Public License as published by
27    the Free Software Foundation, either version 3 of the License, or
28    (at your option) any later version.
29
30    Bash is distributed in the hope that it will be useful,
31    but WITHOUT ANY WARRANTY; without even the implied warranty of
32    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
33    GNU General Public License for more details.
34
35    You should have received a copy of the GNU General Public License
36    along with Bash.  If not, see <http://www.gnu.org/licenses/>.
37 */
38
39 #include "config.h"
40
41 #include <sys/types.h>
42 #include <sys/stat.h>
43
44 #include <stdio.h>
45 #ifdef HAVE_UNISTD_H
46 #  include <unistd.h>
47 #endif
48 #include "bashansi.h"
49 #include <maxpath.h>
50 #include <errno.h>
51
52 #include "builtins.h"
53 #include "shell.h"
54 #include "bashgetopt.h"
55 #include "common.h"
56
57 #ifndef errno
58 extern int      errno;
59 #endif
60
61 extern char     *sh_realpath();
62
63 realpath_builtin(list)
64 WORD_LIST       *list;
65 {
66         int     opt, cflag, vflag, sflag, es;
67         char    *r, realbuf[PATH_MAX], *p;
68         struct stat sb;
69
70         if (list == 0) {
71                 builtin_usage();
72                 return (EX_USAGE);
73         }
74
75         vflag = cflag = sflag = 0;
76         reset_internal_getopt();
77         while ((opt = internal_getopt (list, "csv")) != -1) {
78                 switch (opt) {
79                 case 'c':
80                         cflag = 1;
81                         break;
82                 case 's':
83                         sflag = 1;
84                         break;
85                 case 'v':
86                         vflag = 1;
87                         break;
88                 default:
89                         builtin_usage();
90                 }
91         }
92
93         list = loptend;
94
95         if (list == 0)
96                 builtin_usage();
97
98         for (es = EXECUTION_SUCCESS; list; list = list->next) {
99                 p = list->word->word;
100                 r = sh_realpath(p, realbuf);
101                 if (r == 0) {
102                         es = EXECUTION_FAILURE;
103                         if (sflag == 0)
104                                 builtin_error("%s: cannot resolve: %s", p, strerror(errno));
105                         continue;
106                 }
107                 if (cflag && (stat(realbuf, &sb) < 0)) {
108                         es = EXECUTION_FAILURE;
109                         if (sflag == 0)
110                                 builtin_error("%s: %s", p, strerror(errno));
111                         continue;
112                 }
113                 if (sflag == 0) {
114                         if (vflag)
115                                 printf ("%s -> ", p);
116                         printf("%s\n", realbuf);
117                 }
118         }
119         return es;
120 }
121
122 char *realpath_doc[] = {
123         "Display pathname in canonical form.",
124         "",
125         "Display the canonicalized version of each PATHNAME argument, resolving",
126         "symbolic links.  The -c option checks whether or not each resolved name",
127         "exists.  The -s option produces no output; the exit status determines the",
128         "valididty of each PATHNAME.  The -v option produces verbose output.  The",
129         "exit status is 0 if each PATHNAME was resolved; non-zero otherwise.",
130         (char *)NULL
131 };
132
133 struct builtin realpath_struct = {
134         "realpath",             /* builtin name */
135         realpath_builtin,       /* function implementing the builtin */
136         BUILTIN_ENABLED,        /* initial flags for builtin */
137         realpath_doc,           /* array of long documentation strings */
138         "realpath [-csv] pathname [pathname...]",       /* usage synopsis */
139         0                       /* reserved for internal use */
140 };