Esempio n. 1
0
int
posix_spawn_file_actions_addopen(
	posix_spawn_file_actions_t *file_actions,
	int filedes,
	const char *path,
	int oflag,
	mode_t mode)
{
	file_attr_t *fap;

	if (filedes < 0)
		return (EBADF);
	if ((fap = lmalloc(sizeof (*fap))) == NULL)
		return (ENOMEM);

	fap->fa_pathsize = strlen(path) + 1;
	if ((fap->fa_path = lmalloc(fap->fa_pathsize)) == NULL) {
		lfree(fap, sizeof (*fap));
		return (ENOMEM);
	}
	(void) strcpy(fap->fa_path, path);

	fap->fa_type = FA_OPEN;
	fap->fa_oflag = oflag;
	fap->fa_mode = mode;
	fap->fa_filedes = filedes;
	add_file_attr(file_actions, fap);

	return (0);
}
Esempio n. 2
0
/*
 * Grow the TLS module information array as necessary to include the
 * specified module-id.  tls_modinfo->tls_size must be a power of two.
 * Return a pointer to the (possibly reallocated) module information array.
 */
static TLS_modinfo *
tls_modinfo_alloc(tls_metadata_t *tlsm, ulong_t moduleid)
{
	tls_t *tls_modinfo = &tlsm->tls_modinfo;
	TLS_modinfo *modinfo;
	size_t mod_slots;

	if ((modinfo = tls_modinfo->tls_data) == NULL ||
	    tls_modinfo->tls_size <= moduleid) {
		if ((mod_slots = tls_modinfo->tls_size) == 0)
			mod_slots = MIN_MOD_SLOTS;
		while (mod_slots <= moduleid)
			mod_slots *= 2;
		modinfo = lmalloc(mod_slots * sizeof (TLS_modinfo));
		if (tls_modinfo->tls_data != NULL) {
			(void) memcpy(modinfo, tls_modinfo->tls_data,
			    tls_modinfo->tls_size * sizeof (TLS_modinfo));
			lfree(tls_modinfo->tls_data,
			    tls_modinfo->tls_size * sizeof (TLS_modinfo));
		}
		tls_modinfo->tls_data = modinfo;
		tls_modinfo->tls_size = mod_slots;
	}
	return (modinfo);
}
Esempio n. 3
0
lstring read_file(lstring path){
    FILE *fp = fopen(path,"r");
    lstring source = NULL;
    if (fp != NULL) {
        /* Go to the end of the file. */
        if (fseek(fp, 0L, SEEK_END) == 0) {
            /* Get the size of the file. */
            long bufsize = ftell(fp);
            if (bufsize == -1) {
                /* Error */
                fputs("Error al leer el archivo: ", stderr);
            }
            /* Allocate our buffer to that size. */
            source = (lstring) lmalloc(sizeof(lchar) * (bufsize + 1));
            /* Go back to the start of the file. */
            if (fseek(fp, 0L, SEEK_SET) != 0) {
                /* Error */
                fputs("Error al leer el archivo: ", stderr);
            }
            /* Read the entire file into memory. */
            size_t newLen = fread(source, sizeof(lchar), bufsize, fp);
            if (newLen == 0) {
                fputs("Error al leer el archivo: ", stderr);
            } else {
                source[++newLen] = '\0'; /* Just to be safe. */
            }
        }
        fclose(fp);
    }
    return source;
}
Esempio n. 4
0
shelf_t *make_shelf(char *input)
{
  shelf_t *shelf = lmalloc(sizeof(shelf_t));
  shelf->name = input[0];
  shelf->number = atol(input+1);
  return shelf;
}
Esempio n. 5
0
File: FAT.C Progetto: FDOS/defrag
unsigned short LARGE *readfat(int disk, unsigned short nclusters, long sector,
                              int secsfat)
{
int i;
SIZE_T bufsiz;
unsigned short LARGE *buf;

    bufsiz = ((SIZE_T)nclusters+2) * sizeof(short);

    if (bufsiz & 1)
        ++bufsiz;

    if ((buf = lmalloc(bufsiz)) == NULL)
        return NULL;

#ifndef NEED_LARGE
    memset(buf,0,bufsiz);
#endif

    if (nclusters < 4096)
        i = readfat12(disk,nclusters,sector,secsfat,buf);
    else
        i = readfat16(disk,nclusters,sector,secsfat,buf);

    if (i != 1) {
        lfree(buf);
        return NULL;
    }

    return buf;
}
Esempio n. 6
0
static void gpxecmd(const char **args)
{
    char *q;
    struct s_PXENV_FILE_EXEC *fx;

    fx = lmalloc(sizeof *fx);
    if (!fx)
	return;

    q = (char *)(fx + 1);

    fx->Status = 1;
    fx->Command.offs = OFFS(q);
    fx->Command.seg = SEG(q);

    while (*args) {
	q = stpcpy(q, *args);
	*q++ = ' ';
	args++;
    }
    *--q = '\0';

    pxe_call(PXENV_FILE_EXEC, fx);

    /* This should not return... */
}
Esempio n. 7
0
/*
 * Dispatch a work request to the thread pool.
 * If there are idle workers, awaken one.
 * Else, if the maximum number of workers has
 * not been reached, spawn a new worker thread.
 * Else just return with the job added to the queue.
 */
