summaryrefslogtreecommitdiffstats
path: root/contrib/file/funcs.c
diff options
context:
space:
mode:
authorobrien <obrien@FreeBSD.org>2006-06-19 07:52:15 +0000
committerobrien <obrien@FreeBSD.org>2006-06-19 07:52:15 +0000
commit5c5b299c7d54da4b9c68e95d1f7a230405bd1ac2 (patch)
treeeba3401e66ba997d94604096d6095b69207f5d78 /contrib/file/funcs.c
parentdf11c7b63d4e785920524068f8f9cbdef5dc08ad (diff)
downloadFreeBSD-src-5c5b299c7d54da4b9c68e95d1f7a230405bd1ac2.zip
FreeBSD-src-5c5b299c7d54da4b9c68e95d1f7a230405bd1ac2.tar.gz
Virgin import of Christos Zoulas's FILE 4.17.
Diffstat (limited to 'contrib/file/funcs.c')
-rw-r--r--contrib/file/funcs.c96
1 files changed, 88 insertions, 8 deletions
diff --git a/contrib/file/funcs.c b/contrib/file/funcs.c
index bd77f13..5ea27f4 100644
--- a/contrib/file/funcs.c
+++ b/contrib/file/funcs.c
@@ -30,10 +30,18 @@
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
+#if defined(HAVE_WCHAR_H)
+#include <wchar.h>
+#endif
#ifndef lint
-FILE_RCSID("@(#)$Id: funcs.c,v 1.13 2004/09/11 19:15:57 christos Exp $")
+FILE_RCSID("@(#)$Id: funcs.c,v 1.19 2006/03/02 22:10:26 christos Exp $")
#endif /* lint */
+
+#ifndef HAVE_VSNPRINTF
+int vsnprintf(char *, size_t, const char *, va_list);
+#endif
+
/*
* Like printf, only we print to a buffer and advance it.
*/
@@ -110,11 +118,11 @@ file_badread(struct magic_set *ms)
#ifndef COMPILE_ONLY
protected int
-file_buffer(struct magic_set *ms, const void *buf, size_t nb)
+file_buffer(struct magic_set *ms, int fd, const void *buf, size_t nb)
{
int m;
/* try compression stuff */
- if ((m = file_zmagic(ms, buf, nb)) == 0) {
+ if ((m = file_zmagic(ms, fd, buf, nb)) == 0) {
/* Check if we have a tar file */
if ((m = file_is_tar(ms, buf, nb)) == 0) {
/* try tests in /etc/magic (or surrogate magic file) */
@@ -123,7 +131,10 @@ file_buffer(struct magic_set *ms, const void *buf, size_t nb)
if ((m = file_ascmagic(ms, buf, nb)) == 0) {
/* abandon hope, all ye who remain here */
if (file_printf(ms, ms->flags & MAGIC_MIME ?
- "application/octet-stream" : "data") == -1)
+ (nb ? "application/octet-stream" :
+ "application/empty") :
+ (nb ? "data" :
+ "empty")) == -1)
return -1;
m = 1;
}
@@ -147,6 +158,13 @@ file_reset(struct magic_set *ms)
return 0;
}
+#define OCTALIFY(n, o) \
+ *(n)++ = '\\', \
+ *(n)++ = (((uint32_t)*(o) >> 6) & 3) + '0', \
+ *(n)++ = (((uint32_t)*(o) >> 3) & 7) + '0', \
+ *(n)++ = (((uint32_t)*(o) >> 0) & 7) + '0', \
+ (o)++
+
protected const char *
file_getbuffer(struct magic_set *ms)
{
@@ -169,16 +187,78 @@ file_getbuffer(struct magic_set *ms)
ms->o.pbuf = nbuf;
}
+#if defined(HAVE_WCHAR_H) && defined(HAVE_MBRTOWC) && defined(HAVE_WCWIDTH)
+ {
+ mbstate_t state;
+ wchar_t nextchar;
+ int mb_conv = 1;
+ size_t bytesconsumed;
+ char *eop;
+ (void)memset(&state, 0, sizeof(mbstate_t));
+
+ np = ms->o.pbuf;
+ op = ms->o.buf;
+ eop = op + strlen(ms->o.buf);
+
+ while (op < eop) {
+ bytesconsumed = mbrtowc(&nextchar, op, eop - op,
+ &state);
+ if (bytesconsumed == (size_t)(-1) ||
+ bytesconsumed == (size_t)(-2)) {
+ mb_conv = 0;
+ break;
+ }
+
+ if (iswprint(nextchar) ) {
+ (void)memcpy(np, op, bytesconsumed);
+ op += bytesconsumed;
+ np += bytesconsumed;
+ } else {
+ while (bytesconsumed-- > 0)
+ OCTALIFY(np, op);
+ }
+ }
+ *np = '\0';
+
+ /* Parsing succeeded as a multi-byte sequence */
+ if (mb_conv != 0)
+ return ms->o.pbuf;
+ }
+#endif
+
for (np = ms->o.pbuf, op = ms->o.buf; *op; op++) {
if (isprint((unsigned char)*op)) {
*np++ = *op;
} else {
- *np++ = '\\';
- *np++ = ((*op >> 6) & 3) + '0';
- *np++ = ((*op >> 3) & 7) + '0';
- *np++ = ((*op >> 0) & 7) + '0';
+ OCTALIFY(np, op);
}
}
*np = '\0';
return ms->o.pbuf;
}
+
+/*
+ * Yes these suffer from buffer overflows, but if your OS does not have
+ * these functions, then maybe you should consider replacing your OS?
+ */
+#ifndef HAVE_VSNPRINTF
+int
+vsnprintf(char *buf, size_t len, const char *fmt, va_list ap)
+{
+ return vsprintf(buf, fmt, ap);
+}
+#endif
+
+#ifndef HAVE_SNPRINTF
+/*ARGSUSED*/
+int
+snprintf(char *buf, size_t len, const char *fmt, ...)
+{
+ int rv;
+ va_list ap;
+ va_start(ap, fmt);
+ rv = vsprintf(buf, fmt, ap);
+ va_end(ap);
+ return rv;
+}
+#endif
OpenPOWER on IntegriCloud