Sadly, we can't change symlink mtimes
[metastore.git] / utils.c
blob7b8e784d971c75cffe7cffd7f914a0ab89f96395
1 /*
2 * Main functions of the program.
4 * Copyright (C) 2007 David Härdeman <david@hardeman.nu>
6 * This program is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License as published by the
8 * Free Software Foundation version 2 of the License.
9 *
10 * This program is distributed in the hope that it will be useful, but
11 * WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * General Public License for more details.
15 * You should have received a copy of the GNU General Public License along
16 * with this program; if not, write to the Free Software Foundation, Inc.,
17 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
21 #include <stdlib.h>
22 #include <stdio.h>
23 #include <ctype.h>
24 #include <string.h>
25 #include <stdint.h>
26 #include <stdarg.h>
27 #include <unistd.h>
28 #include <errno.h>
30 #include "utils.h"
32 /* Controls the verbosity level for msg() */
33 static int verbosity = 0;
35 /* Adjusts the verbosity level for msg() */
36 void
37 adjust_verbosity(int adj)
39 verbosity += adj;
43 * Prints messages to console according to the current verbosity
44 * - see utils.h for level defines
46 int
47 msg(int level, const char *fmt, ...)
49 int ret;
50 va_list ap;
52 if (level > verbosity)
53 return 0;
55 va_start(ap, fmt);
57 if (level < MSG_QUIET)
58 ret = vfprintf(stderr, fmt, ap);
59 else
60 ret = vfprintf(stdout, fmt, ap);
62 va_end(ap);
63 return ret;
66 /* Malloc which either succeeds or exits */
67 void *
68 xmalloc(size_t size)
70 void *result = malloc(size);
71 if (!result) {
72 msg(MSG_CRITICAL, "Failed to malloc %zi bytes\n", size);
73 exit(EXIT_FAILURE);
75 return result;
78 /* Ditto for strdup */
79 char *
80 xstrdup(const char *s)
82 char *result = strdup(s);
83 if (!result) {
84 msg(MSG_CRITICAL, "Failed to strdup %zi bytes\n", strlen(s));
85 exit(EXIT_FAILURE);
87 return result;
90 /* Human-readable printout of binary data */
91 void
92 binary_print(const char *s, ssize_t len)
94 ssize_t i;
96 for (i = 0; i < len; i++) {
97 if (isprint(s[i]))
98 msg(MSG_DEBUG, "%c", s[i]);
99 else
100 msg(MSG_DEBUG, "0x%02X", (int)s[i]);
104 /* Writes data to a file or exits on failure */
105 void
106 xfwrite(const void *ptr, size_t size, FILE *stream)
108 if (fwrite(ptr, size, 1, stream) != 1) {
109 msg(MSG_CRITICAL, "Failed to write to file: %s\n",
110 strerror(errno));
111 exit(EXIT_FAILURE);
115 /* Writes an int to a file, using len bytes, in bigendian order */
116 void
117 write_int(uint64_t value, size_t len, FILE *to)
119 char buf[len];
120 int i;
122 for (i = 0; i < len; i++)
123 buf[i] = ((value >> (8 * i)) & 0xff);
124 xfwrite(buf, len, to);
127 /* Writes a binary string to a file */
128 void
129 write_binary_string(const char *string, size_t len, FILE *to)
131 xfwrite(string, len, to);
134 /* Writes a normal C string to a file */
135 void
136 write_string(const char *string, FILE *to)
138 xfwrite(string, strlen(string) + 1, to);
141 /* Reads an int from a file, using len bytes, in bigendian order */
142 uint64_t
143 read_int(char **from, size_t len, const char *max)
145 uint64_t result = 0;
146 int i;
148 if (*from + len > max) {
149 msg(MSG_CRITICAL,
150 "Attempt to read beyond end of file, corrupt file?\n");
151 exit(EXIT_FAILURE);
154 for (i = 0; i < len; i++)
155 result += (((*from)[i] & 0xff) << (8 * i));
156 *from += len;
157 return result;
160 /* Reads a binary string from a file */
161 char *
162 read_binary_string(char **from, size_t len, const char *max)
164 char *result;
166 if (*from + len > max) {
167 msg(MSG_CRITICAL,
168 "Attempt to read beyond end of file, corrupt file?\n");
169 exit(EXIT_FAILURE);
172 result = xmalloc(len);
173 strncpy(result, *from, len);
174 *from += len;
175 return result;
178 /* Reads a normal C string from a file */
179 char *
180 read_string(char **from, const char *max)
182 return read_binary_string(from, strlen(*from) + 1, max);