summaryrefslogtreecommitdiff
path: root/error.h
blob: a41680512d7c330dbb2daecb84a4344527da015a (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
/* SPDX-License-Identifier: GPL-2.0 */

/** \file error.h List of error codes and messages. */

/** Codes and messages. */
#define PARA_ERRORS \
	PARA_ERROR(SUCCESS, "success"), \
	PARA_ERROR(AACDEC_INIT, "failed to init aac decoder"), \
	PARA_ERROR(AAC_DECODE, "aac decode error"), \
	PARA_ERROR(ACL_PERM, "access denied by acl"), \
	PARA_ERROR(ADDRESS_LOOKUP, "can not resolve requested address"),\
	PARA_ERROR(AFH_RECV_BAD_FILENAME, "no file name given"), \
	PARA_ERROR(AFS_SHORT_READ, "short read from afs socket"), \
	PARA_ERROR(AFS_SIGNAL, "afs caught deadly signal"), \
	PARA_ERROR(AFS_SOCKET, "afs socket not writable"), \
	PARA_ERROR(ALSA, "alsa error"), \
	PARA_ERROR(ALSA_MIX_GET_VAL, "could not read control element state"), \
	PARA_ERROR(ALSA_MIX_OPEN, "could not open mixer"), \
	PARA_ERROR(ALSA_MIX_RANGE, "value control element out of range"), \
	PARA_ERROR(ALSA_MIX_SET_VAL, "could not set control element state"), \
	PARA_ERROR(AMP_ZERO_AMP, "no amplification necessary"), \
	PARA_ERROR(AO_APPEND_OPTION, "ao append option: memory allocation failure"), \
	PARA_ERROR(AO_BAD_DRIVER, "ao: invalid driver"), \
	PARA_ERROR(AO_BAD_OPTION, "ao option is not of type key:value"), \
	PARA_ERROR(AO_DEFAULT_DRIVER, "ao: no usable output device"), \
	PARA_ERROR(AO_FILE_NOT_SUPP, "ao: file io drivers not supported"), \
	PARA_ERROR(AO_OPEN_LIVE, "ao: could not open audio device"), \
	PARA_ERROR(AO_PLAY, "ao_play() failed"), \
	PARA_ERROR(AO_PTHREAD, "pthread error"), \
	PARA_ERROR(ATOI_JUNK_AT_END, "further characters after number"), \
	PARA_ERROR(ATOI_NO_DIGITS, "no digits found in string"), \
	PARA_ERROR(ATOI_OVERFLOW, "value too large"), \
	PARA_ERROR(ATT_TABLE_FULL, "no more space left in attribute table"), \
	PARA_ERROR(AUDIOD_DISPATCH, "audiod dispatch error"), \
	PARA_ERROR(AUDIOD_OFF, "audiod switched off"), \
	PARA_ERROR(AUDIOD_SIGNAL, "caught deadly signal"), \
	PARA_ERROR(AUDIOD_TERM, "terminating on user request"), \
	PARA_ERROR(AUDIO_FORMAT, "audio format not recognized"), \
	PARA_ERROR(AUTH_REQUEST, "did not receive auth request"), \
	PARA_ERROR(BAD_AFSI, "invalid afs info"), \
	PARA_ERROR(BAD_ASF_FILE_PROPS, "invalid ASF file properties"), \
	PARA_ERROR(BAD_AUTH, "authentication failure"), \
	PARA_ERROR(BAD_BAND, "invalid or unexpected band designator"), \
	PARA_ERROR(BAD_CHANNEL_COUNT, "channel count not supported"), \
	PARA_ERROR(BAD_CHANNEL, "invalid channel"), \
	PARA_ERROR(BAD_CT, "invalid chunk table or bad FEC configuration"), \
	PARA_ERROR(BAD_FEATURE, "invalid feature request"), \
	PARA_ERROR(BAD_FEC_HEADER, "invalid fec header"), \
	PARA_ERROR(BAD_MOP, "invalid mood or playlist"), \
	PARA_ERROR(BAD_PATH, "invalid path"), \
	PARA_ERROR(BAD_SAMPLE_FORMAT, "sample format not supported"), \
	PARA_ERROR(BAD_SAMPLERATE, "sample rate not supported"), \
	PARA_ERROR(BAD_SLICE_NUM, "invalid slice number"), \
	PARA_ERROR(BAD_SLICE_SIZE, "slice size zero or too large"), \
	PARA_ERROR(BAD_TABLE_NAME, "invalid table"), \
	PARA_ERROR(BAD_USER, "auth request for invalid user"), \
	PARA_ERROR(BASE64, "failed to base64-decode ssh public key"), \
	PARA_ERROR(BIGNUM, "bignum error"), \
	PARA_ERROR(BLINDING, "failed to activate key blinding"), \
	PARA_ERROR(BLOB_SYNTAX, "blob syntax error"), \
	PARA_ERROR(BTR_NAVAIL, "btr node: value currently unavailable"), \
	PARA_ERROR(BTR_NO_CHILD, "btr node has no children"), \
	PARA_ERROR(CHILD_CONTEXT, "now running in child context"), \
	PARA_ERROR(CHMOD, "failed to set socket mode"), \
	PARA_ERROR(CLIENT_SYNTAX, "syntax error"), \
	PARA_ERROR(CLIENT_WRITE, "client write error"), \
	PARA_ERROR(COMMAND_SYNTAX, "syntax error in command"), \
	PARA_ERROR(CREATE_OPUS_DECODER, "could not create opus decoder"), \
	PARA_ERROR(DECRYPT, "decrypt error"), \
	PARA_ERROR(DUMMY_ROW, "attempted to access blob dummy object"), \
	PARA_ERROR(DUP_PIPE, "exec error: can not create pipe"), \
	PARA_ERROR(EMPTY, "file is empty"), \
	PARA_ERROR(ENCRYPT, "encrypt error"), \
	PARA_ERROR(EOF, "end of file"), \
	PARA_ERROR(EOP, "end of playlist"), \
	PARA_ERROR(FEC_BAD_IDX, "invalid index vector"), \
	PARA_ERROR(FECDEC_OVERRUN, "fecdec output buffer overrun"), \
	PARA_ERROR(FEC_PARMS, "invalid fec parameters"), \
	PARA_ERROR(FEC_PIVOT, "pivot column not found"), \
	PARA_ERROR(FEC_SINGULAR, "unexpected singular matrix"), \
	PARA_ERROR(FFT_BAD_PARAMS, "invalid params for fft"), \
	PARA_ERROR(FGETS, "fgets error"), \
	PARA_ERROR(FLAC_AFH_DECODER_ALLOC, "could not allocate stream decoder"), \
	PARA_ERROR(FLAC_AFH_DECODER_INIT, "could not init stream decoder"), \
	PARA_ERROR(FLAC_CHAIN_ALLOC, "could not create metadata chain"), \
	PARA_ERROR(FLAC_CHAIN_READ, "could not read meta chain"), \
	PARA_ERROR(FLACDEC_DECODER_ALLOC, "could not allocate stream decoder"), \
	PARA_ERROR(FLACDEC_DECODER_INIT, "could not init stream decoder"), \
	PARA_ERROR(FLAC_DECODE_POS, "could not get decode position"), \
	PARA_ERROR(FLAC_ITER_ALLOC, "could not allocate meta iterator"), \
	PARA_ERROR(FLAC_REPLACE_COMMENT, "could not replace vorbis comment"), \
	PARA_ERROR(FLAC_SKIP_META, "could not skip metadata"), \
	PARA_ERROR(FLAC_STREAMINFO, "could not read stream info meta block"), \
	PARA_ERROR(FLAC_VARBLOCK, "variable blocksize not supported"), \
	PARA_ERROR(FLAC_WRITE_CHAIN, "failed to write metadata chain"), \
	PARA_ERROR(FNMATCH, "fnmatch error"), \
	PARA_ERROR(FRAME, "invalid mp3 frame"), \
	PARA_ERROR(FRAME_LENGTH, "invalid frame length"), \
	PARA_ERROR(GC_SYNTAX, "grab client syntax error"), \
	PARA_ERROR(GC_WRITE, "grab client write error"), \
	PARA_ERROR(GUI_SIGCHLD, "received SIGCHLD"), \
	PARA_ERROR(HASH_MISMATCH, "hash mismatch, consider re-add"), \
	PARA_ERROR(HEADER_BITRATE, "invalid header bitrate"), \
	PARA_ERROR(HEADER_FREQ, "invalid header frequency"), \
	PARA_ERROR(HTTP_RECV_OVERRUN, "http_recv: output buffer overrun"), \
	PARA_ERROR(I9E_SETUPTERM, "failed to set up terminal"), \
	PARA_ERROR(I9E_TERM_RQ, "received termination request"), \
	PARA_ERROR(ID3_ATTACH, "could not attach id3 frame"), \
	PARA_ERROR(ID3_DETACH, "could not detach id3 frame"), \
	PARA_ERROR(ID3_SETENCODING, "could not set id3 text encoding field"), \
	PARA_ERROR(ID3_SETSTRING, "could not set id3 string field"), \
	PARA_ERROR(INCOHERENT_BLOCK_LEN, "incoherent block length"), \
	PARA_ERROR(KEY_MARKER, "invalid/missing key header or footer"), \
	PARA_ERROR(KEY_PERM, "unprotected private key"), \
	PARA_ERROR(LOCALTIME, "localtime() failed"), \
	PARA_ERROR(LOCK, "lock error"), \
	PARA_ERROR(MAD_FRAME_DECODE, "mad frame decode error"), \
	PARA_ERROR(MAKESOCK, "makesock error"), \
	PARA_ERROR(MAX_CLIENTS, "maximal number of clients exceeded"), \
	PARA_ERROR(MISSING_COLON, "syntax error: missing colon"), \
	PARA_ERROR(MOOD_PARSE, "mood parse error"), \
	PARA_ERROR(MP3DEC_CORRUPT, "too many corrupt frames"), \
	PARA_ERROR(MP3_INFO, "could not read mp3 info"), \
	PARA_ERROR(MP4_READ, "mp4: read error or unexpected end of file"), \
	PARA_ERROR(MP4_CORRUPT, "invalid/corrupt mp4 file"), \
	PARA_ERROR(MP4_BAD_SAMPLE, "mp4: invalid sample number"), \
	PARA_ERROR(MP4_BAD_SAMPLERATE, "mp4: invalid sample rate"), \
	PARA_ERROR(MP4_BAD_SAMPLE_COUNT, "mp4: invalid number of samples"), \
	PARA_ERROR(MP4_TRACK, "mp4: no audio track"), \
	PARA_ERROR(MP4_MISSING_ATOM, "mp4: essential atom not found"), \
	PARA_ERROR(MPI_SCAN, "could not scan multi-precision integer"), \
	PARA_ERROR(NAME_TOO_LONG, "name too long for struct sockaddr_un"), \
	PARA_ERROR(NO_AFHI, "audio format handler info required"), \
	PARA_ERROR(NO_ATTRIBUTES, "no attributes defined yet"), \
	PARA_ERROR(NO_AUDIO_FILE, "no audio file"), \
	PARA_ERROR(NOFD, "did not receive open fd from afs"), \
	PARA_ERROR(NO_MATCH, "no matches"), \
	PARA_ERROR(NO_MORE_SLOTS, "no more empty slots"), \
	PARA_ERROR(NOT_PLAYING, "not playing"), \
	PARA_ERROR(NO_VALID_FILES, "no valid file found in playlist"), \
	PARA_ERROR(NO_WMA, "asf/wma format not recognized"), \
	PARA_ERROR(OGGDEC_BADHEADER, "invalid vorbis bitstream header"), \
	PARA_ERROR(OGGDEC_BADLINK, "invalid stream section or requested link corrupt"), \
	PARA_ERROR(OGGDEC_FAULT, "bug or heap/stack corruption"), \
	PARA_ERROR(OGGDEC_NOTVORBIS, "bitstream is not vorbis data"), \
	PARA_ERROR(OGGDEC_READ, "read from media returned an error"), \
	PARA_ERROR(OGGDEC_VERSION, "vorbis version mismatch"), \
	PARA_ERROR(OGG_EMPTY, "no ogg pages found"), \
	PARA_ERROR(OGG_PACKET_IN, "ogg_stream_packetin() failed"), \
	PARA_ERROR(OGG_SYNC, "internal ogg storage overflow"), \
	PARA_ERROR(OPENSSH_PARSE, "could not parse openssh private key"), \
	PARA_ERROR(OPENSSL, "openssl error"), \
	PARA_ERROR(OPUS_COMMENT, "invalid or corrupted opus comment"), \
	PARA_ERROR(OPUS_DECODE, "opus decode error"), \
	PARA_ERROR(OPUS_HEADER, "invalid opus header"), \
	PARA_ERROR(OPUS_SET_GAIN, "opus: could not set gain"), \
	PARA_ERROR(PATH_FOUND, ""), /* not really an error */ \
	PARA_ERROR(PLAYLIST_EMPTY, "attempted to load empty playlist"), \
	PARA_ERROR(PREBUFFER_SUCCESS, "prebuffering complete"), \
	PARA_ERROR(QUEUE, "packet queue overrun"), \
	PARA_ERROR(READ_PATTERN, "did not read expected pattern"), \
	PARA_ERROR(REGEX, "regular expression error"), \
	PARA_ERROR(RSA, "RSA error"), \
	PARA_ERROR(RSA_DECODE, "RSA decoding error"), \
	PARA_ERROR(SB_PACKET_SIZE, "invalid sideband packet size or protocol error"), \
	PARA_ERROR(SCM_CREDENTIALS, "did not receive SCM credentials"), \
	PARA_ERROR(SENDER_CMD, "command not supported by this sender"), \
	PARA_ERROR(SERVER_CMD_FAILURE, "command failed"), \
	PARA_ERROR(SERVER_CMD_SUCCESS, "command terminated successfully"), \
	PARA_ERROR(SERVER_CRASH, "para_server crashed -- can not live without it"), \
	PARA_ERROR(SEXP_BUILD, "could not build S-expression"), \
	PARA_ERROR(SEXP_DECRYPT, "could not decrypt S-expression"), \
	PARA_ERROR(SEXP_ENCRYPT, "could not encrypt S-expression"), \
	PARA_ERROR(SEXP_FIND, "could not find sublist in S-expression"), \
	PARA_ERROR(SHORT_WRITE, "unexpected short write"), \
	PARA_ERROR(SPX_COMMENT, "invalid speex comment"), \
	PARA_ERROR(SPX_CTL_BAD_RQ, "speex_decoder_ctl: invalid request"), \
	PARA_ERROR(SPX_CTL_INVAL, "speex_decoder_ctl: invalid argument"), \
	PARA_ERROR(SPX_DECODE_OVERFLOW, "speex decoding overflow"), \
	PARA_ERROR(SPX_DECODER_INIT, "speex decoder initialization failed"), \
	PARA_ERROR(SPX_DECODE, "speex decoding error"), \
	PARA_ERROR(SPX_EOS, "speex: end of stream"), \
	PARA_ERROR(SPX_HEADER, "can not read speex header"), \
	PARA_ERROR(SPX_HEADER_MODE, "invalid speex mode in header"), \
	PARA_ERROR(SPX_VERSION, "incompatible speex bit stream version"), \
	PARA_ERROR(SSH_KEY_HEADER, "ssh key header not found"), \
	PARA_ERROR(SSH_PARSE, "could not parse ssh public key"), \
	PARA_ERROR(STATUS_TIMEOUT, "status item timeout"), \
	PARA_ERROR(STREAM_PACKETIN, "ogg stream packet-in error"), \
	PARA_ERROR(STREAM_PACKETOUT, "ogg stream packet-out error"), \
	PARA_ERROR(STREAM_PAGEIN, "ogg stream page-in error"), \
	PARA_ERROR(STREAM_PAGEOUT, "ogg stream page-out error"), \
	PARA_ERROR(STRFTIME, "strftime() failed"), \
	PARA_ERROR(SUBCMD_RUNNING, ""), /* no error */ \
	PARA_ERROR(SYNC_COMPLETE, "all buddies in sync"), \
	PARA_ERROR(SYNC_LISTEN_FD, "no fd to listen on"), \
	PARA_ERROR(SYNC_PAGEOUT, "ogg sync page-out error (no ogg file?)"), \
	PARA_ERROR(TARGET_EXISTS, "requested target is already present"),\
	PARA_ERROR(TARGET_NOT_FOUND, "requested target not found"), \
	PARA_ERROR(TASK_STARTED, "task started"), \
	PARA_ERROR(DEADLY_SIGNAL, "termination request by signal"), \
	PARA_ERROR(TOO_MANY_CLIENTS, "maximal number of stat clients exceeded"), \
	PARA_ERROR(UCRED_PERM, "permission denied"), \
	PARA_ERROR(UDP_OVERRUN, "output buffer overrun"), \
	PARA_ERROR(UNKNOWN_STAT_ITEM, "status item not recognized"), \
	PARA_ERROR(UNSUPPORTED_AUDIO_FORMAT, "given audio format not supported"), \
	PARA_ERROR(UNSUPPORTED_FILTER, "given filter not supported"), \
	PARA_ERROR(USERLIST, "failed to open user list file"), \
	PARA_ERROR(VLC, "invalid vlc code"), \
	PARA_ERROR(VORBIS_COMMENTHEADER, "could not create vorbis comment header"), \
	PARA_ERROR(VORBIS, "vorbis synthesis header-in error (not vorbis?)"), \
	PARA_ERROR(WAV_BAD_FC, "invalid filter configuration"), \
	PARA_ERROR(WAV_SUCCESS, "successfully wrote wav header"), \
	PARA_ERROR(WMA_BAD_PARAMS, "invalid WMA parameters"), \
	PARA_ERROR(WMA_BAD_SUPERFRAME, "invalid superframe"), \
	PARA_ERROR(WMA_BLOCK_SIZE, "invalid block size"), \
	PARA_ERROR(WMA_NO_GUID, "audio stream guid not found"), \
	PARA_ERROR(WMA_OUTPUT_SPACE, "insufficient output space"), \

/** \cond doxygen_ignore */
/*
 * This expands to the identifier prefixed with 'E_' to declare the
 * enumeration. It is redefined below to define the string array.
 */
#define PARA_ERROR(err, msg) E_ ## err

/*
 * Public functions which can fail return the negated value of one of the
 * constants defined in this enumeration to indicate the cause of the error.
 * para_strerror() turns the error code into an error string.
 */
enum para_error_codes {PARA_ERRORS};

/* Redefine PARA_ERROR to expand to the error text. */
#undef PARA_ERROR
#define PARA_ERROR(err, msg) msg
/* Exactly one .c file per executable must expand this to define the array. */
#define DEFINE_PARA_ERRLIST const char * const para_errlist[] = {PARA_ERRORS}
/** \endcond */

/**
 * This bit indicates whether an error code corresponds to a system error
 * number. If yes, the errno value is obtained by clearing this bit from
 * the error code.
 */
#define SYSTEM_ERROR_BIT 30

/** Like SYSTEM_ERROR_BIT, but for errors from the osl library. */
#define OSL_ERROR_BIT 29

/** Like SYSTEM_ERROR_BIT, but for errors from the lopsub library. */
#define LLS_ERROR_BIT 28

/** Set the system error bit for the given number. */
#define ERRNO_TO_PARA_ERROR(num) ((num) | (1 << SYSTEM_ERROR_BIT))

static const char *weak_osl_strerror(int) __attribute__ ((weakref("osl_strerror")));
static const char *weak_lls_strerror(int) __attribute__ ((weakref("lls_strerror")));

/**
 * Paraslash's version of strerror(3).
 *
 * Besides paraslash error codes, normal system error codes, lopsub and osl
 * error codes are handled. The function determines the type of the error code,
 * then calls the corresponding strerror() to obtain the error string.
 *
 * \param num The negated (hence positive) return value of a paraslash function that
 * has failed.
 *
 * \return The error text of the given number. Static storage, callers must not call
 * free on the returned string.
 *
 * See \ref osl() and \ref lls().
 */
_static_inline_ const char *para_strerror(int num)
{
	extern const char * const para_errlist[];
	unsigned idx = num & ~((1U << OSL_ERROR_BIT) | (1U << LLS_ERROR_BIT)
		| (1U << SYSTEM_ERROR_BIT));
	assert(num > 0);
	if (num & (1 << OSL_ERROR_BIT)) {
		assert(weak_osl_strerror);
		return weak_osl_strerror(idx);
	}
	if (num & (1 << LLS_ERROR_BIT)) {
		assert(weak_lls_strerror);
		return weak_lls_strerror(idx);
	}
	if (num & (1 << SYSTEM_ERROR_BIT))
		return strerror(idx);
	return para_errlist[idx];
}

/**
 * Wrapper for osl library calls.
 *
 * \param ret The return value of an osl library function.
 *
 * This should be used for all calls to osl library functions which may return
 * an error code. It changes the return value so that it can be passed to
 * \ref para_strerror().
 *
 * \return An integer suitable as input for \ref para_strerror().
 */
_static_inline_ int osl(int ret)
{
	if (ret >= 0)
		return ret;
	return -(-ret | (1 << OSL_ERROR_BIT));
}

/**
 * Wrapper for lopsub library calls.
 *
 * \param ret See \ref osl().
 * \return See \ref osl().
 */
_static_inline_ int lls(int ret)
{
	if (ret >= 0)
		return ret;
	return -(-ret | (1 << LLS_ERROR_BIT));
}