2 * Copyright (c) 2018 Stefan Sperling <stsp@openbsd.org>
4 * Permission to use, copy, modify, and distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
28 #include "got_compat.h"
30 #include "got_error.h"
31 #include "got_object.h"
33 #include "got_lib_delta.h"
34 #include "got_lib_inflate.h"
35 #include "got_lib_object.h"
36 #include "got_lib_sha1.h"
39 #define nitems(_a) (sizeof(_a) / sizeof((_a)[0]))
42 static struct got_custom_error
{
47 static struct got_custom_error
*
50 static unsigned int idx
;
51 return &custom_errors
[(idx
++) % nitems(custom_errors
)];
54 const struct got_error
*
59 for (i
= 0; i
< nitems(got_errors
); i
++) {
60 if (code
== got_errors
[i
].code
)
61 return &got_errors
[i
];
67 const struct got_error
*
68 got_error_msg(int code
, const char *msg
)
70 struct got_custom_error
*cerr
= get_custom_err();
71 struct got_error
*err
= &cerr
->err
;
74 for (i
= 0; i
< nitems(got_errors
); i
++) {
75 if (code
== got_errors
[i
].code
) {
77 strlcpy(cerr
->msg
, msg
, sizeof(cerr
->msg
));
86 const struct got_error
*
87 got_error_from_errno(const char *prefix
)
89 struct got_custom_error
*cerr
= get_custom_err();
90 struct got_error
*err
= &cerr
->err
;
93 strerror_r(errno
, strerr
, sizeof(strerr
));
94 snprintf(cerr
->msg
, sizeof(cerr
->msg
), "%s: %s", prefix
, strerr
);
96 err
->code
= GOT_ERR_ERRNO
;
101 const struct got_error
*
102 got_error_from_errno2(const char *prefix
, const char *prefix2
)
104 struct got_custom_error
*cerr
= get_custom_err();
105 struct got_error
*err
= &cerr
->err
;
108 strerror_r(errno
, strerr
, sizeof(strerr
));
109 snprintf(cerr
->msg
, sizeof(cerr
->msg
), "%s: %s: %s", prefix
, prefix2
,
112 err
->code
= GOT_ERR_ERRNO
;
113 err
->msg
= cerr
->msg
;
117 const struct got_error
*
118 got_error_from_errno3(const char *prefix
, const char *prefix2
,
121 struct got_custom_error
*cerr
= get_custom_err();
122 struct got_error
*err
= &cerr
->err
;
125 strerror_r(errno
, strerr
, sizeof(strerr
));
126 snprintf(cerr
->msg
, sizeof(cerr
->msg
), "%s: %s: %s: %s", prefix
,
127 prefix2
, prefix3
, strerr
);
129 err
->code
= GOT_ERR_ERRNO
;
130 err
->msg
= cerr
->msg
;
134 const struct got_error
*
135 got_error_from_errno_fmt(const char *fmt
, ...)
137 struct got_custom_error
*cerr
= get_custom_err();
138 struct got_error
*err
= &cerr
->err
;
139 char buf
[PATH_MAX
* 4];
144 vsnprintf(buf
, sizeof(buf
), fmt
, ap
);
147 strerror_r(errno
, strerr
, sizeof(strerr
));
148 snprintf(cerr
->msg
, sizeof(cerr
->msg
), "%s: %s", buf
, strerr
);
150 err
->code
= GOT_ERR_ERRNO
;
151 err
->msg
= cerr
->msg
;
155 const struct got_error
*
156 got_error_set_errno(int code
, const char *prefix
)
159 return got_error_from_errno(prefix
);
162 const struct got_error
*
163 got_ferror(FILE *f
, int code
)
166 return got_error_from_errno("");
167 return got_error(code
);
170 const struct got_error
*
171 got_error_no_obj(struct got_object_id
*id
)
173 char msg
[sizeof("object not found") + SHA1_DIGEST_STRING_LENGTH
];
174 char id_str
[SHA1_DIGEST_STRING_LENGTH
];
177 if (!got_sha1_digest_to_str(id
->sha1
, id_str
, sizeof(id_str
)))
178 return got_error(GOT_ERR_NO_OBJ
);
180 ret
= snprintf(msg
, sizeof(msg
), "object %s not found", id_str
);
181 if (ret
== -1 || ret
>= sizeof(msg
))
182 return got_error(GOT_ERR_NO_OBJ
);
184 return got_error_msg(GOT_ERR_NO_OBJ
, msg
);
187 const struct got_error
*
188 got_error_not_ref(const char *refname
)
190 char msg
[sizeof("reference not found") + 1004];
193 ret
= snprintf(msg
, sizeof(msg
), "reference %s not found", refname
);
194 if (ret
== -1 || ret
>= sizeof(msg
))
195 return got_error(GOT_ERR_NOT_REF
);
197 return got_error_msg(GOT_ERR_NOT_REF
, msg
);
200 const struct got_error
*
201 got_error_uuid(uint32_t uuid_status
, const char *prefix
)
203 switch (uuid_status
) {
206 case uuid_s_bad_version
:
207 return got_error(GOT_ERR_UUID_VERSION
);
208 case uuid_s_invalid_string_uuid
:
209 return got_error(GOT_ERR_UUID_INVALID
);
210 case uuid_s_no_memory
:
211 return got_error_set_errno(ENOMEM
, prefix
);
213 return got_error(GOT_ERR_UUID
);
217 const struct got_error
*
218 got_error_path(const char *path
, int code
)
220 struct got_custom_error
*cerr
= get_custom_err();
221 struct got_error
*err
= &cerr
->err
;
224 for (i
= 0; i
< nitems(got_errors
); i
++) {
225 if (code
== got_errors
[i
].code
) {
227 snprintf(cerr
->msg
, sizeof(cerr
->msg
), "%s: %s", path
,
229 err
->msg
= cerr
->msg
;
237 const struct got_error
*
238 got_error_fmt(int code
, const char *fmt
, ...)
240 struct got_custom_error
*cerr
= get_custom_err();
241 struct got_error
*err
= &cerr
->err
;
242 char buf
[PATH_MAX
* 4];
247 vsnprintf(buf
, sizeof(buf
), fmt
, ap
);
250 for (i
= 0; i
< nitems(got_errors
); i
++) {
251 if (code
== got_errors
[i
].code
) {
253 snprintf(cerr
->msg
, sizeof(cerr
->msg
), "%s: %s", buf
,
255 err
->msg
= cerr
->msg
;