void controlsPrintConfig(FileHandle* file) { file_printf(file, "config=%d\n", selectedKeyConfig); for (unsigned int i=0; i<keyConfigs.size(); i++) { file_printf(file, "(%s)\n", keyConfigs[i].name); for (int j=0; j<NUM_BINDABLE_BUTTONS; j++) { file_printf(file, "%s=%s\n", dsKeyNames[j], gbKeyNames[keyConfigs[i].funcKeys[j]]); } } }
private int handle_mime(struct magic_set *ms, int mime, const char *str) { if ((mime & MAGIC_MIME_TYPE)) { if (file_printf(ms, "inode/%s", str) == -1) return -1; if ((mime & MAGIC_MIME_ENCODING) && file_printf(ms, "; charset=") == -1) return -1; } if ((mime & MAGIC_MIME_ENCODING) && file_printf(ms, "binary") == -1) return -1; return 0; }
static int info_from_stat(RMagic *ms, mode_t md) { /* We cannot open it, but we were able to stat it. */ if (md & 0222) if (file_printf (ms, "writable, ") == -1) return -1; if (md & 0111) if (file_printf (ms, "executable, ") == -1) return -1; if (S_ISREG (md)) if (file_printf (ms, "regular file, ") == -1) return -1; if (file_printf (ms, "no read permission") == -1) return -1; return 0; }
int file_buffer(RMagic *ms, int fd, const char *inname, const void *buf, size_t nb) { int mime, m = 0; if (!ms) return -1; mime = ms->flags & R_MAGIC_MIME; if (nb == 0) { if ((!mime || (mime & R_MAGIC_MIME_TYPE)) && file_printf(ms, mime ? "application/x-empty" : "empty") == -1) return -1; return 1; } else if (nb == 1) { if ((!mime || (mime & R_MAGIC_MIME_TYPE)) && file_printf(ms, mime ? "application/octet-stream" : "very short file (no magic)") == -1) return -1; return 1; } #if 0 /* try compression stuff */ if ((ms->flags & R_MAGIC_NO_CHECK_COMPRESS) != 0 || (m = file_zmagic(ms, fd, inname, buf, nb)) == 0) { #endif /* Check if we have a tar file */ if ((ms->flags & R_MAGIC_NO_CHECK_TAR) != 0 || (m = file_is_tar(ms, buf, nb)) == 0) { /* try tests in /etc/magic (or surrogate magic file) */ if ((ms->flags & R_MAGIC_NO_CHECK_SOFT) != 0 || (m = file_softmagic(ms, buf, nb, BINTEST)) == 0) { /* try known keywords, check whether it is ASCII */ if ((ms->flags & R_MAGIC_NO_CHECK_ASCII) != 0 || (m = file_ascmagic(ms, buf, nb)) == 0) { /* abandon hope, all ye who remain here */ if ((!mime || (mime & R_MAGIC_MIME_TYPE))) { // if (mime) file_printf (ms, "application/octet-stream"); return -1; } m = 1; } } } #if 0 } #endif return m; }
/*VARARGS*/ static void file_error_core(RMagic *ms, int error, const char *f, va_list va, ut32 lineno) { /* Only the first error is ok */ if (ms->haderr) return; if (lineno != 0) { free(ms->o.buf); ms->o.buf = NULL; file_printf (ms, "line %u: ", lineno); } // OPENBSDBUG file_vprintf (ms, f, va); if (error > 0) file_printf (ms, " (%s)", strerror(error)); ms->haderr++; ms->error = error; }
void writeConfigFile() { FileHandle* file = file_open(INI_PATH, "w"); if (file == NULL) { printMenuMessage("Error opening gameyob.ini."); return; } file_printf(file, "[general]\n"); generalPrintConfig(file); file_printf(file, "[console]\n"); menuPrintConfig(file); file_printf(file, "[controls]\n"); controlsPrintConfig(file); file_close(file); char nameBuf[MAX_FILENAME_LEN]; sprintf(nameBuf, "%s.cht", gameboy->getRomFile()->getBasename()); gameboy->getCheatEngine()->saveCheats(nameBuf); }
private int bad_link(struct magic_set *ms, int err, char *buf) { int mime = ms->flags & MAGIC_MIME; if ((mime & MAGIC_MIME_TYPE) && file_printf(ms, "inode/symlink") == -1) return -1; else if (!mime) { if (ms->flags & MAGIC_ERROR) { file_error(ms, err, "broken symbolic link to `%s'", buf); return -1; } if (file_printf(ms, "broken symbolic link to `%s'", buf) == -1) return -1; } return 1; }
int file_zmagic(RMagic *ms, int fd, const char *name, const ut8 *buf, size_t nbytes) { unsigned char *newbuf = NULL; size_t i, nsz; int rv = 0; int mime = ms->flags & R_MAGIC_MIME; if ((ms->flags & R_MAGIC_COMPRESS) == 0) return 0; for (i = 0; i < ncompr; i++) { if (nbytes < compr[i].maglen) continue; if (memcmp(buf, compr[i].magic, compr[i].maglen) == 0 && (nsz = uncompressbuf(ms, fd, i, buf, &newbuf, nbytes)) != NODATA) { ms->flags &= ~R_MAGIC_COMPRESS; rv = -1; if (file_buffer(ms, -1, name, newbuf, nsz) == -1) goto error; if (mime == R_MAGIC_MIME || mime == 0) { if (file_printf(ms, mime ? " compressed-encoding=" : " (") == -1) goto error; } if ((mime == 0 || mime & R_MAGIC_MIME_ENCODING) && file_buffer(ms, -1, NULL, buf, nbytes) == -1) goto error; if (!mime && file_printf(ms, ")") == -1) goto error; rv = 1; break; } } error: if (newbuf) free(newbuf); ms->flags |= R_MAGIC_COMPRESS; return rv; }
static int info_from_stat(RMagic *ms, unsigned short md) { /* We cannot open it, but we were able to stat it. */ if (md & 0222) { if (file_printf (ms, "writable, ") == -1) { return -1; } } if (md & 0111) { if (file_printf (ms, "executable, ") == -1) { return -1; } } if (S_ISREG (md)) { if (file_printf (ms, "regular file, ") == -1) { return -1; } } if (file_printf (ms, "no read permission") == -1) { return -1; } return 0; }
private int bad_link(struct magic_set *ms, int err, char *buf) { const char *errfmt; int mime = ms->flags & MAGIC_MIME; if ((mime & MAGIC_MIME_TYPE) && file_printf(ms, "application/x-symlink") == -1) return -1; else if (!mime) { if (err == ELOOP) errfmt = "symbolic link in a loop"; else errfmt = "broken symbolic link to `%s'"; if (ms->flags & MAGIC_ERROR) { file_error(ms, err, errfmt, buf); return -1; } if (file_printf(ms, errfmt, buf) == -1) return -1; } return 1; }
int file_is_json(struct magic_set *ms, const struct buffer *b) { const unsigned char *uc = CAST(const unsigned char *, b->fbuf); const unsigned char *ue = uc + b->flen; size_t st[JSON_MAX]; int mime = ms->flags & MAGIC_MIME; if ((ms->flags & (MAGIC_APPLE|MAGIC_EXTENSION)) != 0) return 0; memset(st, 0, sizeof(st)); if (!json_parse(&uc, ue, st, 0)) return 0; if (mime == MAGIC_MIME_ENCODING) return 1; if (mime) { if (file_printf(ms, "application/json") == -1) return -1; return 1; } if (file_printf(ms, "JSON data") == -1) return -1; #if JSON_COUNT #define P(n) st[n], st[n] > 1 ? "s" : "" if (file_printf(ms, " (%" SIZE_T_FORMAT "u object%s, %" SIZE_T_FORMAT "u array%s, %" SIZE_T_FORMAT "u string%s, %" SIZE_T_FORMAT "u constant%s, %" SIZE_T_FORMAT "u number%s)", P(JSON_OBJECT), P(JSON_ARRAY), P(JSON_STRING), P(JSON_CONSTANT), P(JSON_NUMBER)) == -1) return -1; #endif return 1; }
private int bad_link(struct magic_set *ms, int err, char *buf) { char *errfmt; if (err == ELOOP) errfmt = "symbolic link in a loop"; else errfmt = "broken symbolic link to `%s'"; if (ms->flags & MAGIC_ERROR) { file_error(ms, err, errfmt, buf); return -1; } if (file_printf(ms, errfmt, buf) == -1) return -1; return 1; }
static int bad_link(RMagic *ms, int err, char *buf) { #ifdef ELOOP const char *errfmt = (err == ELOOP)? "symbolic link in a loop": "broken symbolic link to `%s'"; #else const char *errfmt = "broken symbolic link to `%s'"; #endif if (ms->flags & R_MAGIC_ERROR) { file_error (ms, err, errfmt, buf); return -1; } if (file_printf (ms, errfmt, buf) == -1) return -1; return 1; }
void generalPrintConfig(FileHandle* file) { file_printf(file, "rompath=%s\n", romPath); file_printf(file, "biosfile=%s\n", biosPath); file_printf(file, "borderfile=%s\n", borderPath); }
int file_fsmagic(struct r_magic_set *ms, const char *fn, struct stat *sb) { int ret = 0; int mime = ms->flags & R_MAGIC_MIME; #ifdef S_IFLNK char buf[BUFSIZ+4]; int nch; struct stat tstatbuf; #endif if (!fn) return 0; /* * Fstat is cheaper but fails for files you don't have read perms on. * On 4.2BSD and similar systems, use lstat() to identify symlinks. */ #ifdef S_IFLNK if ((ms->flags & R_MAGIC_SYMLINK) == 0) ret = lstat (fn, sb); else #endif ret = stat (fn, sb); /* don't merge into if; see "ret =" above */ if (ret) { if (ms->flags & R_MAGIC_ERROR) { file_error (ms, errno, "cannot stat `%s'", fn); return -1; } if (file_printf (ms, "cannot open `%s' (%s)", fn, strerror (errno)) == -1) return -1; return 1; } if (mime) { if ((sb->st_mode & S_IFMT) != S_IFREG) { if ((mime & R_MAGIC_MIME_TYPE) && file_printf (ms, "application/x-not-regular-file") == -1) return -1; return 1; } } else { #ifdef S_ISUID if (sb->st_mode & S_ISUID) if (file_printf(ms, "setuid ") == -1) return -1; #endif #ifdef S_ISGID if (sb->st_mode & S_ISGID) if (file_printf(ms, "setgid ") == -1) return -1; #endif #ifdef S_ISVTX if (sb->st_mode & S_ISVTX) if (file_printf(ms, "sticky ") == -1) return -1; #endif } switch (sb->st_mode & S_IFMT) { case S_IFDIR: if (file_printf (ms, "directory") == -1) return -1; return 1; #ifdef S_IFCHR case S_IFCHR: /* * If -s has been specified, treat character special files * like ordinary files. Otherwise, just report that they * are block special files and go on to the next file. */ if ((ms->flags & R_MAGIC_DEVICES) != 0) break; #ifdef HAVE_STAT_ST_RDEV # ifdef dv_unit if (file_printf (ms, "character special (%d/%d/%d)", major (sb->st_rdev), dv_unit(sb->st_rdev), dv_subunit (sb->st_rdev)) == -1) return -1; # else if (file_printf (ms, "character special (%ld/%ld)", (long) major (sb->st_rdev), (long) minor(sb->st_rdev)) == -1) return -1; # endif #else if (file_printf (ms, "character special") == -1) return -1; #endif return 1; #endif #ifdef S_IFBLK case S_IFBLK: /* * If -s has been specified, treat block special files * like ordinary files. Otherwise, just report that they * are block special files and go on to the next file. */ if ((ms->flags & R_MAGIC_DEVICES) != 0) break; #ifdef HAVE_STAT_ST_RDEV # ifdef dv_unit if (file_printf(ms, "block special (%d/%d/%d)", major(sb->st_rdev), dv_unit(sb->st_rdev), dv_subunit(sb->st_rdev)) == -1) return -1; # else if (file_printf(ms, "block special (%ld/%ld)", (long)major(sb->st_rdev), (long)minor(sb->st_rdev)) == -1) return -1; # endif #else if (file_printf(ms, "block special") == -1) return -1; #endif return 1; #endif /* TODO add code to handle V7 MUX and Blit MUX files */ #ifdef S_IFIFO case S_IFIFO: if((ms->flags & R_MAGIC_DEVICES) != 0) break; if (file_printf(ms, "fifo (named pipe)") == -1) return -1; return 1; #endif #ifdef S_IFDOOR case S_IFDOOR: return (file_printf (ms, "door") == -1)? -1:1; #endif #ifdef S_IFLNK case S_IFLNK: if ((nch = readlink (fn, buf, BUFSIZ-1)) <= 0) { if (ms->flags & R_MAGIC_ERROR) { file_error (ms, errno, "unreadable symlink `%s'", fn); return -1; } if (file_printf(ms, "unreadable symlink `%s' (%s)", fn, strerror(errno)) == -1) return -1; return 1; } buf[nch] = '\0'; /* readlink(2) does not do this */ /* If broken symlink, say so and quit early. */ if (*buf == '/') { if (stat(buf, &tstatbuf) < 0) return bad_link(ms, errno, buf); } else { char *tmp; char buf2[BUFSIZ+BUFSIZ+4]; if (!(tmp = strrchr(fn, '/'))) { tmp = buf; /* in current directory anyway */ } else { if (tmp - fn + 1 > BUFSIZ) { if (ms->flags & R_MAGIC_ERROR) { file_error (ms, 0, "path too long: `%s'", buf); return -1; } if (file_printf (ms, "path too long: `%s'", fn) == -1) return -1; return 1; } snprintf (buf2, sizeof (buf2), "%s%s", fn, buf); tmp = buf2; } if (stat (tmp, &tstatbuf) < 0) return bad_link(ms, errno, buf); } /* Otherwise, handle it. */ if ((ms->flags & R_MAGIC_SYMLINK) != 0) { const char *p; ms->flags &= R_MAGIC_SYMLINK; p = r_magic_file(ms, buf); ms->flags |= R_MAGIC_SYMLINK; return p != NULL ? 1 : -1; } else { /* just print what it points to */ if (file_printf (ms, "symbolic link to `%s'", buf) == -1) return -1; } return 1; #endif #ifdef S_IFSOCK case S_IFSOCK: if (file_printf(ms, "socket") == -1) return -1; return 1; #endif case S_IFREG: break; default: file_error (ms, 0, "invalid mode 0%o", sb->st_mode); return -1; /*NOTREACHED*/ } /* * regular file, check next possibility * * If stat() tells us the file has zero length, report here that * the file is empty, so we can skip all the work of opening and * reading the file. * But if the -s option has been given, we skip this optimization, * since on some systems, stat() reports zero size for raw disk * partitions. (If the block special device really has zero length, * the fact that it is empty will be detected and reported correctly * when we read the file.) */ if ((ms->flags & R_MAGIC_DEVICES) == 0 && sb->st_size == 0) { if ((!mime || (mime & R_MAGIC_MIME_TYPE)) && file_printf (ms, mime ? "application/x-empty" : "empty") == -1) return -1; return 1; } return 0; }
private int cdf_file_property_info(struct magic_set *ms, const cdf_property_info_t *info, size_t count) { size_t i; cdf_timestamp_t tp; struct timespec ts; char buf[64]; const char *str = "vnd.ms-office"; const char *s; int len; for (i = 0; i < count; i++) { cdf_print_property_name(buf, sizeof(buf), info[i].pi_id); switch (info[i].pi_type) { case CDF_SIGNED16: if (NOTMIME(ms) && file_printf(ms, ", %s: %hd", buf, info[i].pi_s16) == -1) return -1; break; case CDF_SIGNED32: if (NOTMIME(ms) && file_printf(ms, ", %s: %d", buf, info[i].pi_s32) == -1) return -1; break; case CDF_UNSIGNED32: if (NOTMIME(ms) && file_printf(ms, ", %s: %u", buf, info[i].pi_u32) == -1) return -1; break; case CDF_LENGTH32_STRING: len = info[i].pi_str.s_len; if (len > 1) { s = info[i].pi_str.s_buf; if (NOTMIME(ms)) { char vbuf[1024]; size_t j; for (j = 0; j < sizeof(vbuf) && len--; j++, s++) { if (*s == '\0') break; if (isprint((unsigned char)*s)) vbuf[j] = *s; } if (j == sizeof(vbuf)) --j; vbuf[j] = '\0'; if (vbuf[0]) { if (file_printf(ms, ", %s: %s", buf, vbuf) == -1) return -1; } } else if (info[i].pi_id == CDF_PROPERTY_NAME_OF_APPLICATION) { if (strstr(s, "Word")) str = "msword"; else if (strstr(s, "Excel")) str = "vnd.ms-excel"; else if (strstr(s, "Powerpoint")) str = "vnd.ms-powerpoint"; } } break; case CDF_FILETIME: tp = info[i].pi_tp; if (tp != 0) { if (tp < 1000000000000000LL) { char tbuf[64]; cdf_print_elapsed_time(tbuf, sizeof(tbuf), tp); if (NOTMIME(ms) && file_printf(ms, ", %s: %s", buf, tbuf) == -1) return -1; } else { char *c, *ec; cdf_timestamp_to_timespec(&ts, tp); c = ctime(&ts.tv_sec); if ((ec = strchr(c, '\n')) != NULL) *ec = '\0'; if (NOTMIME(ms) && file_printf(ms, ", %s: %s", buf, c) == -1) return -1; } } break; case CDF_CLIPBOARD: break; default: return -1; } } if (!NOTMIME(ms)) { if (file_printf(ms, "application/%s", str) == -1) return -1; } return 1; }
/* * Go through the whole list, stopping if you find a match. Process all * the continuations of that match before returning. * * We support multi-level continuations: * * At any time when processing a successful top-level match, there is a * current continuation level; it represents the level of the last * successfully matched continuation. * * Continuations above that level are skipped as, if we see one, it * means that the continuation that controls them - i.e, the * lower-level continuation preceding them - failed to match. * * Continuations below that level are processed as, if we see one, * it means we've finished processing or skipping higher-level * continuations under the control of a successful or unsuccessful * lower-level continuation, and are now seeing the next lower-level * continuation and should process it. The current continuation * level reverts to the level of the one we're seeing. * * Continuations at the current level are processed as, if we see * one, there's no lower-level continuation that may have failed. * * If a continuation matches, we bump the current continuation level * so that higher-level continuations are processed. */ static int match(RMagic *ms, struct r_magic *magic, ut32 nmagic, const ut8 *s, size_t nbytes, int mode) { ut32 magindex = 0; unsigned int cont_level = 0; int need_separator = 0; int returnval = 0; /* if a match is found it is set to 1*/ int firstline = 1; /* a flag to print X\n X\n- X */ int printed_something = 0; if (file_check_mem (ms, cont_level) == -1) return -1; for (magindex = 0; magindex < nmagic; magindex++) { int flush; struct r_magic *m = &magic[magindex]; if ((m->flag & BINTEST) != mode) { /* Skip sub-tests */ while (magic[magindex + 1].cont_level != 0 && ++magindex < nmagic - 1) continue; continue; /* Skip to next top-level test*/ } ms->offset = m->offset; ms->line = m->lineno; /* if main entry matches, print it... */ flush = !mget(ms, s, m, nbytes, cont_level); if (flush) { if (m->reln == '!') flush = 0; } else { int ret = magiccheck (ms, m); if (ret == -1) return -1; if (!ret) flush++; } if (flush) { /* * main entry didn't match, * flush its continuations */ while (magindex < nmagic - 1 && magic[magindex + 1].cont_level) magindex++; continue; } /* * If we are going to print something, we'll need to print * a blank before we print something else. */ if (*R_MAGIC_DESC) { need_separator = 1; printed_something = 1; if (print_sep(ms, firstline) == -1) return -1; } if ((ms->c.li[cont_level].off = mprint(ms, m)) == -1) return -1; /* and any continuations that match */ if (file_check_mem(ms, ++cont_level) == -1) return -1; while (++magindex < nmagic - 1 && magic[magindex].cont_level != 0) { m = &magic[magindex]; ms->line = m->lineno; /* for messages */ if (cont_level < m->cont_level) continue; if (cont_level > m->cont_level) { /* * We're at the end of the level * "cont_level" continuations. */ cont_level = m->cont_level; } ms->offset = m->offset; if (m->flag & OFFADD) ms->offset += ms->c.li[cont_level - 1].off; if (m->cond == COND_ELSE || m->cond == COND_ELIF) { if (ms->c.li[cont_level].last_match == 1) continue; } flush = !mget(ms, s, m, nbytes, cont_level); if (flush && m->reln != '!') continue; switch (flush ? 1 : magiccheck(ms, m)) { case -1: return -1; case 0: ms->c.li[cont_level].last_match = 0; break; default: ms->c.li[cont_level].last_match = 1; if (m->type != FILE_DEFAULT) ms->c.li[cont_level].got_match = 1; else if (ms->c.li[cont_level].got_match) { ms->c.li[cont_level].got_match = 0; break; } /* * If we are going to print something, * make sure that we have a separator first. */ if (*R_MAGIC_DESC) { printed_something = 1; if (print_sep(ms, firstline) == -1) return -1; } /* * This continuation matched. Print * its message, with a blank before it * if the previous item printed and * this item isn't empty. */ /* space if previous printed */ if (need_separator && ((m->flag & NOSPACE) == 0) && *R_MAGIC_DESC) { if (file_printf (ms, " ") == -1) return -1; need_separator = 0; } if ((ms->c.li[cont_level].off = mprint(ms, m)) == -1) return -1; if (*R_MAGIC_DESC) need_separator = 1; /* * If we see any continuations * at a higher level, * process them. */ if (file_check_mem(ms, ++cont_level) == -1) return -1; break; } } if (printed_something) { firstline = 0; returnval = 1; } if ((ms->flags & R_MAGIC_CONTINUE) == 0 && printed_something) return 1; /* don't keep searching */ } return returnval; /* This is hit if -k is set or there is no match */ }
static st32 mprint(RMagic *ms, struct r_magic *m) { ut64 v; float vf; double vd; ut64 t = 0; char *buf = NULL; union VALUETYPE *p = &ms->ms_value; switch (m->type) { case FILE_BYTE: v = file_signextend(ms, m, (ut64)p->b); switch (check_fmt(ms, m)) { case -1: return -1; case 1: buf = malloc (2); if (snprintf (buf, 2, "%c", (ut8)v)<0) { free (buf); return -1; } if (file_printf (ms, R_MAGIC_DESC, buf) == -1) { free (buf); return -1; } break; default: if (file_printf(ms, R_MAGIC_DESC, (ut8) v) == -1) return -1; break; } t = ms->offset + sizeof(char); break; case FILE_SHORT: case FILE_BESHORT: case FILE_LESHORT: v = file_signextend (ms, m, (ut64)p->h); switch (check_fmt (ms, m)) { case -1: return -1; case 1: buf = malloc (32); if (snprintf (buf, 32, "%hu", (unsigned short)v) < 0) { free (buf); return -1; } if (file_printf(ms, R_MAGIC_DESC, buf) == -1) { free (buf); return -1; } break; default: if (file_printf(ms, R_MAGIC_DESC, (unsigned short) v) == -1) return -1; break; } t = ms->offset + sizeof(short); break; case FILE_LONG: case FILE_BELONG: case FILE_LELONG: case FILE_MELONG: v = file_signextend(ms, m, (ut64)p->l); switch (check_fmt(ms, m)) { case -1: return -1; case 1: buf = malloc (32); if (snprintf (buf, 32, "%u", (ut32)v) < 0) { free (buf); return -1; } if (file_printf(ms, R_MAGIC_DESC, buf) == -1) { free (buf); return -1; } break; default: if (file_printf(ms, R_MAGIC_DESC, (ut32) v) == -1) return -1; break; } t = ms->offset + sizeof(st32); break; case FILE_QUAD: case FILE_BEQUAD: case FILE_LEQUAD: v = file_signextend(ms, m, p->q); if (file_printf(ms, R_MAGIC_DESC, (ut64) v) == -1) return -1; t = ms->offset + sizeof(ut64); break; case FILE_STRING: case FILE_PSTRING: case FILE_BESTRING16: case FILE_LESTRING16: if (m->reln == '=' || m->reln == '!') { if (file_printf (ms, R_MAGIC_DESC, m->value.s) == -1) return -1; t = ms->offset + m->vallen; } else { if (*m->value.s == '\0') p->s[strcspn (p->s, "\n")] = '\0'; if (file_printf (ms, R_MAGIC_DESC, p->s) == -1) return -1; t = ms->offset + strlen (p->s); if (m->type == FILE_PSTRING) t++; } break; case FILE_DATE: case FILE_BEDATE: case FILE_LEDATE: case FILE_MEDATE: if (file_printf(ms, R_MAGIC_DESC, file_fmttime(p->l, 1)) == -1) return -1; t = ms->offset + sizeof(time_t); break; case FILE_LDATE: case FILE_BELDATE: case FILE_LELDATE: case FILE_MELDATE: if (file_printf(ms, R_MAGIC_DESC, file_fmttime(p->l, 0)) == -1) return -1; t = ms->offset + sizeof(time_t); break; case FILE_QDATE: case FILE_BEQDATE: case FILE_LEQDATE: if (file_printf(ms, R_MAGIC_DESC, file_fmttime((ut32)p->q, 1)) == -1) return -1; t = ms->offset + sizeof(ut64); break; case FILE_QLDATE: case FILE_BEQLDATE: case FILE_LEQLDATE: if (file_printf(ms, R_MAGIC_DESC, file_fmttime((ut32)p->q, 0)) == -1) return -1; t = ms->offset + sizeof(ut64); break; case FILE_FLOAT: case FILE_BEFLOAT: case FILE_LEFLOAT: vf = p->f; switch (check_fmt(ms, m)) { case -1: return -1; case 1: buf = malloc (32); if (snprintf (buf, 32, "%g", vf) < 0) { free (buf); return -1; } if (file_printf (ms, R_MAGIC_DESC, buf) == -1) { free (buf); return -1; } break; default: if (file_printf(ms, R_MAGIC_DESC, vf) == -1) return -1; break; } t = ms->offset + sizeof(float); break; case FILE_DOUBLE: case FILE_BEDOUBLE: case FILE_LEDOUBLE: vd = p->d; switch (check_fmt(ms, m)) { case -1: return -1; case 1: buf = malloc (32); if (snprintf (buf, 32, "%g", vd) < 0) { free (buf); return -1; } if (file_printf (ms, R_MAGIC_DESC, buf) == -1) { free (buf); return -1; } break; default: if (file_printf(ms, R_MAGIC_DESC, vd) == -1) return -1; break; } t = ms->offset + sizeof(double); break; case FILE_REGEX: { char *cp; int rval; cp = strdupn((const char *)ms->search.s, ms->search.rm_len); if (cp == NULL) { file_oomem(ms, ms->search.rm_len); return -1; } rval = file_printf(ms, R_MAGIC_DESC, cp); free(cp); if (rval == -1) return -1; if ((m->str_flags & REGEX_OFFSET_START)) t = ms->search.offset; else t = ms->search.offset + ms->search.rm_len; break; } case FILE_SEARCH: if (file_printf(ms, R_MAGIC_DESC, m->value.s) == -1) return -1; if ((m->str_flags & REGEX_OFFSET_START)) t = ms->search.offset; else t = ms->search.offset + m->vallen; break; case FILE_DEFAULT: if (file_printf(ms, R_MAGIC_DESC, m->value.s) == -1) return -1; t = ms->offset; break; default: file_magerror(ms, "invalid m->type (%d) in mprint()", m->type); return -1; } free (buf); return(t); }
int file_ascmagic(RMagic *ms, const ut8 *buf, size_t nbytes) { return 0; size_t i; ut8 *nbuf = NULL, *utf8_buf = NULL, *utf8_end; unichar *ubuf = NULL; size_t ulen, mlen; const struct names *p; int rv = -1; int mime = ms->flags & R_MAGIC_MIME; const char *code = NULL; const char *code_mime = NULL; const char *type = NULL; const char *subtype = NULL; const char *subtype_mime = NULL; int has_escapes = 0; int has_backspace = 0; int seen_cr = 0; int n_crlf = 0; int n_lf = 0; int n_cr = 0; int n_nel = 0; size_t last_line_end = (size_t)-1; int has_long_lines = 0; /* * Undo the NUL-termination kindly provided by process() * but leave at least one byte to look at */ while (nbytes > 1 && buf[nbytes - 1] == '\0') nbytes--; if (!(nbuf = calloc(1, (nbytes + 1) * sizeof(nbuf[0])))) goto done; if (!(ubuf = calloc(1, (nbytes + 1) * sizeof(ubuf[0])))) goto done; /* * Then try to determine whether it's any character code we can * identify. Each of these tests, if it succeeds, will leave * the text converted into one-unichar-per-character Unicode in * ubuf, and the number of characters converted in ulen. */ if (looks_ascii(buf, nbytes, ubuf, &ulen)) { code = "ASCII"; code_mime = "us-ascii"; type = "text"; } else if (looks_utf8_with_BOM(buf, nbytes, ubuf, &ulen) > 0) { code = "UTF-8 Unicode (with BOM)"; code_mime = "utf-8"; type = "text"; } else if (file_looks_utf8(buf, nbytes, ubuf, &ulen) > 1) { code = "UTF-8 Unicode"; code_mime = "utf-8"; type = "text"; } else if ((i = looks_ucs16(buf, nbytes, ubuf, &ulen)) != 0) { if (i == 1) code = "Little-endian UTF-16 Unicode"; else code = "Big-endian UTF-16 Unicode"; type = "character data"; code_mime = "utf-16"; /* is this defined? */ } else if (looks_latin1(buf, nbytes, ubuf, &ulen)) { if (!memcmp (buf, "\xff\xff\xff\xff", 4)) { // uninitialized memory is not iso-8859!! goto done; } code = "ISO-8859"; type = "text"; code_mime = "iso-8859-1"; } else if (looks_extended(buf, nbytes, ubuf, &ulen)) { code = "Non-ISO extended-ASCII"; type = "text"; code_mime = "unknown"; } else { from_ebcdic(buf, nbytes, nbuf); if (looks_ascii(nbuf, nbytes, ubuf, &ulen)) { code = "EBCDIC"; type = "character data"; code_mime = "ebcdic"; } else if (looks_latin1(nbuf, nbytes, ubuf, &ulen)) { code = "International EBCDIC"; type = "character data"; code_mime = "ebcdic"; } else { rv = 0; goto done; /* doesn't look like text at all */ } } if (nbytes <= 1) { rv = 0; goto done; } /* Convert ubuf to UTF-8 and try text soft magic */ /* If original was ASCII or UTF-8, could use nbuf instead of re-converting. */ /* malloc size is a conservative overestimate; could be re-converting improved, or at least realloced after re-converting conversion. */ mlen = ulen * 6; if (!(utf8_buf = malloc(mlen))) { file_oomem(ms, mlen); goto done; } if (!(utf8_end = encode_utf8(utf8_buf, mlen, ubuf, ulen))) goto done; if (file_softmagic(ms, utf8_buf, utf8_end - utf8_buf, TEXTTEST) != 0) { rv = 1; goto done; } /* look for tokens from names.h - this is expensive! */ if ((ms->flags & R_MAGIC_NO_CHECK_TOKENS) != 0) goto subtype_identified; i = 0; while (i < ulen) { size_t end; /* skip past any leading space */ while (i < ulen && ISSPC(ubuf[i])) i++; if (i >= ulen) break; /* find the next whitespace */ for (end = i + 1; end < nbytes; end++) if (ISSPC(ubuf[end])) break; /* compare the word thus isolated against the token list */ for (p = names; p < names + NNAMES; p++) { if (ascmatch((const ut8 *)p->name, ubuf + i, end - i)) { subtype = types[p->type].human; subtype_mime = types[p->type].mime; goto subtype_identified; } } i = end; } subtype_identified: /* Now try to discover other details about the file. */ for (i = 0; i < ulen; i++) { if (ubuf[i] == '\n') { if (seen_cr) n_crlf++; else n_lf++; last_line_end = i; } else if (seen_cr) n_cr++; seen_cr = (ubuf[i] == '\r'); if (seen_cr) last_line_end = i; if (ubuf[i] == 0x85) { /* X3.64/ECMA-43 "next line" character */ n_nel++; last_line_end = i; } /* If this line is _longer_ than MAXLINELEN, remember it. */ if (i > last_line_end + MAXLINELEN) has_long_lines = 1; if (ubuf[i] == '\033') has_escapes = 1; if (ubuf[i] == '\b') has_backspace = 1; } /* Beware, if the data has been truncated, the final CR could have been followed by a LF. If we have HOWMANY bytes, it indicates that the data might have been truncated, probably even before this function was called. */ if (seen_cr && nbytes < HOWMANY) n_cr++; if (mime) { if (mime & R_MAGIC_MIME_TYPE) { if (subtype_mime) { if (file_printf(ms, subtype_mime) == -1) goto done; } else { if (file_printf(ms, "text/plain") == -1) goto done; } } if ((mime == 0 || mime == R_MAGIC_MIME) && code_mime) { if ((mime & R_MAGIC_MIME_TYPE) && file_printf(ms, " charset=") == -1) goto done; if (file_printf(ms, code_mime) == -1) goto done; } if (mime == R_MAGIC_MIME_ENCODING) if (file_printf(ms, "binary") == -1){ rv = 1; goto done; } } else { if (file_printf(ms, code) == -1) goto done; if (subtype) { if (file_printf(ms, " ") == -1) goto done; if (file_printf(ms, subtype) == -1) goto done; } if (file_printf(ms, " ") == -1) goto done; if (file_printf(ms, type) == -1) goto done; if (has_long_lines) if (file_printf(ms, ", with very long lines") == -1) goto done; /* * Only report line terminators if we find one other than LF, * or if we find none at all. */ if ((n_crlf == 0 && n_cr == 0 && n_nel == 0 && n_lf == 0) || (n_crlf != 0 || n_cr != 0 || n_nel != 0)) { if (file_printf(ms, ", with") == -1) goto done; if (n_crlf == 0 && n_cr == 0 && n_nel == 0 && n_lf == 0) { if (file_printf(ms, " no") == -1) goto done; } else { if (n_crlf) { if (file_printf(ms, " CRLF") == -1) goto done; if (n_cr || n_lf || n_nel) if (file_printf(ms, ",") == -1) goto done; } if (n_cr) { if (file_printf(ms, " CR") == -1) goto done; if (n_lf || n_nel) if (file_printf(ms, ",") == -1) goto done; } if (n_lf) { if (file_printf(ms, " LF") == -1) goto done; if (n_nel) if (file_printf(ms, ",") == -1) goto done; } if (n_nel) if (file_printf(ms, " NEL") == -1) goto done; } if (file_printf(ms, " line terminators") == -1) goto done; } if (has_escapes) if (file_printf(ms, ", with escape sequences") == -1) goto done; if (has_backspace) if (file_printf(ms, ", with overstriking") == -1) goto done; } rv = 1; done: free (nbuf); free (ubuf); free (utf8_buf); return rv; }