int
tpool_dispatch(tpool_t *tpool, void (*func)(void *), void *arg)
{
	tpool_job_t *job;

	ASSERT(!(tpool->tp_flags & (TP_DESTROY | TP_ABANDON)));

	if ((job = lmalloc(sizeof (*job))) == NULL)
		return (-1);
	job->tpj_next = NULL;
	job->tpj_func = func;
	job->tpj_arg = arg;

	sig_mutex_lock(&tpool->tp_mutex);

	if (tpool->tp_head == NULL)
		tpool->tp_head = job;
	else
		tpool->tp_tail->tpj_next = job;
	tpool->tp_tail = job;
	tpool->tp_njobs++;

	if (!(tpool->tp_flags & TP_SUSPEND)) {
		if (tpool->tp_idle > 0)
			(void) cond_signal(&tpool->tp_workcv);
		else if (tpool->tp_current < tpool->tp_maximum &&
		    create_worker(tpool) == 0)
			tpool->tp_current++;
	}

	sig_mutex_unlock(&tpool->tp_mutex);
	return (0);
}
Esempio n. 8
0
locale_t
duplocale(locale_t src)
{
	locale_t	loc;
	int		i;

	loc = lmalloc(sizeof (*loc));
	if (loc == NULL) {
		return (NULL);
	}
	if (src == NULL) {
		/* illumos extension: POSIX says LC_GLOBAL_LOCALE here */
		src = ___global_locale;
	}
	for (i = 0; i < LC_ALL; i++) {
		loc->locdata[i] = src->locdata[i];
		loc->loaded[i] = 0;
	}
	loc->collate = loc->locdata[LC_COLLATE]->l_data[0];
	loc->ctype = loc->locdata[LC_CTYPE]->l_data[0];
	loc->runelocale = loc->locdata[LC_CTYPE]->l_data[1];
	loc->messages = loc->locdata[LC_MESSAGES]->l_data[0];
	loc->monetary = loc->locdata[LC_MONETARY]->l_data[0];
	loc->numeric = loc->locdata[LC_NUMERIC]->l_data[0];
	loc->time = loc->locdata[LC_TIME]->l_data[0];
	return (loc);
}
Esempio n. 9
0
static lat_object* str_new(const char* p, size_t len)
{
  lat_object* str = lmalloc(sizeof(lat_object));
  str->type = T_STR;
  str->data_size = len;
  str->data.str = p;
  return str;
}
Esempio n. 10
0
ldb_meta_t* ldb_meta_create_with_exp(uint32_t vercare, uint64_t lastver, uint64_t nextver, uint64_t exptime){
  ldb_meta_t* meta = (ldb_meta_t*)lmalloc(sizeof(ldb_meta_t)); 
  meta->vercare_ = vercare;
  meta->lastver_ = lastver;
  meta->nextver_ = nextver;
  meta->exptime_ = exptime;
  return meta;  
}
Esempio n. 11
0
struct ludis_handle *
handle_new()
{
    struct ludis_handle *h;

    h = lmalloc(sizeof(struct ludis_handle));
    handle_init(h);
    return h;
}
Esempio n. 12
0
File: str.c Progetto: simonz05/ludis
/* buffer_new_str returns a new buffer for Str */
Buffer *
buffer_new_str(Str *s) {
    Buffer *b;

    b = lmalloc(sizeof(Buffer));
    b->off = 0;
    b->s = s;
    return b;
}
Esempio n. 13
0
File: str.c Progetto: simonz05/ludis
/* buffer_new returns a new buffer */
Buffer *
buffer_new(size_t n) {
    Buffer *b;

    b = lmalloc(sizeof(Buffer));
    b->off = 0;
    b->s = str_new(n);
    return b;
}
Esempio n. 14
0
char *lstrdup(const char *s)
{
    int l = strlen(s) + 1;
    char *d = lmalloc(l);

    if (d)
	memcpy(d, s, l);

    return d;
}
Esempio n. 15
0
void *lzalloc(size_t size)
{
    void *p;
    p = lmalloc(size);
    if (!p)
	errno = ENOMEM;
    else
	memset(p, 0, size);
    return p;
}
Esempio n. 16
0
static void dump_e820(void)
{
    com32sys_t ireg, oreg;
    struct e820_data ed;
    uint32_t type;
    void *low_ed;

    low_ed = lmalloc(sizeof ed);
    if (!low_ed)
        return;

    memset(&ireg, 0, sizeof ireg);

    ireg.eax.w[0] = 0xe820;
    ireg.edx.l = 0x534d4150;
    ireg.ecx.l = sizeof(struct e820_data);
    ireg.edi.w[0] = OFFS(low_ed);
    ireg.es = SEG(low_ed);

    memset(&ed, 0, sizeof ed);
    ed.extattr = 1;

    do {
        memcpy(low_ed, &ed, sizeof ed);

        __intcall(0x15, &ireg, &oreg);
        if (oreg.eflags.l & EFLAGS_CF ||
                oreg.eax.l != 0x534d4150 || oreg.ecx.l < 20)
            break;

        memcpy(&ed, low_ed, sizeof ed);

        if (oreg.ecx.l >= 24) {
            /* ebx base length end type */
            printf("%8x %016llx %016llx %016llx %d [%x]",
                   ireg.ebx.l, ed.base, ed.len, ed.base + ed.len, ed.type,
                   ed.extattr);
        } else {
            /* ebx base length end */
            printf("%8x %016llx %016llx %016llx %d [-]",
                   ireg.ebx.l, ed.base, ed.len, ed.base + ed.len, ed.type);
            ed.extattr = 1;
        }

        type = ed.type - 1;
        if (type < sizeof(e820_types) / sizeof(e820_types[0]))
            printf(" %s", e820_types[type]);

        putchar('\n');

        ireg.ebx.l = oreg.ebx.l;
    } while (ireg.ebx.l);

    lfree(low_ed);
}
Esempio n. 17
0
int
posix_spawnattr_init(
	posix_spawnattr_t *attr)
{
	if ((attr->__spawn_attrp = lmalloc(sizeof (posix_spawnattr_t))) == NULL)
		return (ENOMEM);
	/*
	 * Add default stuff here?
	 */
	return (0);
}
Esempio n. 18
0
int
_pthread_rwlockattr_init(pthread_rwlockattr_t *attr)
{
	rwlattr_t *ap;

	if ((ap = lmalloc(sizeof (rwlattr_t))) == NULL)
		return (ENOMEM);
	ap->pshared = DEFAULT_TYPE;
	attr->__pthread_rwlockattrp = ap;
	return (0);
}
Esempio n. 19
0
int
pthread_attr_init(pthread_attr_t *attr)
{
	thrattr_t *ap;

	if ((ap = lmalloc(sizeof (thrattr_t))) != NULL) {
		*ap = *def_thrattr();
		attr->__pthread_attrp = ap;
		return (0);
	}
	return (ENOMEM);
}
Esempio n. 20
0
SqlHelper *SqlHelper_init( const char *nomeTabella ) {
	SqlHelper *self = (SqlHelper *)lmalloc( sizeof(SqlHelper) );

    self->query = lstring_new_from_cstr( "INSERT INTO " );
    self->query = lstring_append_cstr_f( self->query, nomeTabella );
    self->query = lstring_append_cstr_f( self->query, " (" );

    self->quantiCampi = 0;

    self->buffer = lstring_new();

    return self;
}
Esempio n. 21
0
/*
 * pthread_attr_clone: make a copy of a pthread_attr_t.
 */
