Exemplo n.º 1
0
Arquivo: xskip.c Projeto: mrmt/enma
/*
 * [RFC2822]
 * quoted-pair = ("\" text) / obs-qp
 */
int
XSkip_quotedPair(const char *head, const char *tail, const char **nextp)
{
    *nextp = head;
    if (head + 1 < tail && *head == '\\' && IS_TEXT(*(head + 1))) {
        *nextp += 2;
    }   // end if
    return *nextp - head;
}   // end function : XSkip_quotedPair
Exemplo n.º 2
0
Arquivo: xparse.c Projeto: mrmt/enma
/*
 * [RFC2822]
 * quoted-pair = ("\" text) / obs-qp
 */
static int
XParse_quotedPair(const char *head, const char *tail, const char **nextp, XBuffer *xbuf)
{
    *nextp = head;
    if (head + 1 < tail && *head == '\\' && IS_TEXT(*(head + 1))) {
        XBuffer_appendChar(xbuf, *(head + 1));
        *nextp += 2;
    }   // end if

    return *nextp - head;
}   // end function : XParse_quotedPair
Exemplo n.º 3
0
gboolean populate_files (gpointer data)     //TODO:: show an spinner while loading
{
  FilebrowserBackend *filebackend= FILEBROWSER_BACKEND(data);
  FilebrowserBackendDetails *directory = FILEBROWSER_BACKEND_GET_PRIVATE(filebackend);
  GDK_THREADS_ENTER();
  if (g_cancellable_is_cancelled (directory->cancellable)){
  GDK_THREADS_LEAVE();
  return FALSE; /* remove source */
  }
  GError *error=NULL;
  GFileInfo *info = g_file_enumerator_next_file (directory->enumerator, directory->cancellable, &error);
  if (info){
	  const gchar *mime= g_file_info_get_content_type (info);
	  if (!g_file_info_get_is_hidden (info)  && !g_file_info_get_is_backup (info)){
	    if (MIME_ISDIR(mime)){
		//if has dot in name pos 0 don't process
		const gchar *folder=g_file_info_get_display_name(info);
		if(folder[0]!='.'){
		  FOLDERFILE *current;
		  current=new_folderfile();
		  current->mime=g_strdup(mime);
      GIcon *icon =g_file_info_get_icon(info); 
      current->icon= g_icon_to_string (icon);
		  current->display_name=g_strdup(folder);
		  /* add to list */
		 directory->filesinfolder = g_slist_append(directory->filesinfolder, current);
		  }
	  } else {
	    if (IS_TEXT(mime) && !IS_APPLICATION(mime)){
	      //files
	      FOLDERFILE *current;
	      current=new_folderfile();
	      current->mime=g_strdup(mime);
	      GIcon *icon =g_file_info_get_icon(info); 
	      current->icon= g_icon_to_string (icon);
	      current->display_name=g_strdup(g_file_info_get_display_name(info));
	      /* add to list */
	      directory->filesinfolder = g_slist_append(directory->filesinfolder, current);
	      }
	    }
	  }	
	g_object_unref(info);
   } else {
   	if (error){
   		g_print(_("Error::%s"),error->message);
   		g_error_free (error);
   	}
	GDK_THREADS_LEAVE();
	return FALSE; /* remove source */
   }
    GDK_THREADS_LEAVE();
    return TRUE;
}
Exemplo n.º 4
0
static gboolean
parse_domain (const gchar *argument, gint index, gint *parsed_position,
              GError **error)
{
    gint i;
    const gchar *domain;

    domain = argument + index;
    if (domain[0] == '[') {
        i = 1;
        while (TRUE) {
            if (domain[i] == '[' || domain[i] == ']') {
                break;
            } else if (domain[i] == '\\') {
                i++;
                if (IS_TEXT(domain[i])) {
                    i++;
                } else {
                    RETURN_ERROR_WITH_POSITION("invalid quoted character "
                                               "in domain",
                                               argument, index + i);
                }
            } else if (g_ascii_isspace(domain[i])) {
                break;
            } else if (g_ascii_iscntrl(domain[i]) ||
                       g_ascii_isgraph(domain[i])) {
                i++;
            } else {
                break;
            }
        }
        if (domain[i] != ']')
            RETURN_ERROR_WITH_POSITION("terminate ']' is missing in domain",
                                       argument, index + i);
        i++;
    } else {
        i = 0;
        if (!g_ascii_isalnum(domain[i]))
            RETURN_ERROR_WITH_POSITION("domain should start with "
                                       "alphabet or digit",
                                       argument, index + i);
        do {
            i++;
            while (g_ascii_isalnum(domain[i]) || domain[i] == '-') {
                i++;
            }
        } while (domain[i] == '.');
    }

    *parsed_position = i;
    return TRUE;
}
Exemplo n.º 5
0
static gboolean
parse_local_part (const gchar *argument, gint index, gint *parsed_position,
                  GError **error)
{
    gint i;
    const gchar *local_part;

    local_part = argument + index;
    if (local_part[0] == '"') {
        i = 1;
        while (TRUE) {
            if (local_part[i] == '\\') {
                i++;
                if (IS_TEXT(local_part[i])) {
                    i++;
                } else {
                    RETURN_ERROR_WITH_POSITION("invalid quoted character "
                                               "in local part",
                                               argument, index + i);
                }
            } else if (local_part[i] == '"') {
                break;
            } else if (g_ascii_isspace(local_part[i])) {
                break;
            } else if (g_ascii_iscntrl(local_part[i]) ||
                       g_ascii_isgraph(local_part[i])) {
                i++;
            } else {
                break;
            }
        }
        if (local_part[i] != '"')
            RETURN_ERROR_WITH_POSITION("end quote for local part is missing",
                                       argument, index + i);
        i++;
    } else {
        i = -1;
        do {
            i++;
            while (IS_ATOM_TEXT(local_part[i])) {
                i++;
            }
        } while (local_part[i] == '.');
    }

    *parsed_position = i;
    return TRUE;
}
Exemplo n.º 6
0
static int
elf_exec(int fd, Elf_Ehdr *elf, u_long *marks, int flags)
{
	Elf_Shdr *shp;
	Elf_Phdr *phdr;
	Elf_Off off;
	int i;
	size_t sz;
	int first;
	int havesyms;
	paddr_t minp = ~0, maxp = 0, pos = 0;
	paddr_t offset = marks[MARK_START], shpp, elfp;

	sz = elf->e_phnum * sizeof(Elf_Phdr);
	phdr = ALLOC(sz);

	if (lseek(fd, elf->e_phoff, SEEK_SET) == -1)  {
		WARN(("lseek phdr"));
		FREE(phdr, sz);
		return 1;
	}
	if (read(fd, phdr, sz) != sz) {
		WARN(("read program headers"));
		FREE(phdr, sz);
		return 1;
	}

	for (first = 1, i = 0; i < elf->e_phnum; i++) {

		if (phdr[i].p_type != PT_LOAD ||
		    (phdr[i].p_flags & (PF_W|PF_R|PF_X)) == 0)
			continue;

#define IS_TEXT(p)	(p.p_flags & PF_X)
#define IS_DATA(p)	((p.p_flags & PF_X) == 0)
#define IS_BSS(p)	(p.p_filesz < p.p_memsz)
		/*
		 * XXX: Assume first address is lowest
		 */
		if ((IS_TEXT(phdr[i]) && (flags & LOAD_TEXT)) ||
		    (IS_DATA(phdr[i]) && (flags & LOAD_DATA))) {

			/* Read in segment. */
			PROGRESS(("%s%lu", first ? "" : "+",
			    (u_long)phdr[i].p_filesz));

			if (lseek(fd, phdr[i].p_offset, SEEK_SET) == -1)  {
				WARN(("lseek text"));
				FREE(phdr, sz);
				return 1;
			}
			if (READ(fd, phdr[i].p_vaddr, phdr[i].p_filesz) !=
			    phdr[i].p_filesz) {
				WARN(("read text"));
				FREE(phdr, sz);
				return 1;
			}
			first = 0;

		}
		if ((IS_TEXT(phdr[i]) && (flags & (LOAD_TEXT|COUNT_TEXT))) ||
		    (IS_DATA(phdr[i]) && (flags & (LOAD_DATA|COUNT_TEXT)))) {
			pos = phdr[i].p_vaddr;
			if (minp > pos)
				minp = pos;
			pos += phdr[i].p_filesz;
			if (maxp < pos)
				maxp = pos;
		}

		/* Zero out bss. */
		if (IS_BSS(phdr[i]) && (flags & LOAD_BSS)) {
			PROGRESS(("+%lu",
			    (u_long)(phdr[i].p_memsz - phdr[i].p_filesz)));
			BZERO((phdr[i].p_vaddr + phdr[i].p_filesz),
			    phdr[i].p_memsz - phdr[i].p_filesz);
		}
		if (IS_BSS(phdr[i]) && (flags & (LOAD_BSS|COUNT_BSS))) {
			pos += phdr[i].p_memsz - phdr[i].p_filesz;
			if (maxp < pos)
				maxp = pos;
		}
	}
	FREE(phdr, sz);

	/*
	 * Copy the ELF and section headers.
	 */
	elfp = maxp = roundup(maxp, sizeof(long));
	if (flags & (LOAD_HDR|COUNT_HDR))
		maxp += sizeof(Elf_Ehdr);

	if (flags & (LOAD_SYM|COUNT_SYM)) {
		if (lseek(fd, elf->e_shoff, SEEK_SET) == -1)  {
			WARN(("lseek section headers"));
			return 1;
		}
		sz = elf->e_shnum * sizeof(Elf_Shdr);
		shp = ALLOC(sz);

		if (read(fd, shp, sz) != sz) {
			WARN(("read section headers"));
			return 1;
		}

		shpp = maxp;
		maxp += roundup(sz, sizeof(long));

		/*
		 * Now load the symbol sections themselves.  Make sure the
		 * sections are aligned. Don't bother with string tables if
		 * there are no symbol sections.
		 */
		off = roundup((sizeof(Elf_Ehdr) + sz), sizeof(long));

		for (havesyms = i = 0; i < elf->e_shnum; i++)
			if (shp[i].sh_type == SHT_SYMTAB)
				havesyms = 1;

		for (first = 1, i = 0; i < elf->e_shnum; i++) {
			if (shp[i].sh_type == SHT_SYMTAB ||
			    shp[i].sh_type == SHT_STRTAB) {
				if (havesyms && (flags & LOAD_SYM)) {
					PROGRESS(("%s%ld", first ? " [" : "+",
					    (u_long)shp[i].sh_size));
					if (lseek(fd, shp[i].sh_offset,
					    SEEK_SET) == -1) {
						WARN(("lseek symbols"));
						FREE(shp, sz);
						return 1;
					}
					if (READ(fd, maxp, shp[i].sh_size) !=
					    shp[i].sh_size) {
						WARN(("read symbols"));
						FREE(shp, sz);
						return 1;
					}
				}
				maxp += roundup(shp[i].sh_size,
				    sizeof(long));
				shp[i].sh_offset = off;
				off += roundup(shp[i].sh_size, sizeof(long));
				first = 0;
			}
		}
		if (flags & LOAD_SYM) {
			BCOPY(shp, shpp, sz);

			if (havesyms && first == 0)
				PROGRESS(("]"));
		}
		FREE(shp, sz);
	}

	/*
	 * Frob the copied ELF header to give information relative
	 * to elfp.
	 */
	if (flags & LOAD_HDR) {
		elf->e_phoff = 0;
		elf->e_shoff = sizeof(Elf_Ehdr);
		elf->e_phentsize = 0;
		elf->e_phnum = 0;
		BCOPY(elf, elfp, sizeof(*elf));
	}

	marks[MARK_START] = LOADADDR(minp);
	marks[MARK_ENTRY] = LOADADDR(elf->e_entry);
	marks[MARK_NSYM] = 1;	/* XXX: Kernel needs >= 0 */
	marks[MARK_SYM] = LOADADDR(elfp);
	marks[MARK_END] = LOADADDR(maxp);
	return 0;
}
Exemplo n.º 7
0
/*
 * elf32_exec
 *
 * Load the kernel indicated by 'fd' into the guest physical memory
 * space, at the addresses defined in the ELF header.
 *
 * This function is used for 32 bit kernels.
 *
 * Parameters:
 *  fd: file descriptor of the kernel to load
 *  elf: ELF header of the kernel
 *  marks: array to store the offsets of various kernel structures
 *      (start, bss, etc)
 *  flags: flag value to indicate which section(s) to load (usually
 *      LOAD_ALL)
 *
 * Return values:
 *  0 if successful
 *  1 if unsuccessful
 */
