Example #1
0
int
cmd_execbg (Shell *shell, void *args)
{
	if (array_is_empty (args))
	{
		fprintf (stderr, "The command execbg expects at least one argument.\n");
		return -1;
	}

	return execute (array_get (args, 0), args, EXEC_BG, NULL);
}
Example #2
0
int
cmd_sdc (Shell *s, void *args)
{
	if (array_is_empty (args))
	{
		fprintf (stderr, "The command sdc expects at least one argument.\n");
		return -1;
	}

	shell_set_default_command (s, array_get (args, 0));
	return 0;
}
Example #3
0
int
cmd_exec (Shell *shell, void *args)
{
	if (array_is_empty (args))
	{
		fprintf (stderr, "The command exec expects at least one argument.\n");
		return -1;
	}

	execute (array_get (args, 0), args, EXEC_REPLACE, NULL);
	error (0, errno, "Error");
	return -1;
}
Example #4
0
int
cmd_help (Shell *shell, void *args)
{
	if (array_is_empty (args))
	{
		printf ("Available commands:\n");

		const Array *a = shell_get_commands (shell);
		for (size_t i = 0, n = array_get_size (a); i < n; ++i)
		{
			const command_t *command = array_get (a, i);
			printf ("  %s\n", command->name);

		}
		return 0;
	}

	int return_value = 0;
	for (size_t i = 0, n = array_get_size (args); i < n; ++i)
	{
		const char *name = array_get (args, i);
		const command_t *p = shell_get_command (shell, name);
		if (!p) // Command not found.
		{
			fprintf (stderr, "No command \"%s\" found.\n", name);
			--return_value;
		}
		else
		{
			printf ("- %s: %s", name, name);
			if (p->args_list)
			{
				printf (" %s", p->args_list);
			}
			printf ("\n  ");
			if (p->help)
			{
				printf ("%s", p->help);
			}
			else
			{
				printf ("%s", "No help available for this command.");
			}
			printf ("\n");
		}
	}
	return return_value;
}
Example #5
0
int
cmd_history (Shell *shell, void *args)
{
	if (array_is_empty (args))
	{
		fprintf (stderr, "The command history expects at least one argument.\n");
		return -1;
	}
	const char *opt = array_get (args, 0);
	if (0 == strcmp ("-c", opt))
	{
		clear_history ();
		return 0;
	}
	return -1;
}
Example #6
0
int
cmd_execfg (Shell *shell, void *args)
{
	if (array_is_empty (args))
	{
		fprintf (stderr, "The command execfg expects at least one argument.\n");
		return -1;
	}

	int status;
	if (-1 == execute (array_get (args, 0), args, EXEC_FG, &status))
	{
		fprintf (stderr, "fork () failed.\n");
		return -1;
	}
	return status;
}
Example #7
0
int
cmd_version (Shell *shell, void *args)
{
	if (!array_is_empty (args))
	{
		const char *arg = array_get (args, 0);
		if (0 == strcmp ("-v", arg))
		{
			printf ("%s\n", get_prog_version ());
			return 0;
		}
		else if (0 == strcmp ("-n", arg))
		{
			printf ("%s\n", get_prog_version_name ());
			return 0;
		}
	}
	print_version ();
	return 0;
}
Example #8
0
int ArrayMain(void)
{
	int sum[] = { 1,2,3,4,5,6,7,8,9 };
	struct Array tmp;
	int *ret;
	int *ret2;
	int *ret3;
	int *ret4;

	array_init(&tmp, 128);
	
	/* add an element and get it */
	array_insert_rear(&tmp, sum);
	ret = array_get_head(&tmp);
	printf("%d(should be 1)\n", *ret);
	
	/* array is 2 1 3 */
	array_insert_head(&tmp, sum + 1);
	array_insert_rear(&tmp, sum + 2);
	ret2 = array_get_rear(&tmp);
	printf("%d (should be 3)\n", *ret2);

	/* array is 4 1 3 */
	array_set_by_index(&tmp, sum + 3, 0);
	ret3 = array_get_head(&tmp);
	printf("%d(should be 4)\n", *ret3);

	/* array is 1 3 */
	array_remove_head(&tmp);
	printf("%d(should be 2)\n", array_get_length(&tmp));

	while (!array_is_empty(&tmp))
	{
		ret4 = array_get_head(&tmp);
		printf("%d ", *ret4);
		array_remove_head(&tmp);
	}
	printf("(should be 1 3)\n");
	return 0;
}
Example #9
0
int
cmd_setenv (Shell *shell, void *args)
{
	if (array_is_empty (args))
	{
		char **p = environ;
		while (*p)
		{
			printf ("%s\n", *p);
			++p;
		}
	}
	else
	{
		for (size_t i = 0, n = array_get_size (args); i < n; ++i)
		{
			putenv (strdup (array_get (args, i)));
		}
	}

	return 0;
}
Example #10
0
int
cmd_cd (Shell *shell, void *args)
{
	char *new_pwd;
	if (!array_is_empty (args))
	{
		if (0 == strcmp ("-", array_get (args, 0)))
		{
			if ( (new_pwd = getenv ("OLDPWD")) )
			{
				new_pwd = strdup (new_pwd);
			}
			else
			{
				fprintf (stderr, "Failed to get previous directory.\n");
				return -1;
			}
		}
		else
		{
			new_pwd = strdup (array_get (args, 0));
		}
	}
	else if (!get_home_dir ())
	{
		fprintf (stderr, "Failed to get home directory.\n");
		return -1;
	}
	else
	{
		new_pwd = strdup (get_home_dir ());
	}

	char *old_pwd = get_cwd ();
	if (0 != chdir (new_pwd))
	{
		fprintf (stderr, "Failed to change directory to \"%s\".\n", new_pwd);
		return -1;
	}
	// Because new_cwd does not contain an absolute path.
	free (new_pwd);

	if (old_pwd)
	{
		setenv ("OLDPWD", old_pwd, 1);
		free (old_pwd);
	}
	else
	{
		unsetenv ("OLDPWD");
	}

	if ( (new_pwd = get_cwd ()) )
	{
		setenv ("PWD", new_pwd, 1);
		free (new_pwd);
	}
	else
	{
		unsetenv ("PWD");
	}

	return 0;
}
Example #11
0
enum dsc_image_parse_result
dsc_image_parse(struct tbd_create_info *const info_in,
                struct dyld_shared_cache_info *const dsc_info,
                struct dyld_cache_image_info *const image,
                const uint64_t macho_options,
                const uint64_t tbd_options,
                __unused const uint64_t options)
{
    /*
     * The mappings store the data-structures that make up a mach-o file for all
     * dyld_shared_cache images.
     *
     * To find out image's data, we have to recurse the mappings, to find the
     * one containing our file.
     */

    uint64_t max_image_size = 0;
    const uint64_t file_offset =
        get_image_file_offset_from_address(dsc_info,
                                           image->address,
                                           &max_image_size);

    if (file_offset == 0) {
        return E_DSC_IMAGE_PARSE_NO_CORRESPONDING_MAPPING;
    }

    if (max_image_size < sizeof(struct mach_header)) {
        return E_DSC_IMAGE_PARSE_SIZE_TOO_SMALL;
    }

    const uint8_t *const map = dsc_info->map;
    const struct mach_header *const header =
        (const struct mach_header *)(map + file_offset);

    const uint32_t magic = header->magic;

    const bool is_64 = magic == MH_MAGIC_64 || magic == MH_CIGAM_64;
    const bool is_big_endian = magic == MH_CIGAM || magic == MH_CIGAM_64;

    if (is_64) {
        if (max_image_size < sizeof(struct mach_header_64)) {
            return E_DSC_IMAGE_PARSE_SIZE_TOO_SMALL;
        }
    } else {
        const bool is_fat =
            magic == FAT_MAGIC || magic == FAT_MAGIC_64 ||
            magic == FAT_CIGAM || magic == FAT_CIGAM_64;

        if (is_fat) {
            return E_DSC_IMAGE_PARSE_FAT_NOT_SUPPORTED;
        }

        if (!is_big_endian && magic != MH_MAGIC) {
            return E_DSC_IMAGE_PARSE_NOT_A_MACHO;
        }
    }

    const uint32_t flags = header->flags;
    if (flags & MH_TWOLEVEL) {
        info_in->flags_field |= TBD_FLAG_FLAT_NAMESPACE;
    }

    if (!(flags & MH_APP_EXTENSION_SAFE)) {
        info_in->flags_field |= TBD_FLAG_NOT_APP_EXTENSION_SAFE;
    }

    struct symtab_command symtab = {};

    /*
     * The symbol-table and string-table offsets are absolute, not relative from
     * image's base, but we still need to account for shared-cache's start and
     * size.
     *
     * To accomplish this, we parse the symbol-table separately.
     *
     * The section's offset are also absolute (relative to the map, not to the
     * header).
     */

    const uint64_t arch_bit = dsc_info->arch_bit;
    const uint64_t lc_options =
        O_MACHO_FILE_PARSE_DONT_PARSE_SYMBOL_TABLE |
        O_MACHO_FILE_PARSE_SECT_OFF_ABSOLUTE |
        macho_options;

    struct mf_parse_load_commands_from_map_info info = {
        .map = map,
        .map_size = dsc_info->size,

        .macho = (const uint8_t *)header,
        .macho_size = max_image_size,

        .arch = dsc_info->arch,
        .arch_bit = arch_bit,

        .available_map_range = dsc_info->available_range,

        .is_64 = is_64,
        .is_big_endian = is_big_endian,

        .ncmds = header->ncmds,
        .sizeofcmds = header->sizeofcmds,

        .tbd_options = tbd_options,
        .options = lc_options
    };

    const enum macho_file_parse_result parse_load_commands_result =
        macho_file_parse_load_commands_from_map(info_in, &info, &symtab);

    if (parse_load_commands_result != E_MACHO_FILE_PARSE_OK) {
        return translate_macho_file_parse_result(parse_load_commands_result);
    }

    /*
     * If symtab is invalid, we can simply assume that no symbol-table was
     * found, but that this was ok from the options as
     * macho_file_parse_load_commands_from_map didn't return an error-code.
     */

    if (symtab.cmd != LC_SYMTAB) {
        return E_DSC_IMAGE_PARSE_OK;
    }

    /*
     * For parsing the symbol-tables, we provide the full dyld_shared_cache map
     * as the symbol-table and string-table offsets are relative to the full
     * map, not relative to the mach-o header.
     */

    enum macho_file_parse_result ret = E_MACHO_FILE_PARSE_OK;
    if (is_64) {
        ret =
            macho_file_parse_symbols_64_from_map(info_in,
                                                 map,
                                                 dsc_info->available_range,
                                                 arch_bit,
                                                 is_big_endian,
                                                 symtab.symoff,
                                                 symtab.nsyms,
                                                 symtab.stroff,
                                                 symtab.strsize,
                                                 tbd_options);
    } else {
        ret =
            macho_file_parse_symbols_from_map(info_in,
                                              map,
                                              dsc_info->available_range,
                                              arch_bit,
                                              is_big_endian,
                                              symtab.symoff,
                                              symtab.nsyms,
                                              symtab.stroff,
                                              symtab.strsize,
                                              tbd_options);
    }

    if (ret != E_MACHO_FILE_PARSE_OK) {
        return translate_macho_file_parse_result(ret);
    }

    if (!(tbd_options & O_TBD_PARSE_IGNORE_MISSING_EXPORTS)) {
        if (array_is_empty(&info_in->exports)) {
            return E_DSC_IMAGE_PARSE_NO_EXPORTS;
        }
    }

    info_in->archs = arch_bit;
    info_in->archs_count = 1;
    info_in->flags |= F_TBD_CREATE_INFO_EXPORTS_HAVE_FULL_ARCHS;

    return E_DSC_IMAGE_PARSE_OK;
}