int
pthread_attr_clone(pthread_attr_t *attr, const pthread_attr_t *old_attr)
{
	thrattr_t *ap;
	const thrattr_t *old_ap =
	    old_attr? old_attr->__pthread_attrp : def_thrattr();

	if (old_ap == NULL)
		return (EINVAL);
	if ((ap = lmalloc(sizeof (thrattr_t))) == NULL)
		return (ENOMEM);
	*ap = *old_ap;
	attr->__pthread_attrp = ap;
	return (0);
}
Esempio n. 22
0
void
setprogname(const char *argv0)
{
	uberdata_t *udp = curthread->ul_uberdata;
	const char *progname;

	if ((progname = strrchr(argv0, '/')) == NULL)
		progname = argv0;
	else
		progname++;

	if (udp->progname == NULL)
		udp->progname = lmalloc(PROGNAMESIZE);
	(void) strlcpy(udp->progname, progname, PROGNAMESIZE);
	__progname = udp->progname;
}
Esempio n. 23
0
struct locdata *
__locdata_alloc(const char *name, size_t memsz)
{
	struct locdata *ldata;

	if ((ldata = lmalloc(sizeof (*ldata))) == NULL) {
		return (NULL);
	}
	if ((ldata->l_data[0] = libc_malloc(memsz)) == NULL) {
		lfree(ldata, sizeof (*ldata));
		errno = ENOMEM;
		return (NULL);
	}
	(void) strlcpy(ldata->l_lname, name, sizeof (ldata->l_lname));

	return (ldata);
}
Esempio n. 24
0
int
posix_spawn_file_actions_addclosefrom_np(
	posix_spawn_file_actions_t *file_actions,
	int lowfiledes)
{
	file_attr_t *fap;

	if (lowfiledes < 0)
		return (EBADF);
	if ((fap = lmalloc(sizeof (*fap))) == NULL)
		return (ENOMEM);
	fap->fa_type = FA_CLOSEFROM;
	fap->fa_filedes = lowfiledes;
	add_file_attr(file_actions, fap);

	return (0);
}
Esempio n. 25
0
File: user.c Progetto: erukiti/ma
void	ulist_init()
{
	uint	i;

	user.list=lmalloc(sizeof(ulist_t) *(MAX_user+1));
	if (user.list==NULL)
		error(lpu(farcoreleft(),0));

	op_user();
	for (i=0;i<=user.member;++i)
		{
		 if (sion_sr("user",lpu(i,0))==0)
		 	continue;
		 sion_read(nowvar);
		 ulist_rep(i,nowvar);
		}
	sion_close();
}
Esempio n. 26
0
int
posix_spawn_file_actions_adddup2(
	posix_spawn_file_actions_t *file_actions,
	int filedes,
	int newfiledes)
{
	file_attr_t *fap;

	if (filedes < 0 || newfiledes < 0)
		return (EBADF);
	if ((fap = lmalloc(sizeof (*fap))) == NULL)
		return (ENOMEM);

	fap->fa_type = FA_DUP2;
	fap->fa_filedes = filedes;
	fap->fa_newfiledes = newfiledes;
	add_file_attr(file_actions, fap);

	return (0);
}
Esempio n. 27
0
/*
 * This is called from the dynamic linker, before libc_init() is called,
 * to setup all of the TLS blocks that are available at process startup
 * and hence must be included as part of the static TLS block.
 * No locks are needed because we are single-threaded at this point.
 * We must be careful not to call any function that could possibly
 * invoke the dynamic linker.  That is, we must only call functions
 * that are wholly private to libc.
 */