static int
elf32_exec(int fd, Elf32_Ehdr *elf, u_long *marks, int flags)
{
	Elf32_Shdr *shp;
	Elf32_Phdr *phdr;
	Elf32_Off off;
	int i;
	ssize_t sz;
	int first;
	int havesyms, havelines;
	paddr_t minp = ~0, maxp = 0, pos = 0;
	paddr_t offset = marks[MARK_START], shpp, elfp;

	sz = elf->e_phnum * sizeof(Elf32_Phdr);
	phdr = malloc(sz);

	if (lseek(fd, (off_t)elf->e_phoff, SEEK_SET) == -1)  {
		free(phdr);
		return 1;
	}

	if (read(fd, phdr, sz) != sz) {
		free(phdr);
		return 1;
	}

	for (first = 1, i = 0; i < elf->e_phnum; i++) {
		if (phdr[i].p_type == PT_OPENBSD_RANDOMIZE) {
			int m;

			/* Fill segment if asked for. */
			if (flags & LOAD_RANDOM) {
				for (pos = 0; pos < phdr[i].p_filesz;
				    pos += m) {
					m = phdr[i].p_filesz - pos;
					marc4random_buf(phdr[i].p_paddr + pos,
					    m);
				}
			}
			if (flags & (LOAD_RANDOM | COUNT_RANDOM)) {
				marks[MARK_RANDOM] = LOADADDR(phdr[i].p_paddr);
				marks[MARK_ERANDOM] =
				    marks[MARK_RANDOM] + phdr[i].p_filesz;
			}
			continue;
		}

		if (phdr[i].p_type != PT_LOAD ||
		    (phdr[i].p_flags & (PF_W|PF_R|PF_X)) == 0)
			continue;

#define IS_TEXT(p)	(p.p_flags & PF_X)
#define IS_DATA(p)	((p.p_flags & PF_X) == 0)
#define IS_BSS(p)	(p.p_filesz < p.p_memsz)
		/*
		 * XXX: Assume first address is lowest
		 */
		if ((IS_TEXT(phdr[i]) && (flags & LOAD_TEXT)) ||
		    (IS_DATA(phdr[i]) && (flags & LOAD_DATA))) {

			/* Read in segment. */
			if (lseek(fd, (off_t)phdr[i].p_offset,
			    SEEK_SET) == -1) {
				free(phdr);
				return 1;
			}
			if (mread(fd, phdr[i].p_paddr, phdr[i].p_filesz) !=
			    phdr[i].p_filesz) {
				free(phdr);
				return 1;
			}

			first = 0;
		}

		if ((IS_TEXT(phdr[i]) && (flags & (LOAD_TEXT | COUNT_TEXT))) ||
		    (IS_DATA(phdr[i]) && (flags & (LOAD_DATA | COUNT_TEXT)))) {
			pos = phdr[i].p_paddr;
			if (minp > pos)
				minp = pos;
			pos += phdr[i].p_filesz;
			if (maxp < pos)
				maxp = pos;
		}

		/* Zero out BSS. */
		if (IS_BSS(phdr[i]) && (flags & LOAD_BSS)) {
			mbzero((phdr[i].p_paddr + phdr[i].p_filesz),
			    phdr[i].p_memsz - phdr[i].p_filesz);
		}
		if (IS_BSS(phdr[i]) && (flags & (LOAD_BSS|COUNT_BSS))) {
			pos += phdr[i].p_memsz - phdr[i].p_filesz;
			if (maxp < pos)
				maxp = pos;
		}
	}
	free(phdr);

	/*
	 * Copy the ELF and section headers.
	 */
	elfp = maxp = roundup(maxp, sizeof(Elf32_Addr));
	if (flags & (LOAD_HDR | COUNT_HDR))
		maxp += sizeof(Elf32_Ehdr);

	if (flags & (LOAD_SYM | COUNT_SYM)) {
		if (lseek(fd, (off_t)elf->e_shoff, SEEK_SET) == -1)  {
			WARN(("lseek section headers"));
			return 1;
		}
		sz = elf->e_shnum * sizeof(Elf32_Shdr);
		shp = malloc(sz);

		if (read(fd, shp, sz) != sz) {
			free(shp);
			return 1;
		}

		shpp = maxp;
		maxp += roundup(sz, sizeof(Elf32_Addr));

		ssize_t shstrsz = shp[elf->e_shstrndx].sh_size;
		char *shstr = malloc(shstrsz);
		if (lseek(fd, (off_t)shp[elf->e_shstrndx].sh_offset,
		    SEEK_SET) == -1) {
			free(shstr);
			free(shp);
			return 1;
		}
		if (read(fd, shstr, shstrsz) != shstrsz) {
			free(shstr);
			free(shp);
			return 1;
		}

		/*
		 * Now load the symbol sections themselves. Make sure the
		 * sections are aligned. Don't bother with string tables if
		 * there are no symbol sections.
		 */
		off = roundup((sizeof(Elf32_Ehdr) + sz), sizeof(Elf32_Addr));

		for (havesyms = havelines = i = 0; i < elf->e_shnum; i++)
			if (shp[i].sh_type == SHT_SYMTAB)
				havesyms = 1;

		for (first = 1, i = 0; i < elf->e_shnum; i++) {
			if (shp[i].sh_type == SHT_SYMTAB ||
			    shp[i].sh_type == SHT_STRTAB ||
			    !strcmp(shstr + shp[i].sh_name, ".debug_line")) {
				if (havesyms && (flags & LOAD_SYM)) {
					if (lseek(fd, (off_t)shp[i].sh_offset,
					    SEEK_SET) == -1) {
						free(shstr);
						free(shp);
						return 1;
					}
					if (mread(fd, maxp,
					    shp[i].sh_size) != shp[i].sh_size) {
						free(shstr);
						free(shp);
						return 1;
					}
				}
				maxp += roundup(shp[i].sh_size,
				    sizeof(Elf32_Addr));
				shp[i].sh_offset = off;
				shp[i].sh_flags |= SHF_ALLOC;
				off += roundup(shp[i].sh_size,
				    sizeof(Elf32_Addr));
				first = 0;
			}
		}
		if (flags & LOAD_SYM) {
			mbcopy(shp, shpp, sz);
		}
		free(shstr);
		free(shp);
	}

	/*
	 * Frob the copied ELF header to give information relative
	 * to elfp.
	 */
	if (flags & LOAD_HDR) {
		elf->e_phoff = 0;
		elf->e_shoff = sizeof(Elf32_Ehdr);
		elf->e_phentsize = 0;
		elf->e_phnum = 0;
		mbcopy(elf, elfp, sizeof(*elf));
	}

	marks[MARK_START] = LOADADDR(minp);
	marks[MARK_ENTRY] = LOADADDR(elf->e_entry);
	marks[MARK_NSYM] = 1;	/* XXX: Kernel needs >= 0 */
	marks[MARK_SYM] = LOADADDR(elfp);
	marks[MARK_END] = LOADADDR(maxp);

	return 0;
}
Exemplo n.º 8
0
//
//  MAKE_Tuple: C
//
REB_R MAKE_Tuple(
    REBVAL *out,
    enum Reb_Kind kind,
    const REBVAL *opt_parent,
    const REBVAL *arg
){
    assert(kind == REB_TUPLE);
    if (opt_parent)
        fail (Error_Bad_Make_Parent(kind, opt_parent));

    if (IS_TUPLE(arg))
        return Move_Value(out, arg);

    RESET_CELL(out, REB_TUPLE, CELL_MASK_NONE);
    REBYTE *vp = VAL_TUPLE(out);

    // !!! Net lookup parses IP addresses out of `tcp://93.184.216.34` or
    // similar URL!s.  In Rebol3 these captures come back the same type
    // as the input instead of as STRING!, which was a latent bug in the
    // network code of the 12-Dec-2012 release:
    //
    // https://github.com/rebol/rebol/blob/master/src/mezz/sys-ports.r#L110
    //
    // All attempts to convert a URL!-flavored IP address failed.  Taking
    // URL! here fixes it, though there are still open questions.
    //
    if (IS_TEXT(arg) or IS_URL(arg)) {
        REBSIZ size;
        const REBYTE *bp
            = Analyze_String_For_Scan(&size, arg, MAX_SCAN_TUPLE);

        if (Scan_Tuple(out, bp, size) == nullptr)
            fail (arg);
        return out;
    }

    if (ANY_ARRAY(arg)) {
        REBCNT len = 0;
        REBINT n;

        RELVAL *item = VAL_ARRAY_AT(arg);

        for (; NOT_END(item); ++item, ++vp, ++len) {
            if (len >= MAX_TUPLE)
                goto bad_make;
            if (IS_INTEGER(item)) {
                n = Int32(item);
            }
            else if (IS_CHAR(item)) {
                n = VAL_CHAR(item);
            }
            else
                goto bad_make;

            if (n > 255 || n < 0)
                goto bad_make;
            *vp = n;
        }

        VAL_TUPLE_LEN(out) = len;

        for (; len < MAX_TUPLE; len++) *vp++ = 0;
        return out;
    }

    REBCNT alen;

    if (IS_ISSUE(arg)) {
        REBSTR *spelling = VAL_STRING(arg);
        const REBYTE *ap = STR_HEAD(spelling);
        size_t size = STR_SIZE(spelling); // UTF-8 len
        if (size & 1)
            fail (arg); // must have even # of chars
        size /= 2;
        if (size > MAX_TUPLE)
            fail (arg); // valid even for UTF-8
        VAL_TUPLE_LEN(out) = size;
        for (alen = 0; alen < size; alen++) {
            REBYTE decoded;
            if ((ap = Scan_Hex2(&decoded, ap)) == NULL)
                fail (arg);
            *vp++ = decoded;
        }
    }
    else if (IS_BINARY(arg)) {
        REBYTE *ap = VAL_BIN_AT(arg);
        REBCNT len = VAL_LEN_AT(arg);
        if (len > MAX_TUPLE) len = MAX_TUPLE;
        VAL_TUPLE_LEN(out) = len;
        for (alen = 0; alen < len; alen++) *vp++ = *ap++;
    }
    else
        fail (arg);

    for (; alen < MAX_TUPLE; alen++) *vp++ = 0;
    return out;

  bad_make:
    fail (Error_Bad_Make(REB_TUPLE, arg));
}
Exemplo n.º 9
0
int
ELFNAMEEND(loadfile)(int fd, Elf_Ehdr *elf, u_long *marks, int flags)
{
	Elf_Shdr *shp;
	Elf_Phdr *phdr;
	int i, j;
	ssize_t sz;
	int first;
	Elf_Addr shpp;
	Elf_Addr minp = ~0, maxp = 0, pos = 0, elfp = 0;
	u_long offset = marks[MARK_START];
	ssize_t nr;
	struct __packed {
		Elf_Nhdr	nh;
		uint8_t		name[ELF_NOTE_NETBSD_NAMESZ + 1];
		uint8_t		desc[ELF_NOTE_NETBSD_DESCSZ];
	} note;
	char *shstr = NULL;
	int boot_load_ctf = 1;

	/* some ports dont use the offset */
	(void)&offset;

	internalize_ehdr(elf->e_ident[EI_DATA], elf);

	sz = elf->e_phnum * sizeof(Elf_Phdr);
	phdr = ALLOC(sz);

	if (lseek(fd, elf->e_phoff, SEEK_SET) == -1)  {
		WARN(("lseek phdr"));
		goto freephdr;
	}
	nr = read(fd, phdr, sz);
	if (nr == -1) {
		WARN(("read program headers"));
		goto freephdr;
	}
	if (nr != sz) {
		errno = EIO;
		WARN(("read program headers"));
		goto freephdr;
	}

	for (first = 1, i = 0; i < elf->e_phnum; i++) {
		internalize_phdr(elf->e_ident[EI_DATA], &phdr[i]);

#ifndef MD_LOADSEG /* Allow processor ABI specific segment loads */
#define MD_LOADSEG(a) /*CONSTCOND*/0
#endif
		if (MD_LOADSEG(&phdr[i]))
			goto loadseg;

		if (phdr[i].p_type != PT_LOAD ||
		    (phdr[i].p_flags & (PF_W|PF_X)) == 0)
			continue;

#define IS_TEXT(p)	(p.p_flags & PF_X)
#define IS_DATA(p)	(p.p_flags & PF_W)
#define IS_BSS(p)	(p.p_filesz < p.p_memsz)
		/*
		 * XXX: Assume first address is lowest
		 */
		if ((IS_TEXT(phdr[i]) && (flags & LOAD_TEXT)) ||
		    (IS_DATA(phdr[i]) && (flags & LOAD_DATA))) {

		loadseg:
			if (marks[MARK_DATA] == 0 && IS_DATA(phdr[i]))
				marks[MARK_DATA] = LOADADDR(phdr[i].p_vaddr);

			/* Read in segment. */
			PROGRESS(("%s%lu", first ? "" : "+",
			    (u_long)phdr[i].p_filesz));

			if (lseek(fd, phdr[i].p_offset, SEEK_SET) == -1)  {
				WARN(("lseek text"));
				goto freephdr;
			}
			nr = READ(fd, phdr[i].p_vaddr, phdr[i].p_filesz);
			if (nr == -1) {
				WARN(("read text error"));
				goto freephdr;
			}
			if (nr != (ssize_t)phdr[i].p_filesz) {
				errno = EIO;
				WARN(("read text"));
				goto freephdr;
			}
			first = 0;

		}
		if ((IS_TEXT(phdr[i]) && (flags & (LOAD_TEXT|COUNT_TEXT))) ||
		    (IS_DATA(phdr[i]) && (flags & (LOAD_DATA|COUNT_TEXT)))) {
			pos = phdr[i].p_vaddr;
			if (minp > pos)
				minp = pos;
			pos += phdr[i].p_filesz;
			if (maxp < pos)
				maxp = pos;
		}

		/* Zero out bss. */
		if (IS_BSS(phdr[i]) && (flags & LOAD_BSS)) {
			PROGRESS(("+%lu",
			    (u_long)(phdr[i].p_memsz - phdr[i].p_filesz)));
			BZERO((phdr[i].p_vaddr + phdr[i].p_filesz),
			    phdr[i].p_memsz - phdr[i].p_filesz);
		}
		if (IS_BSS(phdr[i]) && (flags & (LOAD_BSS|COUNT_BSS))) {
			pos += phdr[i].p_memsz - phdr[i].p_filesz;
			if (maxp < pos)
				maxp = pos;
		}
	}
	DEALLOC(phdr, sz);

	/*
	 * Copy the ELF and section headers.
	 */
	maxp = roundup(maxp, ELFROUND);
	if (flags & (LOAD_HDR|COUNT_HDR)) {
		elfp = maxp;
		maxp += sizeof(Elf_Ehdr);
	}

	if (flags & (LOAD_SYM|COUNT_SYM)) {
		if (lseek(fd, elf->e_shoff, SEEK_SET) == -1)  {
			WARN(("lseek section headers"));
			return 1;
		}
		sz = elf->e_shnum * sizeof(Elf_Shdr);

		shp = ALLOC(sz);

		nr = read(fd, shp, sz);
		if (nr == -1) {
			WARN(("read section headers"));
			goto freeshp;
		}
		if (nr != sz) {
			errno = EIO;
			WARN(("read section headers"));
			goto freeshp;
		}

		shpp = maxp;
		maxp += roundup(sz, ELFROUND);

#ifndef _STANDALONE
		/* Internalize the section headers. */
		for (i = 0; i < elf->e_shnum; i++)
			internalize_shdr(elf->e_ident[EI_DATA], &shp[i]);
#endif /* ! _STANDALONE */

		/*
		 * First load the section names section.
		 */
		if (boot_load_ctf && (elf->e_shstrndx != 0)) {
			if (flags & LOAD_SYM) {
				if (lseek(fd, shp[elf->e_shstrndx].sh_offset,
				    SEEK_SET) == -1) {
					WARN(("lseek symbols"));
					goto freeshp;
				}
				nr = READ(fd, maxp,
				    shp[elf->e_shstrndx].sh_size);
				if (nr == -1) {
					WARN(("read symbols"));
					goto freeshp;
				}
				if (nr !=
				    (ssize_t)shp[elf->e_shstrndx].sh_size) {
					errno = EIO;
					WARN(("read symbols"));
					goto freeshp;
				}

				shstr = ALLOC(shp[elf->e_shstrndx].sh_size);
				if (lseek(fd, shp[elf->e_shstrndx].sh_offset,
				    SEEK_SET) == -1) {
					WARN(("lseek symbols"));
					goto freeshp;
				}
				nr = read(fd, shstr,
				    shp[elf->e_shstrndx].sh_size);
				if (nr == -1) {
					WARN(("read symbols"));
					goto freeshp;
				}
			}
			shp[elf->e_shstrndx].sh_offset = maxp - elfp;
			maxp += roundup(shp[elf->e_shstrndx].sh_size, ELFROUND);
		}

		/*
		 * Now load the symbol sections themselves.  Make sure
		 * the sections are aligned. Don't bother with any
		 * string table that isn't referenced by a symbol
		 * table.
		 */
		for (first = 1, i = 0; i < elf->e_shnum; i++) {
		    	if (i == elf->e_shstrndx) {
			    /* already loaded this section */
			    continue;
			}
			switch (shp[i].sh_type) {
			case SHT_PROGBITS:
			    	if (boot_load_ctf && shstr) {
					/* got a CTF section? */
					if (strncmp(".SUNW_ctf",
						    &shstr[shp[i].sh_name],
						    10) == 0) {
					    	goto havesym;
					}
				}

				/* Not loading this, so zero out the offset. */
				shp[i].sh_offset = 0;
			    	break;
			case SHT_STRTAB:
				for (j = 0; j < elf->e_shnum; j++)
					if (shp[j].sh_type == SHT_SYMTAB &&
					    shp[j].sh_link == (unsigned int)i)
						goto havesym;
				/* FALLTHROUGH */
			default:
				/* Not loading this, so zero out the offset. */
				shp[i].sh_offset = 0;
				break;
			havesym:
			case SHT_SYMTAB:
				if (flags & LOAD_SYM) {
					PROGRESS(("%s%ld", first ? " [" : "+",
					    (u_long)shp[i].sh_size));
					if (lseek(fd, shp[i].sh_offset,
					    SEEK_SET) == -1) {
						WARN(("lseek symbols"));
						goto freeshp;
					}
					nr = READ(fd, maxp, shp[i].sh_size);
					if (nr == -1) {
						WARN(("read symbols"));
						goto freeshp;
					}
					if (nr != (ssize_t)shp[i].sh_size) {
						errno = EIO;
						WARN(("read symbols"));
						goto freeshp;
					}
				}
				shp[i].sh_offset = maxp - elfp;
				maxp += roundup(shp[i].sh_size, ELFROUND);
				first = 0;
				break;
			case SHT_NOTE:
				if ((flags & LOAD_NOTE) == 0)
					break;
				if (shp[i].sh_size < sizeof(note)) {
					shp[i].sh_offset = 0;
					break;
				}
				if (lseek(fd, shp[i].sh_offset, SEEK_SET)
				    == -1) {
					WARN(("lseek note"));
					goto freeshp;
				}
				nr = read(fd, &note, sizeof(note));
				if (nr == -1) {
					WARN(("read note"));
					goto freeshp;
				}
				if (note.nh.n_namesz ==
				    ELF_NOTE_NETBSD_NAMESZ &&
				    note.nh.n_descsz ==
				    ELF_NOTE_NETBSD_DESCSZ &&
				    note.nh.n_type ==
				    ELF_NOTE_TYPE_NETBSD_TAG &&
				    memcmp(note.name, ELF_NOTE_NETBSD_NAME,
				    sizeof(note.name)) == 0) {
				    	memcpy(&netbsd_version, &note.desc,
				    	    sizeof(netbsd_version));
				}
				shp[i].sh_offset = 0;
				break;
			}
		}
		if (flags & LOAD_SYM) {
#ifndef _STANDALONE
			/* Externalize the section headers. */
			for (i = 0; i < elf->e_shnum; i++)
				externalize_shdr(elf->e_ident[EI_DATA],
				    &shp[i]);
#endif /* ! _STANDALONE */
			BCOPY(shp, shpp, sz);

			if (first == 0)
				PROGRESS(("]"));
		}
		DEALLOC(shp, sz);
	}
	
	if (shstr) {
	    DEALLOC(shstr, shp[elf->e_shstrndx].sh_size);
	}

	/*
	 * Frob the copied ELF header to give information relative
	 * to elfp.
	 */
	if (flags & LOAD_HDR) {
		elf->e_phoff = 0;
		elf->e_shoff = sizeof(Elf_Ehdr);
		elf->e_phentsize = 0;
		elf->e_phnum = 0;
		externalize_ehdr(elf->e_ident[EI_DATA], elf);
		BCOPY(elf, elfp, sizeof(*elf));
		internalize_ehdr(elf->e_ident[EI_DATA], elf);
	}

	marks[MARK_START] = LOADADDR(minp);
	marks[MARK_ENTRY] = LOADADDR(elf->e_entry);
	/*
	 * Since there can be more than one symbol section in the code
	 * and we need to find strtab too in order to do anything
	 * useful with the symbols, we just pass the whole elf
	 * header back and we let the kernel debugger find the
	 * location and number of symbols by itself.
	 */
	marks[MARK_NSYM] = 1;	/* XXX: Kernel needs >= 0 */
	marks[MARK_SYM] = LOADADDR(elfp);
	marks[MARK_END] = LOADADDR(maxp);
	return 0;
freephdr:
	DEALLOC(phdr, sz);
	return 1;
freeshp:
	DEALLOC(shp, sz);
	return 1;
}
Exemplo n.º 10
0
//
//  Call_Core: C
//
// flags:
//     1: wait, is implied when I/O redirection is enabled
//     2: console
//     4: shell
//     8: info
//     16: show
//
// Return -1 on error, otherwise the process return code.
//
// POSIX previous simple version was just 'return system(call);'
// This uses 'execvp' which is "POSIX.1 conforming, UNIX compatible"
//
REB_R Call_Core(REBFRM *frame_) {
    PROCESS_INCLUDE_PARAMS_OF_CALL_INTERNAL_P;

    UNUSED(REF(console));  // !!! actually not paid attention to, why?

    // SECURE was never actually done for R3-Alpha
    //
    Check_Security(Canon(SYM_CALL), POL_EXEC, ARG(command));

    // Make sure that if the output or error series are STRING! or BINARY!,
    // they are not read-only, before we try appending to them.
    //
    if (IS_TEXT(ARG(output)) or IS_BINARY(ARG(output)))
        FAIL_IF_READ_ONLY(ARG(output));
    if (IS_TEXT(ARG(error)) or IS_BINARY(ARG(error)))
        FAIL_IF_READ_ONLY(ARG(error));

    char *inbuf;
    size_t inbuf_size;

    if (not REF(input)) {
      null_input_buffer:
        inbuf = nullptr;
        inbuf_size = 0;
    }
    else switch (VAL_TYPE(ARG(input))) {
      case REB_LOGIC:
        goto null_input_buffer;

      case REB_TEXT: {
        inbuf_size = rebSpellIntoQ(nullptr, 0, ARG(input), rebEND);
        inbuf = rebAllocN(char, inbuf_size);
        size_t check;
        check = rebSpellIntoQ(inbuf, inbuf_size, ARG(input), rebEND);
        UNUSED(check);
        break; }

      case REB_FILE: {
        size_t size;
        inbuf = s_cast(rebBytes(  // !!! why fileNAME size passed in???
            &size,
            "file-to-local", ARG(input),
            rebEND
        ));
        inbuf_size = size;
        break; }

      case REB_BINARY: {
        inbuf = s_cast(rebBytes(&inbuf_size, ARG(input), rebEND));
        break; }

      default:
        panic (ARG(input));  // typechecking should not have allowed it
    }

    bool flag_wait;
    if (
        REF(wait)
        or (
            IS_TEXT(ARG(input)) or IS_BINARY(ARG(input))
            or IS_TEXT(ARG(output)) or IS_BINARY(ARG(output))
            or IS_TEXT(ARG(error)) or IS_BINARY(ARG(error))
        ) // I/O redirection implies /WAIT
    ){
        flag_wait = true;
    }
    else
        flag_wait = false;

    // We synthesize the argc and argv from the "command", and in the process
    // we do dynamic allocations of argc strings through the API.  These need
    // to be freed before we return.
    //
    char *cmd;
    int argc;
    const char **argv;

    if (IS_TEXT(ARG(command))) {
        //
        // !!! POSIX does not offer the ability to take a single command
        // line string when invoking a process.  You have to use an argv[]
        // array.  The only workaround to this is to run through a shell--
        // but that would give you a new environment.  We only parse the
        // command line if forced (Windows can call with a single command
        // line, but has the reverse problem: it has to make the command
        // line out of argv[] parts if you pass an array).
        //
        if (not REF(shell)) {
            REBVAL *block = rebValue(
                "parse-command-to-argv*", ARG(command), rebEND
            );
            Move_Value(ARG(command), block);
            rebRelease(block);
            goto block_command;
        }

        cmd = rebSpell(ARG(command), rebEND);

        argc = 1;
        argv = rebAllocN(const char*, (argc + 1));

        // !!! Make two copies because it frees cmd and all the argv.  Review.
        //
        argv[0] = rebSpell(ARG(command), rebEND);
        argv[1] = nullptr;
    }
    else if (IS_BLOCK(ARG(command))) {