Imported Upstream version 1.2.3
[nfs-utils.git] / support / nfs / xcommon.c
1 /*
2  * xcommon.c - various functions put together to avoid basic error checking.
3  *
4  * added fcntl locking by Kjetil T. (kjetilho@math.uio.no) - aeb, 950927
5  *
6  * 1999-02-22 Arkadiusz Miskiewicz <misiek@pld.ORG.PL>
7  * - added Native Language Support
8  *
9  * 2006-06-06 Amit Gud <agud@redhat.com>
10  * - Moved code snippets here from mount/sundries.c of util-linux
11  *   and merged code from support/nfs/xmalloc.c by Olaf Kirch <okir@monad.swb.de> here.
12  */
13
14 #include <unistd.h>
15 #include <ctype.h>
16 #include <stdio.h>
17 #include <stdlib.h>
18 #include <string.h>
19
20 #include "xcommon.h"
21 #include "nls.h"        /* _() */
22
23 void (*at_die)(void ) = NULL;
24
25 char *
26 xstrndup (const char *s, int n) {
27      char *t;
28
29      if (s == NULL)
30           die (EX_SOFTWARE, _("bug in xstrndup call"));
31
32      t = xmalloc(n+1);
33      strncpy(t,s,n);
34      t[n] = 0;
35
36      return t;
37 }
38
39 char *
40 xstrconcat2 (const char *s, const char *t) {
41      char *res;
42
43      if (!s) s = "";
44      if (!t) t = "";
45      res = xmalloc(strlen(s) + strlen(t) + 1);
46      strcpy(res, s);
47      strcat(res, t);
48      return res;
49 }
50
51 /* frees its first arg - typical use: s = xstrconcat3(s,t,u); */
52 char *
53 xstrconcat3 (const char *s, const char *t, const char *u) {
54      char *res;
55
56      if (!s) s = "";
57      if (!t) t = "";
58      if (!u) u = "";
59      res = xmalloc(strlen(s) + strlen(t) + strlen(u) + 1);
60      strcpy(res, s);
61      strcat(res, t);
62      strcat(res, u);
63      free((void *) s);
64      return res;
65 }
66
67 /* frees its first arg - typical use: s = xstrconcat4(s,t,u,v); */
68 char *
69 xstrconcat4 (const char *s, const char *t, const char *u, const char *v) {
70      char *res;
71
72      if (!s) s = "";
73      if (!t) t = "";
74      if (!u) u = "";
75      if (!v) v = "";
76      res = xmalloc(strlen(s) + strlen(t) + strlen(u) + strlen(v) + 1);
77      strcpy(res, s);
78      strcat(res, t);
79      strcat(res, u);
80      strcat(res, v);
81      free((void *) s);
82      return res;
83 }
84
85 /* Non-fatal error.  Print message and return.  */
86 /* (print the message in a single printf, in an attempt
87     to avoid mixing output of several threads) */
88 void
89 nfs_error (const char *fmt, ...) {
90      va_list args;
91      char *fmt2;
92
93      fmt2 = xstrconcat2 (fmt, "\n");
94      va_start (args, fmt);
95      vfprintf (stderr, fmt2, args);
96      va_end (args);
97      free (fmt2);
98 }
99
100 /* Make a canonical pathname from PATH.  Returns a freshly malloced string.
101    It is up the *caller* to ensure that the PATH is sensible.  i.e.
102    canonicalize ("/dev/fd0/.") returns "/dev/fd0" even though ``/dev/fd0/.''
103    is not a legal pathname for ``/dev/fd0''.  Anything we cannot parse
104    we return unmodified.   */
105 char *canonicalize (const char *path) {
106         char canonical[PATH_MAX+2];
107
108         if (path == NULL)
109                 return NULL;
110
111 #if 1
112         if (streq(path, "none") ||
113             streq(path, "proc") ||
114             streq(path, "devpts"))
115                 return xstrdup(path);
116 #endif
117         if (realpath (path, canonical))
118                 return xstrdup(canonical);
119
120         return xstrdup(path);
121 }
122
123 /* Fatal error.  Print message and exit.  */
124 void
125 die(int err, const char *fmt, ...) {
126         va_list args;
127
128         va_start(args, fmt);
129         vfprintf(stderr, fmt, args);
130         fprintf(stderr, "\n");
131         va_end(args);
132
133         if (at_die)
134                 (*at_die)();
135
136         exit(err);
137 }
138
139 static void
140 die_if_null(void *t) {
141         if (t == NULL)
142                 die(EX_SYSERR, _("not enough memory"));
143 }
144
145 void *
146 xmalloc (size_t size) {
147         void *t;
148
149         if (size == 0)
150                 return NULL;
151
152         t = malloc(size);
153         die_if_null(t);
154
155         return t;
156 }
157
158 void *
159 xrealloc (void *p, size_t size) {
160         void *t;
161
162         t = realloc(p, size);
163         die_if_null(t);
164
165         return t;
166 }
167
168 void
169 xfree(void *ptr)
170 {
171         free(ptr);
172 }
173
174 char *
175 xstrdup (const char *s) {
176         char *t;
177
178         if (s == NULL)
179                 return NULL;
180
181         t = strdup(s);
182         die_if_null(t);
183
184         return t;
185 }