Esempio n. 1
0
static char *cleanse_path(char *inpath)
{
	char *newpath;

	// Remove "." and ".."
	newpath = malloc(strlen(inpath));
	memcpy(newpath, "/", 2);

	char *token;
	char *remainder = inpath;
	while ((token = strsep(&remainder, "/"))) {
		if (token[0] == 0 || str_is_equal(token, ".")) {
			continue;
		}
		else if (str_is_equal(token, "..")) {
			char *lastslash = strrchr(newpath, '/');
			if (lastslash > newpath)
				*lastslash = 0;
			else
				newpath[1] = 0;
		}
		else {
			if (strlen(newpath) > 1)
				strcat(newpath, "/");
			strcat(newpath, token);
		}
	}
	free(inpath);

	return newpath;
}
Esempio n. 2
0
static afc_error_t remove_path(char *path, bool recurse)
{
	afc_error_t result;
	char **infolist = NULL;
	bool is_dir;

	result = afc_get_file_info(afc, path, &infolist);

	if (result != AFC_E_SUCCESS) {
		if (result != AFC_E_OBJECT_NOT_FOUND)
			afc_warn(result, "%s: stat failed: %s", __func__, path);
		return result;
	}

	if (recurse && is_directory(path, &is_dir) == AFC_E_SUCCESS && is_dir) {
		char **list = NULL;

		result = afc_read_directory(afc, path, &list);
		if (result != AFC_E_SUCCESS) {
			afc_warn(result, "%s", path);
			return result;
		}

		for (int i = 0; list[i] && result == AFC_E_SUCCESS; i++) {
			if (str_is_equal(list[i], "."))
				; // NOP
			else if (str_is_equal(list[i], ".."))
				; // NOP
			else {
				char *subdir_path;
				if (asprintf(&subdir_path, "%s/%s", path, list[i]) > 0) {
					result = remove_path(subdir_path, recurse);
					free(subdir_path);
				}
				else {
					warn("%s: %s", __func__, "asprintf");
				}
			}
			free(list[i]);
		}
		free(list);
	}

	if (recurse)
		printf("removing: %s\n", path);

	result = afc_remove_path(afc, path);

	if (result != AFC_E_SUCCESS)
		afc_warn(result, "%s", path);

	return result;
}
Esempio n. 3
0
static afc_error_t cmd_mv(int argc, const char *argv[])
{
	afc_error_t result;
	const char *filename;
	char *source_path, *target_path;
	char **infolist;
	bool target_is_dir;

	if (argc != 2) {
		warnx("usage: mv <source> <target>");
		return -1;
	}
	source_path = build_absolute_path(argv[0]);
	target_path = build_absolute_path(argv[1]);

	if (source_path && target_path) {

		result = afc_get_file_info(afc, target_path, &infolist);
		if (result == AFC_E_SUCCESS) {
			for (int i = 0; infolist[i] != NULL; i++) {
				if (str_is_equal(infolist[i], "st_ifmt"))
					target_is_dir = str_is_equal(infolist[i+1], "S_IFDIR");
				free(infolist[i]);
			}
			free(infolist);

			if (target_is_dir) {
				filename = basename((char *) argv[0]);
				target_path = realloc(target_path, strlen(filename) + 2);
				strcat(target_path, "/");
				strcat(target_path, filename);
				result = AFC_E_SUCCESS;
			}
		}
		else if (result == AFC_E_OBJECT_NOT_FOUND) {
			result = AFC_E_SUCCESS;
		}

		if (result == AFC_E_SUCCESS) {
			result = afc_rename_path(afc, source_path, target_path);
			if (result != AFC_E_SUCCESS)
				afc_warn(result, "rename %s", argv[0]);
		}
	}
	else {
		result = AFC_E_INTERNAL_ERROR;
	}
	free(source_path);
	free(target_path);

	return result;
}
Esempio n. 4
0
void
_xfce_rc_simple_delete_group (XfceRc      *rc,
                              const gchar *name,
                              gboolean     global)
{
  XfceRcSimple *simple = XFCE_RC_SIMPLE (rc);
  Group        *group;
  Entry        *entry;
  Entry        *next;

  if (name == NULL)
    name = NULL_GROUP;

  for (group = simple->gfirst; group != NULL; group = group->next)
    {
      if (str_is_equal (group->name, name))
        {
          if (simple->group == group || str_is_equal (name, NULL_GROUP))
            {
              /* don't delete current group or the default group, just clear them */
              for (entry = group->efirst; entry != NULL; entry = next)
                {
                  next = entry->next;
                  simple_entry_free (entry);
                }
              group->efirst = group->elast = NULL;
            }
          else
            {
              /* unlink group from group list */
              if (group->prev != NULL)
                group->prev->next = group->next;
              else
                simple->gfirst = group->next;
              if (group->next != NULL)
                group->next->prev = group->prev;
              else
                simple->glast = group->prev;

              /* delete this group */
              simple_group_free (group);
            }

          simple->dirty = TRUE;
          break;
        }
    }
}
Esempio n. 5
0
void
_xfce_rc_simple_delete_entry (XfceRc      *rc,
                              const gchar *key,
                              gboolean     global)
{
  XfceRcSimple *simple = XFCE_RC_SIMPLE (rc);
  Entry        *entry;

  for (entry = simple->group->efirst; entry != NULL; entry = entry->next)
    {
      if (str_is_equal (entry->key, key))
        {
          if (entry->prev != NULL)
            entry->prev->next = entry->next;
          else
            simple->group->efirst = entry->next;

          if (entry->next != NULL)
            entry->next->prev = entry->prev;
          else
            simple->group->elast = entry->prev;

          /* delete this entry */
          simple_entry_free (entry);

          simple->dirty = TRUE;
          break;
        }
    }
}
Esempio n. 6
0
static afc_error_t cmd_rm(int argc, const char *argv[])
{
	afc_error_t result;
	char *path = NULL;
	bool recurse = false;

	if (argc < 1) {
		warnx("usage: rm [-r] <file> ...");
		return AFC_E_INVALID_ARG;
	}

	if (argc > 1 && (recurse = str_is_equal("-r", argv[0]))) {
		argc--;
		argv++;
	}

	for (int i = 0; i < argc; i++) {

		path = build_absolute_path(argv[i]);
		if (!path)
			return AFC_E_INTERNAL_ERROR;

		result = remove_path(path, recurse);
		free(path);
		if (result == AFC_E_OBJECT_NOT_FOUND)
			afc_warn(result, "%s", argv[i]);
		return  result;
	}

	return AFC_E_SUCCESS;
}
Esempio n. 7
0
static Group*
simple_add_group (XfceRcSimple *simple,
                  const gchar  *name)
{
  Group *group;

  for (group = simple->gfirst; group != NULL; group = group->next)
    if (str_is_equal (group->name, name))
      return group;

  group         = g_slice_new (Group);
  group->name   = g_string_chunk_insert (simple->string_chunk, name);
  group->efirst = NULL;
  group->elast  = NULL;

  if (G_UNLIKELY (simple->gfirst == NULL))
    {
      group->next = group->prev = NULL;
      simple->gfirst = simple->glast = group;
    }
  else
    {
      group->next = NULL;
      group->prev = simple->glast;
      simple->glast->next = group;
      simple->glast = group;
    }

  return group;
}
Esempio n. 8
0
const gchar*
_xfce_rc_simple_get_group (const XfceRc *rc)
{
  const XfceRcSimple *simple = XFCE_RC_SIMPLE_CONST (rc);

  if (str_is_equal (simple->group->name, NULL_GROUP))
    return NULL;
  else
    return simple->group->name;
}
Esempio n. 9
0
void
_xfce_rc_simple_set_group (XfceRc      *rc,
                           const gchar *name)
{
  XfceRcSimple *simple = XFCE_RC_SIMPLE (rc);

  if (name == NULL)
    name = NULL_GROUP;

  if (!str_is_equal (simple->group->name, name))
    simple->group = simple_add_group (simple, name);
}
Esempio n. 10
0
static gboolean
simple_write (XfceRcSimple *simple, const gchar *filename)
{
  LEntry *lentry;
  Entry  *entry;
  Group  *group;
  gchar   buffer[LINE_MAX];
  FILE   *fp;

  fp = fopen (filename, "w");
  if (G_UNLIKELY (fp == NULL))
    {
      g_critical ("Unable to open file %s for writing: %s", filename, g_strerror (errno));
      return FALSE;
    }

  for (group = simple->gfirst; group != NULL; group = group->next)
    {
      /* don't store empty groups */
      if (group->efirst == NULL)
        continue;

      /* NULL_GROUP has no header */
      if (!str_is_equal (group->name, NULL_GROUP))
        fprintf (fp, "[%s]\n", group->name);

      for (entry = group->efirst; entry != NULL; entry = entry->next)
        {
          simple_escape (buffer, LINE_MAX, entry->value);
          fprintf (fp, "%s=%s\n", entry->key, buffer);

          for (lentry = entry->lfirst; lentry != NULL; lentry = lentry->next)
            {
              simple_escape (buffer, LINE_MAX, lentry->value);
              fprintf (fp, "%s[%s]=%s\n", entry->key, lentry->locale, buffer);
            }
        }

      fprintf (fp, "\n");
    }

  if (ferror (fp))
    {
      g_critical ("Unable to write to file %s: Unexpected internal error", filename);
      fclose (fp);
      unlink (filename);
      return FALSE;
    }

  fclose (fp);
  return TRUE;
}
Esempio n. 11
0
static char * infolist_get_value(char **infolist, char *property)
{
	char *value = NULL;

	for (int j = 0; infolist[j] != NULL; j += 2)
	{
		if (str_is_equal(property, infolist[j])) {
			value = infolist[j+1];
			break;
		}
	}
	return value;
}
Esempio n. 12
0
gboolean
_xfce_rc_simple_has_entry (const XfceRc *rc,
                           const gchar  *key)
{
  const XfceRcSimple *simple = XFCE_RC_SIMPLE_CONST (rc);
  const Entry        *entry;

  for (entry = simple->group->efirst; entry != NULL; entry = entry->next)
    if (str_is_equal (entry->key, key))
      break;

  return entry != NULL;
}
Esempio n. 13
0
const gchar*
_xfce_rc_simple_read_entry (const XfceRc *rc,
                            const gchar  *key,
                            gboolean      translated)
{
  const XfceRcSimple *simple = XFCE_RC_SIMPLE_CONST (rc);
  LEntry             *lentry;
  Entry              *entry;
  const gchar        *best_value;
  guint               best_match;
  guint               match;

  for (entry = simple->group->efirst; entry != NULL; entry = entry->next)
    if (str_is_equal (entry->key, key))
      break;

  if (G_LIKELY (entry != NULL))
    {
      /* check for localized entry (best fit!) */
      if (G_LIKELY (translated && rc->locale != NULL))
        {
          best_match = XFCE_LOCALE_NO_MATCH;
          best_value = NULL;

          for (lentry = entry->lfirst; lentry != NULL; lentry = lentry->next)
            {
              match = xfce_locale_match (rc->locale, lentry->locale);
              if (match == XFCE_LOCALE_FULL_MATCH)
                {
                  /* FULL MATCH */
                  return lentry->value;
                }
              else if (match > best_match)
                {
                  best_match = match;
                  best_value = lentry->value;
                }
            }

          if (best_value != NULL)
            return best_value;

          /* FALL-THROUGH */
        }

      return entry->value;
    }

  return NULL;
}
Esempio n. 14
0
static char *build_absolute_path(const char *inpath)
{
	char *path;

	if (inpath[0] == '/')
		path = strdup(inpath);
	else {
		if (asprintf(&path, "%s/%s", str_is_equal(cwd, "/") ? "" : cwd, inpath) == -1) {
			warn("asprintf");
			return NULL;
		}
	}
	for (int i = strlen(path); i > 1 && path[i] == '/'; i--)
		path[i] = 0;

	return path;
}
Esempio n. 15
0
gboolean
_xfce_rc_simple_has_group (const XfceRc *rc,
                           const gchar  *name)
{
  const XfceRcSimple *simple = XFCE_RC_SIMPLE_CONST (rc);
  const Group        *group;

  /* the NULL group always exists */
  if (name == NULL)
    return TRUE;

  for (group = simple->gfirst; group != NULL; group = group->next)
    if (str_is_equal (group->name, name))
      break;

  return group != NULL;
}
Esempio n. 16
0
static afc_error_t cmd_ln(int argc, const char *argv[])
{
	afc_error_t result;
	int type = AFC_HARDLINK;
	char *source_path = NULL;
	char *target_path = NULL;

	if (argc == 3 && str_is_equal("-s", argv[0])) {
		type = AFC_SYMLINK;
		argc--;
		argv++;
	}
	if (argc != 2) {
		warnx("usage: ln [-s] <source> <target>");
		return AFC_E_INVALID_ARG;
	}

	if (type == AFC_HARDLINK)
		source_path = build_absolute_path(argv[0]);
	else
		source_path = strdup(argv[0]);

	target_path = build_absolute_path(argv[1]);

	if (!source_path || !target_path) {
		free(source_path);
		free(target_path);
		return AFC_E_INTERNAL_ERROR;
	}

//	warnx("%s: %s -> %s\n", type == AFC_HARDLINK ? "hard link" : "sym link", source_path, target_path);

	result = afc_make_link(afc, type, source_path, target_path);
	if (result == AFC_E_OBJECT_NOT_FOUND)
		afc_warn(result, "%s", argv[0]);
	else if (result != AFC_E_SUCCESS)
		afc_warn(result, "afc_make_link");

	free(source_path);
	free(target_path);

	return result;
}
Esempio n. 17
0
static afc_error_t is_directory(char *path, bool *is_dir)
{
	afc_error_t result;
	char **infolist = NULL;
	char *value;

	result = afc_get_file_info(afc, path, &infolist);

	if (result != AFC_E_SUCCESS) {
		if (result != AFC_E_OBJECT_NOT_FOUND)
			afc_warn(result, "%s: stat failed: %s", __func__, path);
		return result;
	}

	if ((value = infolist_get_value(infolist, "st_ifmt")))
		*is_dir = str_is_equal(value, "S_IFDIR");

	infolist_free(infolist);

	return result;
}
Esempio n. 18
0
static int str_to_cmd(const char *str)
{
	if (str_is_equal(str, "-"))
		return CMD_INTERACTIVE;
	else if (str_is_equal(str, "cd"))
		return CMD_CD;
	else if (str_is_equal(str, "pwd"))
		return CMD_PWD;
	else if (str_is_equal(str, "ls"))
		return CMD_LS;
	else if (str_is_equal(str, "mkdir"))
		return CMD_MKDIR;
	else if (str_is_equal(str, "ln"))
		return CMD_LN;
	else if (str_is_equal(str, "rm"))
		return CMD_RM;
	else if (str_is_equal(str, "mv"))
		return CMD_MV;
	else if (str_is_equal(str, "cp"))
		return CMD_CP;
	else if (str_is_equal(str, "cat"))
		return CMD_CAT;
	else if (str_is_equal(str, "stat"))
		return CMD_STAT;
	else if (str_is_equal(str, "quit"))
		return CMD_QUIT;

	return CMD_UNKNOWN;
}
Esempio n. 19
0
int main(int argc, const char **argv)
{
	char *errmsg = "";
	idevice_t device = NULL;
	lockdownd_client_t client = NULL;
	lockdownd_service_descriptor_t service = NULL;
	house_arrest_client_t hac = NULL;
	const char *service_name = "com.apple.afc";
    const char *appid = NULL;
	char *device_name = NULL;
	int result = 0;
	char* udid = NULL;
	int cmd = CMD_INTERACTIVE;
	const char *cmdstr = NULL;
	int i;

	cwd = strdup("/");

	/* parse cmdline args */
	for (i = 1; i < argc; i++) {
		if (str_is_equal(argv[i], "-d") || str_is_equal(argv[i], "--debug")) {
			idevice_set_debug_level(1);
			continue;
		}
		else if (str_is_equal(argv[i], "-u") || str_is_equal(argv[i], "--udid")) {
			i++;
			if (!argv[i] || (strlen(argv[i]) != 40)) {
				print_usage(argc, argv);
				exit(EXIT_FAILURE);
			}
			udid = strdup(argv[i]);
			continue;
		}
		else if (str_is_equal(argv[i], "-2") || str_is_equal(argv[i], "--afc2")) {
			service_name = "com.apple.afc2";
			continue;
		}
        else if (str_is_equal(argv[i], "-a") || str_is_equal(argv[i], "--appid")) {
            if (++i >=  argc) {
                print_usage(argc, argv);
                exit(EXIT_FAILURE);
            }
            appid = argv[i];
        }
		else if (str_is_equal(argv[i], "-h") || str_is_equal(argv[i], "--help")) {
			print_usage(argc, argv);
			exit(EXIT_SUCCESS);
		}
		else if ((cmd = str_to_cmd(argv[i])) != CMD_UNKNOWN) {
			cmdstr = argv[i];
			i++;
			break;
		}
	}
	argc -= i;
	argv += i;

	/* Connect to device */
	if (udid) {
		result = idevice_new(&device, udid);
		if (result != IDEVICE_E_SUCCESS)
			errx(EXIT_FAILURE, "No device found with udid %s, is it plugged in?", udid);
	}
	else {
		result = idevice_new(&device, NULL);
		if (result != IDEVICE_E_SUCCESS)
			errx(EXIT_FAILURE, "No device found, is it plugged in?");
		idevice_get_udid(device, &udid);
	}

	/* Connect to lockdownd */
	result = lockdownd_client_new_with_handshake(device, &client, "afccl");
	if (result != LOCKDOWN_E_SUCCESS) {
		asprintf(&errmsg, "ERROR: Connecting to lockdownd service failed!");
		goto bail;
	}

	result = lockdownd_get_device_name(client, &device_name);
	if ((result != LOCKDOWN_E_SUCCESS) || !device_name) {
		asprintf(&errmsg, "ERROR: Could not get device name!");
		goto bail;
	}

    if (appid) {
        result = lockdownd_start_service(client, "com.apple.mobile.house_arrest", &service);
        if (result != LOCKDOWN_E_SUCCESS || !service || !service->port) {
			asprintf(&errmsg, "error starting house arrest service: (%d) %s", result, afc_strerror(result));
			goto bail;
        }
        if (client) {
            lockdownd_client_free(client);
            client = NULL;
        }
        
        if (house_arrest_client_new(device, service, &hac) != HOUSE_ARREST_E_SUCCESS) {
            asprintf(&errmsg, "could not connect to house_arrest service!\n");
			goto bail;
        }
        
        if (service) {
            lockdownd_service_descriptor_free(service);
            service = NULL;
        }
        
        result = house_arrest_send_command(hac, "VendDocuments", appid);
        if (result != HOUSE_ARREST_E_SUCCESS) {
            asprintf(&errmsg, "error %d when trying to get VendDocuments\n", result);
			goto bail;
        }
        
        plist_t dict = NULL;
        if (house_arrest_get_result(hac, &dict) != HOUSE_ARREST_E_SUCCESS) {
            if (house_arrest_get_result(hac, &dict) != HOUSE_ARREST_E_SUCCESS) {
                asprintf(&errmsg, "hmmm....\n");
				goto bail;
            }
        }
        
        plist_t node = plist_dict_get_item(dict, "Error");
        if (node) {
            char *str = NULL;
            plist_get_string_val(node, &str);
            asprintf(&errmsg, "Error: %s\n", str);
            if (str) free(str);
            plist_free(dict);
            dict = NULL;
			goto bail;
		}
        node = plist_dict_get_item(dict, "Status");
        if (node) {
            char *str = NULL;
            plist_get_string_val(node, &str);
            if (str && (strcmp(str, "Complete") != 0)) {
                printf("Warning: Status is not 'Complete' but '%s'\n", str);
            }
            if (str) free(str);
        }
        if (dict) {
            plist_free(dict);
        }
        
        afc_error_t ae = afc_client_new_from_house_arrest_client(hac, &afc);
        if (ae != AFC_E_SUCCESS) {
            printf("afc error %d\n", ae);
        }

    }
    else {
        result = lockdownd_start_service(client, service_name, &service);
        if (result != LOCKDOWN_E_SUCCESS || !service || !service->port) {
            asprintf(&errmsg, "error starting AFC service: (%d) %s", result, afc_strerror(result));
			goto bail;
        }

        /* Connect to AFC */
        result = afc_client_new(device, service, &afc);
        lockdownd_client_free(client);
        idevice_free(device);
        if (result != AFC_E_SUCCESS) {
            errx(EXIT_FAILURE, "AFC connection failed (%d) %s", result, afc_strerror(result));
        }
	}
	result = do_cmd(cmd, argc, argv);

	if (hac)
		house_arrest_client_free(hac);

	afc_client_free(afc);

	exit(result == 0 ? EXIT_SUCCESS : EXIT_FAILURE);
    
bail:
    if (hac)
		house_arrest_client_free(hac);

	if (service)
		lockdownd_service_descriptor_free(service);

    if (client)
		lockdownd_client_free(client);

    if (device)
		idevice_free(device);

	errx(EXIT_FAILURE, "%s", errmsg);
}
Esempio n. 20
0
static Entry*
simple_add_entry (XfceRcSimple *simple,
                  const gchar  *key,
                  const gchar  *value,
                  const gchar  *locale)
{
  LEntry *lentry_before;
  LEntry *lentry;
  Entry  *entry;
  gint    result;

  for (entry = simple->group->efirst; entry != NULL; entry = entry->next)
    if (str_is_equal (entry->key, key))
      break;

  if (G_UNLIKELY (entry == NULL))
    {
      entry         = g_slice_new (Entry);
      entry->key    = g_string_chunk_insert (simple->string_chunk, key);
      entry->value  = g_string_chunk_insert (simple->string_chunk, value);
      entry->lfirst = NULL;
      entry->llast  = NULL;

      if (simple->group->efirst == NULL)
        {
          entry->next = entry->prev = NULL;
          simple->group->efirst = simple->group->elast = entry;
        }
      else
        {
          entry->next = NULL;
          entry->prev = simple->group->elast;
          simple->group->elast->next = entry;
          simple->group->elast = entry;
        }

      if (locale == NULL)
        return entry;
    }

  if (G_UNLIKELY (locale == NULL))
    {
      /* overwrite existing value */
      if (!str_is_equal (entry->value, value))
        entry->value = g_string_chunk_insert (simple->string_chunk, value);
    }
  else
    {
      /* Add the localized value. Note the optimization used within here: We store
       * the locales in alphabetic order (e.g. de, fr, ...). And we start the search
       * at the end of the locales list, since locales are usually sorted in the
       * rc files. Once we notice that the locale in question is less than the
       * current list locale, we cancel the search and remember the list element as
       * the element before the new list element (remember the sorting order). This
       * makes parsing a usual resource config file with lots of locales amazingly
       * fast.
       */
      lentry_before = NULL;
      for (lentry = entry->llast; lentry != NULL; lentry = lentry->prev)
        {
          result = strcmp (lentry->locale, locale);

          if (result == 0)
            break;
          else if (result < 0)
            {
              lentry_before = lentry;
              lentry = NULL;
              break;
            }
        }

      if (G_LIKELY (lentry == NULL))
        {
          /* create new localized entry */
          lentry         = g_slice_new (LEntry);
          lentry->locale = g_string_chunk_insert (simple->string_chunk, locale);
          lentry->value  = g_string_chunk_insert (simple->string_chunk, value);

          if (G_UNLIKELY (entry->lfirst == NULL))
            {
              lentry->next = lentry->prev = NULL;
              entry->lfirst = entry->llast = lentry;
            }
          else if (lentry_before != NULL)
            {
              lentry->next = lentry_before->next;
              lentry->prev = lentry_before;
              if (G_UNLIKELY (lentry_before->next != NULL))
                lentry_before->next->prev = lentry;
              else
                entry->llast = lentry;
              lentry_before->next = lentry;
            }
          else
            {
              lentry->next = NULL;
              lentry->prev = entry->llast;
              entry->llast->next = lentry;
              entry->llast = lentry;
            }
        }
      else
        {
          /* overwrite value in existing localized entry */
          if (G_LIKELY (!str_is_equal (lentry->value, value)))
            lentry->value = g_string_chunk_insert (simple->string_chunk, value);
        }
    }

  return entry;
}