void
__tls_static_mods(TLS_modinfo **tlslist, unsigned long statictlssize)
{
	ulwp_t *oldself = __curthread();
	tls_metadata_t *tlsm;
	TLS_modinfo **tlspp;
	TLS_modinfo *tlsp;
	TLS_modinfo *modinfo;
	caddr_t data;
	caddr_t data_end;
	int max_modid;

	primary_link_map = 1;		/* inform libc_init */
	if (statictlssize == 0)
		return;

	/*
	 * Retrieve whatever dynamic TLS metadata was generated by code
	 * running on alternate link maps prior to now (we must be running
	 * on the primary link map now since __tls_static_mods() is only
	 * called on the primary link map).
	 */
	tlsm = &__uberdata.tls_metadata;
	if (oldself != NULL) {
		(void) memcpy(tlsm,
		    &oldself->ul_uberdata->tls_metadata, sizeof (*tlsm));
		ASSERT(tlsm->static_tls.tls_data == NULL);
	}

	/*
	 * We call lmalloc() to allocate the template even though libc_init()
	 * has not yet been called.  lmalloc() must and does deal with this.
	 */
	ASSERT((statictlssize & (ALIGN - 1)) == 0);
	tlsm->static_tls.tls_data = data = lmalloc(statictlssize);
	data_end = data + statictlssize;
	tlsm->static_tls.tls_size = statictlssize;
	/*
	 * Initialize the static TLS template.
	 * We make no assumptions about the order in memory of the TLS
	 * modules we are processing, only that they fit within the
	 * total size we are given and that they are self-consistent.
	 * We do not assume any order for the moduleid's; we only assume
	 * that they are reasonably small integers.
	 */
	for (max_modid = 0, tlspp = tlslist; (tlsp = *tlspp) != NULL; tlspp++) {
		ASSERT(tlsp->tm_flags & TM_FLG_STATICTLS);
		ASSERT(tlsp->tm_stattlsoffset > 0);
		ASSERT(tlsp->tm_stattlsoffset <= statictlssize);
		ASSERT((tlsp->tm_stattlsoffset & (ALIGN - 1)) == 0);
		ASSERT(tlsp->tm_filesz <= tlsp->tm_memsz);
		ASSERT(tlsp->tm_memsz <= tlsp->tm_stattlsoffset);
		if (tlsp->tm_filesz)
			(void) memcpy(data_end-tlsp->tm_stattlsoffset,
			    tlsp->tm_tlsblock, tlsp->tm_filesz);
		if (max_modid < tlsp->tm_modid)
			max_modid = tlsp->tm_modid;
	}
	/*
	 * Record the static TLS_modinfo information.
	 */
	modinfo = tls_modinfo_alloc(tlsm, max_modid);
	for (tlspp = tlslist; (tlsp = *tlspp) != NULL; tlspp++)
		(void) memcpy(&modinfo[tlsp->tm_modid],
		    tlsp, sizeof (*tlsp));

	/*
	 * Copy the new tls_metadata back to the old, if any,
	 * since it will be copied up again in libc_init().
	 */
	if (oldself != NULL)
		(void) memcpy(&oldself->ul_uberdata->tls_metadata,
		    tlsm, sizeof (*tlsm));
}
Esempio n. 28
0
/*
 * Return the address of a TLS variable for the current thread.
 * Run the constructors for newly-allocated dynamic TLS.
 */
