Exemple #1
0
void macro_append(const char *text)
{
    struct membuf *mb;

    LOG(LOG_DEBUG, ("appending >>%s<< to macro\n", text));

    mb = get_named_buffer(s->named_buffer, s->macro_name);
    membuf_append(mb, text, strlen(text));
}
Exemple #2
0
static void WriteToBufferCallback(const char *text, int length, void *user_data)
{
    struct membuf *buf = ((struct ParserData *)user_data)->buf;

    if (length < 0)
        length = strlen(text);

    membuf_append(buf, text, length);
}
Exemple #3
0
// Allowed only for membufs, and unmanaged output files.
// For unmanaged output files, must be used with care, and should not be
// mixed with dbuf_write().
void dbuf_write_at(dbuf *f, i64 pos, const u8 *m, i64 len)
{
	if(len<1 || pos<0) return;

	if(pos + len > f->max_len_hard) {
		do_on_dbuf_size_exceeded(f);
	}

	if(f->btype==DBUF_TYPE_MEMBUF) {
		i64 amt_overwrite, amt_newzeroes, amt_append;

		if(pos+len <= f->len) { // entirely within the current file
			amt_overwrite = len;
			amt_newzeroes = 0;
			amt_append = 0;
		}
		else if(pos >= f->len) { // starts after the end of the current file
			amt_overwrite = 0;
			amt_newzeroes = pos - f->len;
			amt_append = len;
		}
		else { // overlaps the end of the current file
			amt_overwrite = f->len - pos;
			amt_newzeroes = 0;
			amt_append = len - amt_overwrite;
		}

		if(amt_overwrite>0) {
			de_memcpy(&f->membuf_buf[pos], m, (size_t)amt_overwrite);
		}
		if(amt_newzeroes>0) {
			dbuf_write_zeroes(f, amt_newzeroes);

		}
		if(amt_append>0) {
			membuf_append(f, &m[amt_overwrite], amt_append);
		}
	}
	else if(f->btype==DBUF_TYPE_OFILE && !f->is_managed) {
		i64 curpos = de_ftell(f->fp);
		if(pos != curpos) {
			de_fseek(f->fp, pos, SEEK_SET);
		}
		fwrite(m, 1, (size_t)len, f->fp);
		if(pos+len > f->len) {
			f->len = pos+len;
		}
	}
	else if(f->btype==DBUF_TYPE_NULL) {
		;
	}
	else {
		de_err(f->c, "internal: Attempt to seek on non-seekable stream");
		de_fatalerror(f->c);
	}
}
Exemple #4
0
void read_file(const char *name, struct membuf *buf)
{
    char block[1024];
    FILE *in;
    int len;

    in = fopen(name, "rb");
    if(in == NULL)
    {
        LOG(LOG_ERROR, ("Can't open file \"%s\" for input.\n", name));
        exit(-1);
    }
    do
    {
        len = fread(block, 1, 1024, in);
        membuf_append(buf, block, len);
    }
    while(len == 1024);
    LOG(LOG_DEBUG, ("read %d bytes from file\n", len));
    fclose(in);
}
Exemple #5
0
void dbuf_write(dbuf *f, const u8 *m, i64 len)
{
	if(f->len + len > f->max_len_hard) {
		do_on_dbuf_size_exceeded(f);
	}

	if(f->writecallback_fn) {
		f->writecallback_fn(f, m, len);
	}

	if(f->btype==DBUF_TYPE_NULL) {
		f->len += len;
		return;
	}
	else if(f->btype==DBUF_TYPE_OFILE || f->btype==DBUF_TYPE_STDOUT) {
		if(!f->fp) return;
		if(f->c->debug_level>=3) {
			de_dbg3(f->c, "writing %d bytes to %s", (int)len, f->name);
		}
		fwrite(m, 1, (size_t)len, f->fp);
		f->len += len;
		return;
	}
	else if(f->btype==DBUF_TYPE_MEMBUF) {
		if(f->c->debug_level>=3 && f->name) {
			de_dbg3(f->c, "appending %d bytes to membuf %s", (int)len, f->name);
		}
		membuf_append(f, m, len);
		return;
	}
	else if(f->btype==DBUF_TYPE_ODBUF) {
		dbuf_write(f->parent_dbuf, m, len);
		f->len += len;
		return;
	}

	de_err(f->c, "Internal: Invalid output file type (%d)", f->btype);
	de_fatalerror(f->c);
}
static
int
do_load(char *file_name, struct membuf *mem)
{
    struct load_info info[1];
    unsigned char *p;

    membuf_clear(mem);
    membuf_append(mem, NULL, 65536);
    p = membuf_get(mem);

    info->basic_txt_start = -1;

    load_located(file_name, p, info);

    /* move memory to beginning of buffer */
    membuf_truncate(mem, info->end);
    membuf_trim(mem, info->start);

    LOG(LOG_NORMAL, (" Crunching from $%04X to $%04X.",
                     info->start, info->end));
    return info->start;
}
static void load_plain_file(const char *name, struct membuf *mb)
{
    int file_len;
    int read_len;
    int offset = 0;
    int len = -1;
    FILE *in;

    in = fopen(name, "rb");
    if(in == NULL)
    {
        char *p = strrchr(name, ',');
        if(p == NULL)
        {
            /* not found and no comma  */
            LOG(LOG_ERROR, ("Error: file not found.\n"));
            exit(1);
        }
        *p = '\0';
        if(str_to_int(p + 1, &offset))
        {
            LOG(LOG_ERROR, ("Error: invalid value for plain file offset.\n"));
            exit(1);
        }
        in = fopen(name, "rb");
        if(in == NULL)
        {
            p = strrchr(name, ',');
            len = offset;
            if(len < 0)
            {
                LOG(LOG_ERROR, ("Error, value for plain file "
                                "len must not be negative.\n"));
                exit(1);
            }
            *p = '\0';
            if(str_to_int(p + 1, &offset))
            {
                LOG(LOG_ERROR,
                    ("Error: invalid value for plain file offset.\n"));
                exit(1);
            }
            in = fopen(name, "rb");
            if(in == NULL)
            {
                /* really not found */
                LOG(LOG_ERROR, ("Error: file not found.\n"));
                exit(1);
            }
        }
    }
    /* get the real length of the file and validate the offset*/
    if(fseek(in, 0, SEEK_END))
    {
        LOG(LOG_ERROR, ("Error: can't seek to EOF.\n"));
        fclose(in);
        exit(1);
    }
    file_len = ftell(in);
    if(offset < 0)
    {
        offset += file_len;
    }
    if(len < 0)
    {
        len = file_len - offset;
    }
    if(fseek(in, offset, SEEK_SET))
    {
        LOG(LOG_ERROR, ("Error: can't seek to offset %d.\n", offset));
        fclose(in);
        exit(1);
    }
    if(offset + len > file_len)
    {
        LOG(LOG_ERROR, ("Error: can't read %d bytes from offset %d.\n",
                        len, offset));
        fclose(in);
        exit(1);
    }
    LOG(LOG_VERBOSE, ("Reading %d bytes from offset %d.\n", len, offset));
    do
    {
        char buf[1024];
        int r = 1024 < len? 1024: len;
        read_len = fread(buf, 1, r, in);
        if(read_len < r)
        {
            LOG(LOG_ERROR, ("Error: tried to read %d bytes but got %d.\n",
                            r, read_len));
            fclose(in);
            exit(1);
        }
        membuf_append(mb, buf, r);
        len -= r;
    }
    while(len > 0);
    fclose(in);
}
static
int
do_loads(int filec, char *filev[], struct membuf *mem,
         int basic_txt_start, int sys_token,
         int *basic_var_startp, int *runp, int trim_sys)
{
    int run = -1;
    int min_start = 65537;
    int max_end = -1;
    int basic_code = 0;
    int i;
    unsigned char *p;
    struct load_info info[1];


    membuf_clear(mem);
    membuf_append(mem, NULL, 65536);
    p = membuf_get(mem);

    for (i = 0; i < filec; ++i)
    {
        info->basic_txt_start = basic_txt_start;
        load_located(filev[i], p, info);
        run = info->run;
        if(run != -1 && runp != NULL)
        {
            LOG(LOG_DEBUG, ("Propagating found run address $%04X.\n",
                            info->run));
            *runp = info->run;
        }

        /* do we expect any basic file? */
        if(basic_txt_start >= 0)
        {
            if(info->basic_var_start >= 0)
            {
                basic_code = 1;
                if(basic_var_startp != NULL)
                {
                    *basic_var_startp = info->basic_var_start;
                }
                if(runp != NULL && run == -1)
                {
                    /* only if we didn't get run address from load_located
                     * (run is not -1 if we did) */
                    int stub_len;
                    run = find_sys(p + basic_txt_start, sys_token, &stub_len);
                    *runp = run;
                    if (trim_sys &&
                        basic_txt_start == info->start &&
                        min_start >= info->start)
                    {
                        if (run >= info->start &&
                            run < info->start + stub_len)
                        {
                            /* the run address points into the sys stub,
                               trim up to it but no further */
                            info->start = run;
                        }
                        else
                        {
                            /* trim the sys stub*/
                            info->start += stub_len;
                        }
                    }
                }
            }
        }

        if (info->start < min_start)
        {
            min_start = info->start;
        }
        if (info->end > max_end)
        {
            max_end = info->end;
        }
    }

    if(basic_txt_start >= 0 && !basic_code && run == -1)
    {
        /* no program loaded to the basic start */
        LOG(LOG_ERROR, ("\nError: nothing loaded at the start of basic "
                        "text address ($%04X).\n",
                        basic_txt_start));
        exit(1);
    }

    /* if we have a basic code loaded and we are doing a proper basic start
     * (the caller don't expect a sys address so runp is NULL */
    if(basic_code && runp == NULL)
    {
        int valuepos = basic_txt_start - 1;
        /* the byte immediatley preceeding the basic start must be 0
         * for basic to function properly. */
        if(min_start > valuepos)
        {
            /* It not covered by the files to crunch. Since the
             * default fill value is 0 we don't need to set it but we
             * need to include that location in the crunch as well. */
            min_start = valuepos;
        }
        else
        {
            int value = p[valuepos];
            /* it has been covered by at least one file. Let's check
             * if it is zero. */
            if(value != 0)
            {
                /* Hm, its not, danger Will Robinson! */
                LOG(LOG_WARNING,
                    ("Warning, basic will probably not work since the value of"
                     " the location \npreceeding the basic start ($%04X)"
                     " is not 0 but %d.\n", valuepos, value));
            }
        }
    }

    /* move memory to beginning of buffer */
    membuf_truncate(mem, max_end);
    membuf_trim(mem, min_start);

    return min_start;
}