(WRITTEN_BY): Rename from AUTHORS.
[platform/upstream/coreutils.git] / src / readlink.c
1 /* readlink -- display value of a symbolic link.
2    Copyright (C) 2002, 2003 Free Software Foundation, Inc.
3
4    This program is free software; you can redistribute it and/or modify
5    it under the terms of the GNU General Public License as published by
6    the Free Software Foundation; either version 2, or (at your option)
7    any later version.
8
9    This program is distributed in the hope that it will be useful,
10    but WITHOUT ANY WARRANTY; without even the implied warranty of
11    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12    GNU General Public License for more details.
13
14    You should have received a copy of the GNU General Public License
15    along with this program; if not, write to the Free Software Foundation,
16    Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
17
18 /* Written by Dmitry V. Levin */
19
20 #include <config.h>
21 #include <stdio.h>
22 #include <getopt.h>
23 #include <sys/types.h>
24
25 #include "system.h"
26 #include "canonicalize.h"
27 #include "error.h"
28 #include "xreadlink.h"
29 #include "long-options.h"
30 #include "quote.h"
31
32 /* The official name of this program (e.g., no `g' prefix).  */
33 #define PROGRAM_NAME "readlink"
34
35 #define WRITTEN_BY _("Written by Dmitry V. Levin.")
36
37 /* Name this program was run with.  */
38 char *program_name;
39
40   /* If nonzero, canonicalize file name. */
41 static int canonicalize;
42   /* If nonzero, do not output the trailing newline. */
43 static int no_newline;
44   /* If nonzero, report error messages. */
45 static int verbose;
46
47 static struct option const longopts[] =
48 {
49   {"canonicalize", no_argument, 0, 'f'},
50   {"no-newline", no_argument, 0, 'n'},
51   {"quiet", no_argument, 0, 'q'},
52   {"silent", no_argument, 0, 's'},
53   {"verbose", no_argument, 0, 'v'},
54   {GETOPT_HELP_OPTION_DECL},
55   {GETOPT_VERSION_OPTION_DECL},
56   {NULL, 0, NULL, 0}
57 };
58
59 void
60 usage (int status)
61 {
62   if (status != EXIT_SUCCESS)
63     fprintf (stderr, _("Try `%s --help' for more information.\n"),
64              program_name);
65   else
66     {
67       printf (_("Usage: %s [OPTION]... FILE\n"), program_name);
68       fputs (_("Display value of a symbolic link on standard output.\n\n"),
69              stdout);
70       fputs (_("\
71   -f, --canonicalize      canonicalize by following every symlink in every\n\
72                           component of the given path recursively\n\
73   -n, --no-newline        do not output the trailing newline\n\
74   -q, --quiet,\n\
75   -s, --silent            suppress most error messages\n\
76   -v, --verbose           report error messages\n\
77 "), stdout);
78       fputs (HELP_OPTION_DESCRIPTION, stdout);
79       fputs (VERSION_OPTION_DESCRIPTION, stdout);
80       printf (_("\nReport bugs to <%s>.\n"), PACKAGE_BUGREPORT);
81     }
82   exit (status);
83 }
84
85 int
86 main (int argc, char *const argv[])
87 {
88   const char *fname;
89   char *value;
90   int optc;
91
92   initialize_main (&argc, &argv);
93   program_name = argv[0];
94   setlocale (LC_ALL, "");
95   bindtextdomain (PACKAGE, LOCALEDIR);
96   textdomain (PACKAGE);
97
98   atexit (close_stdout);
99
100   while ((optc = getopt_long (argc, argv, "fnqsv", longopts, NULL)) != -1)
101     {
102       switch (optc)
103         {
104         case 0:
105           break;
106         case 'f':
107           canonicalize = 1;
108           break;
109         case 'n':
110           no_newline = 1;
111           break;
112         case 'q':
113         case 's':
114           verbose = 0;
115           break;
116         case 'v':
117           verbose = 1;
118           break;
119         case_GETOPT_HELP_CHAR;
120         case_GETOPT_VERSION_CHAR (PROGRAM_NAME, WRITTEN_BY);
121         default:
122           usage (EXIT_FAILURE);
123         }
124     }
125
126   if (optind >= argc)
127     {
128       error (0, 0, _("too few arguments"));
129       usage (EXIT_FAILURE);
130     }
131
132   fname = argv[optind++];
133
134   if (optind < argc)
135     {
136       error (0, 0, _("too many arguments"));
137       usage (EXIT_FAILURE);
138     }
139
140   value = (canonicalize ? canonicalize_file_name : xreadlink) (fname);
141   if (value)
142     {
143       printf ("%s%s", value, (no_newline ? "" : "\n"));
144       free (value);
145       return EXIT_SUCCESS;
146     }
147
148   if (verbose)
149     error (EXIT_FAILURE, errno, "%s", fname);
150
151   return EXIT_FAILURE;
152 }