void *
slow_tls_get_addr(TLS_index *tls_index)
{
	ulwp_t *self = curthread;
	tls_metadata_t *tlsm = &self->ul_uberdata->tls_metadata;
	TLS_modinfo *tlsp;
	ulong_t moduleid;
	tls_t *tlsent;
	caddr_t	base;
	void (**initarray)(void);
	ulong_t arraycnt = 0;

	/*
	 * Defer signals until we have finished calling
	 * all of the constructors.
	 */
	sigoff(self);
	lmutex_lock(&tlsm->tls_lock);
	if ((moduleid = tls_index->ti_moduleid) < self->ul_ntlsent)
		tlsent = self->ul_tlsent;
	else {
		ASSERT(moduleid < tlsm->tls_modinfo.tls_size);
		tlsent = lmalloc(tlsm->tls_modinfo.tls_size * sizeof (tls_t));
		if (self->ul_tlsent != NULL) {
			(void) memcpy(tlsent, self->ul_tlsent,
			    self->ul_ntlsent * sizeof (tls_t));
			lfree(self->ul_tlsent,
			    self->ul_ntlsent * sizeof (tls_t));
		}
		self->ul_tlsent = tlsent;
		self->ul_ntlsent = tlsm->tls_modinfo.tls_size;
	}
	tlsent += moduleid;
	if ((base = tlsent->tls_data) == NULL) {
		tlsp = (TLS_modinfo *)tlsm->tls_modinfo.tls_data + moduleid;
		if (tlsp->tm_memsz == 0) {	/* dlclose()d module? */
			base = NULL;
		} else if (tlsp->tm_flags & TM_FLG_STATICTLS) {
			/* static TLS is already allocated/initialized */
			base = (caddr_t)self - tlsp->tm_stattlsoffset;
			tlsent->tls_data = base;
			tlsent->tls_size = 0;	/* don't lfree() this space */
		} else {
			/* allocate/initialize the dynamic TLS */
			base = lmalloc(tlsp->tm_memsz);
			if (tlsp->tm_filesz != 0)
				(void) memcpy(base, tlsp->tm_tlsblock,
				    tlsp->tm_filesz);
			tlsent->tls_data = base;
			tlsent->tls_size = tlsp->tm_memsz;
			/* remember the constructors */
			arraycnt = tlsp->tm_tlsinitarraycnt;
			initarray = tlsp->tm_tlsinitarray;
		}
	}
	lmutex_unlock(&tlsm->tls_lock);

	/*
	 * Call constructors, if any, in ascending order.
	 * We have to do this after dropping tls_lock because
	 * we have no idea what the constructors will do.
	 * At least we have signals deferred until they are done.
	 */
	if (arraycnt) {
		do {
			(**initarray++)();
		} while (--arraycnt != 0);
	}

	if (base == NULL)	/* kludge to get x86/x64 to boot */
		base = (caddr_t)self - 512;

	sigon(self);
	return (base + tls_index->ti_tlsoffset);
}
Esempio n. 29
0
/**
 * write_sectors - write several sectors from disk
 * @drive_info:		driveinfo struct describing the disk
 * @lba:		Position to write
 * @data:		Buffer to write
 * @size:		Size of the buffer (number of sectors)
 *
 * Return the number of sectors write on success or -1 on failure.
 * errno_disk contains the error number.
 **/
