Пример #1
0
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]]);
        }
    }
}
Пример #2
0
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;
}
Пример #3
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;
}
Пример #4
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;
}
Пример #5
0
/*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;
}
Пример #6
0
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;
}
Пример #8
0
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;
}
Пример #9
0
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;
}
Пример #10
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;
}
Пример #11
0
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;
}
Пример #12
0
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;
}
Пример #13
0
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;
}
Пример #14
0
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);
}
Пример #15
0
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;
}
Пример #16
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;
}
Пример #17
0
/*
 * 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 */
}
Пример #18
0
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);
}
Пример #19
0
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;
}