int write_sectors(const struct driveinfo *drive_info, const unsigned int lba,
		  const void *data, const int size)
{
    com32sys_t inreg, outreg;
    struct ebios_dapa *dapa;
    void *buf;
    int rv = -1;

    buf = lmalloc(SECTOR * size);
    if (!buf)
	return -1;

    dapa = lmalloc(sizeof(*dapa));
    if (!dapa)
	goto out;

    memcpy(buf, data, SECTOR * size);
    memset(&inreg, 0, sizeof inreg);

    if (drive_info->ebios) {
	dapa->len = sizeof(*dapa);
	dapa->count = size;
	dapa->off = OFFS(buf);
	dapa->seg = SEG(buf);
	dapa->lba = lba;

	inreg.esi.w[0] = OFFS(dapa);
	inreg.ds = SEG(dapa);
	inreg.edx.b[0] = drive_info->disk;
	inreg.eax.w[0] = 0x4300;	/* Extended write */
    } else {
	unsigned int c, h, s;

	if (!drive_info->cbios) {	// XXX errno
	    /* We failed to get the geometry */
	    if (lba)
		goto out;	/* Can only write MBR */

	    s = 1;
	    h = 0;
	    c = 0;
	} else
	    lba_to_chs(drive_info, lba, &s, &h, &c);

	// XXX errno
	if (s > 63 || h > 256 || c > 1023)
	    goto out;

	inreg.eax.w[0] = 0x0301;	/* Write one sector */
	inreg.ecx.b[1] = c & 0xff;
	inreg.ecx.b[0] = s + (c >> 6);
	inreg.edx.b[1] = h;
	inreg.edx.b[0] = drive_info->disk;
	inreg.ebx.w[0] = OFFS(buf);
	inreg.es = SEG(buf);
    }

    /* Perform the write */
    if (int13_retry(&inreg, &outreg)) {
	errno_disk = outreg.eax.b[1];	/* Give up */
    } else
	rv = size;
out:
    lfree(dapa);
    lfree(buf);
    return rv;
}
Esempio n. 30
0
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
int main(int argc, char **argv)
{
  int menu_index;
  const union syslinux_derivative_info *sdi;
  char working_dir[256];

  openconsole(&dev_stdcon_r, &dev_stdcon_w);

  lowmem_buf = lmalloc(LOWMEM_BUF_SIZE);
  if (!lowmem_buf) {
    printf("Could not allocate memory.\n");
    return 1;
  }

  sdi = syslinux_derivative_info();

  gfx_config.sector_shift = sdi->disk.sector_shift;
  gfx_config.boot_drive = sdi->disk.drive_number;

  if(sdi->c.filesystem == SYSLINUX_FS_PXELINUX) {
    gfx_config.sector_shift = 11;
    gfx_config.boot_drive = 0;
  }

  gfx_config.media_type = gfx_config.boot_drive < 0x80 ? 1 : 0;

  if(sdi->c.filesystem == SYSLINUX_FS_ISOLINUX) {
    gfx_config.media_type = sdi->iso.cd_mode ? 0 : 2;
  }

  gfx_config.bootloader = 1;
  gfx_config.sysconfig_size = sizeof gfx_config;
  gfx_config.bootloader_seg = 0;	// apparently not needed

  if(argc < 2) {
    printf("Usage: gfxboot.c32 bootlogo_file [message_file]\n");
    if(argc > 2) show_message(argv[2]);

    return 0;
  }

  if(read_config_file("~")) {
    printf("Error reading config file\n");
    if(argc > 2) show_message(argv[2]);

    return 0;
  }

  if(getcwd(working_dir, sizeof working_dir)) {
    gfx_config.gfxboot_cwd = (uint32_t) working_dir;
  }

  if(gfx_init(argv[1])) {
    printf("Error setting up gfxboot\n");
    if(argc > 2) show_message(argv[2]);

    return 0;
  }

  gfx_menu_init();

  for(;;) {
    menu_index = gfx_input();

    // abort gfx, return to text mode prompt
    if(menu_index == -1) {
      gfx_done();
      break;
    }

    // does not return if it succeeds
    boot(menu_index);
  }

  if(argc > 2) show_message(argv[2]);

  return 0;
}