Beispiel #1
0
static int
shell_cd (Camera __unused__ *camera, const char *arg)
{
	char folder[MAX_FOLDER_LEN];
	CameraList *list;
	int arg_count = shell_arg_count (arg);

	if (!arg_count)
		return (GP_OK);

	/* shell_arg(arg, 0, arg_dir); */

	if (strlen (arg) > 1023) {
		cli_error_print ("Folder value is too long");
		return (GP_ERROR);
	}

	/* Get the new folder value */
	shell_construct_path (p->folder, arg, folder, NULL);

	CHECK (gp_list_new (&list));

	CL (gp_camera_folder_list_folders (p->camera, folder, list,
					      p->context), list);
	gp_list_free (list);
	free (p->folder);
	p->folder = malloc (sizeof (char) * (strlen (folder) + 1));
	if (!p->folder)
		return (GP_ERROR_NO_MEMORY);
	strcpy (p->folder, folder);
	printf (_("Remote directory now '%s'."), p->folder);
	putchar ('\n');
	return (GP_OK);
}
Beispiel #2
0
int
for_each_file (GPParams *p, FileAction action)
{
	CameraList *list;
	int i, count, r;
	const char *name = NULL;
	char *f = NULL;

	CR (gp_list_new (&list));
	/* Iterate on all files */
	CR (gp_camera_folder_list_files (p->camera, p->folder, list,
					 p->context));
	CR (count = gp_list_count (list));
	if (p->flags & FLAGS_REVERSE) {
		for (i = count ; i--; ) {
			CL (gp_list_get_name (list, i, &name), list);
			CL (action (p, name), list);
		}
	} else {
		for (i = 0; i < count; i++) {
			CL (gp_list_get_name (list, i, &name), list);
			CL (action (p, name), list);
		}
	}

	/* If no recursion is requested, we are done. */
	if (!(p->flags & FLAGS_RECURSE)) {
		gp_list_free (list);
		return (GP_OK);
	}

	/* Recursion requested. Descend into subfolders. */
	CL (gp_camera_folder_list_folders (p->camera, p->folder,
					   list, p->context), list);
	CL (count = gp_list_count (list), list);
	for (i = 0; i < count; i++) {
		CL (gp_list_get_name (list, i, &name), list);
		f = p->folder;
		p->folder = malloc (sizeof (char) *
				(strlen (f) + 1 + strlen (name) + 1));
		if (!p->folder) {
			p->folder = f;
			gp_list_free (list);
			return (GP_ERROR_NO_MEMORY);
		}
		strcpy (p->folder, f);
		if (p->folder[strlen (p->folder) - 1] != '/')
			strcat (p->folder, "/");
		strcat (p->folder, name);
		r = for_each_file (p, action);
		free (p->folder);
		p->folder = f;
		CL (r, list);
	}
	gp_list_free (list);
	return (GP_OK);
}
Beispiel #3
0
static int foreach_entry(char* folder, GPParams* gp_params, enum EntryType type, PHandleFunc func, void* args)
{
	CameraList *list = NULL;
	int ret = 0, count = 0;
	CK00 (ret = gp_list_new (&list), err_newlist);
	if (type == ET_FOLDER)
		CK00 (ret = gp_camera_folder_list_folders (gp_params->camera, folder, list, gp_params->context), err_listfolder);
	else if (type == ET_FILE)
		CK00 (ret = gp_camera_folder_list_files (gp_params->camera, folder, list, gp_params->context), err_listfiles);
	else {
		LOG_E("unknow type :%d\n", type);
		goto release_list;
	}
	CK00 (count = ret = gp_list_count (list), err_listcount);

	int i = 0;
	for (i = 0; i < count; ++i) {
		const char* tmp_name = NULL;
		CK00 (ret= gp_list_get_name (list, i, &tmp_name), err_listgetname);
		if (type == ET_FILE && try_get_camera_file(gp_params, folder, tmp_name) < 0) {
			continue;
		}
		char* new_folder = NULL;
		CK01 (new_folder = make_new_path(folder,tmp_name), err_makpath);
		func(new_folder, gp_params, args);
		safe_free(new_folder);
	}
release_list:
	if (list)
		gp_list_free (list);
out:
	return ret;

err_newlist:
	LOG_E("gp_list_new error,retcode = %d", ret);
	ret = -1;
	goto out;
err_listfolder:
	LOG_E("gp_camera_folder_list_folders error,retcode = %d", ret);
	ret = -1;
	goto release_list;
err_listfiles:
	LOG_E("gp_camera_folder_list_files error,retcode = %d", ret);
	ret = -1;
	goto release_list;
err_listcount:
	LOG_E("gp_list_count error,retcode = %d", ret);
	ret = -1;
	goto release_list;
err_listgetname:
	LOG_E("gp_list_get_name error,retcode = %d", ret);
	ret = -1;
	goto release_list;
err_makpath:
	ret = -1;
	goto release_list;	
}
Beispiel #4
0
static int
shell_ls (Camera __unused__ *camera, const char *arg)
{
	CameraList *list;
	char buf[1024], folder[MAX_FOLDER_LEN];
	int x, y=1;
	int arg_count = shell_arg_count(arg);
	const char *name;

	if (arg_count) {
		shell_construct_path (p->folder, arg, folder, NULL);
	} else {
		strcpy (folder, p->folder);
	}

	CHECK (gp_list_new (&list));
	CL (gp_camera_folder_list_folders (p->camera, folder, list,
					      p->context), list);

	if (p->flags & FLAGS_QUIET)
		printf ("%i\n", gp_list_count (list));

	for (x = 1; x <= gp_list_count (list); x++) {
		CL (gp_list_get_name (list, x - 1, &name), list);
		if (p->flags & FLAGS_QUIET)
			printf ("%s\n", name);
		else {
			sprintf (buf, "%s/", name);
			printf ("%-20s", buf);
			if (y++ % 4 == 0)
				putchar ('\n');
		}
	}

	CL (gp_camera_folder_list_files (p->camera, folder, list,
					    p->context), list);

	if (p->flags & FLAGS_QUIET)
		printf("%i\n", gp_list_count(list));

	for (x = 1; x <= gp_list_count (list); x++) {
		gp_list_get_name (list, x - 1, &name);
		if (p->flags & FLAGS_QUIET)
			printf ("%s\n", name);
		else {
			printf ("%-20s", name);
			if (y++ % 4 == 0)
				putchar ('\n');
		}
	}
	if ((p->flags & FLAGS_QUIET) == 0 && (y % 4 != 1))
		putchar ('\n');

	gp_list_free (list);
	return (GP_OK);
}
Beispiel #5
0
static int
get_path_for_id_rec (GPParams *p,
		     const char *base_folder, unsigned int id,
		     unsigned int *base_id, char *folder,
		     char *filename)
{
	char subfolder[1024];
	int n_folders, n_files, r;
	unsigned int i;
	const char *name;
	CameraList *list;

	strncpy (folder, base_folder, MAX_FOLDER_LEN);
	CR (gp_list_new(&list));
	CL (gp_camera_folder_list_files (p->camera, base_folder, list,
					 p->context), list);
	CL (n_files = gp_list_count (list), list);
	if (id - *base_id < (unsigned int) n_files) {

		/* ID is in this folder */
		GP_DEBUG ("ID %i is in folder '%s'.", id, base_folder);
		CL (gp_list_get_name (list, id - *base_id, &name), list);
		strncpy (filename, name, MAX_FILE_LEN);
		gp_list_free (list);
		return (GP_OK);
	} else {
		/* Look for IDs in subfolders */
		GP_DEBUG ("ID %i is not in folder '%s'.", id, base_folder);
		*base_id += n_files;
		CL (gp_camera_folder_list_folders (p->camera, base_folder,
						   list, p->context), list);
		CL (n_folders = gp_list_count (list), list);
		for (i = 0; i < (unsigned int)n_folders; i++) {
			CL (gp_list_get_name (list, i, &name), list);
			strncpy (subfolder, base_folder, sizeof (subfolder));
			if (strlen (base_folder) > 1)
				strncat (subfolder, "/", sizeof (subfolder) - strlen(subfolder) - 1);
			strncat (subfolder, name, sizeof (subfolder) - strlen(subfolder) - 1);
			r = get_path_for_id_rec (p, subfolder, id, base_id,
						 folder, filename);
			switch (r) {
			case GP_ERROR_FRONTEND_BAD_ID:
				break;
			default:
				gp_list_free (list);
				return (r);
			}
		}
		gp_list_free (list);
		return (GP_ERROR_FRONTEND_BAD_ID);
	}
}
Beispiel #6
0
bool GPCamera::getFolders(const QString& folder)
{
#ifdef HAVE_GPHOTO2
    int         errorCode;
    CameraList* clist = 0;
    gp_list_new(&clist);

    d->status->cancel = false;
    errorCode         = gp_camera_folder_list_folders(d->camera, QFile::encodeName(folder).constData(), clist, d->status->context);

    if (errorCode != GP_OK)
    {
        qCDebug(DIGIKAM_IMPORTUI_LOG) << "Failed to get folders list from camera!";
        printGphotoErrorDescription(errorCode);
        gp_list_unref(clist);
        return false;
    }

    QStringList subFolderList;
    int count = gp_list_count(clist);

    if (count < 1)
    {
        return true;
    }

    for (int i = 0 ; i < count ; ++i)
    {
        const char* subFolder = 0;
        errorCode             = gp_list_get_name(clist, i, &subFolder);

        if (errorCode != GP_OK)
        {
            qCDebug(DIGIKAM_IMPORTUI_LOG) << "Failed to get folder name from camera!";
            printGphotoErrorDescription(errorCode);
            gp_list_unref(clist);
            return false;
        }

        subFolderList.append(folder + QFile::decodeName(subFolder) + QLatin1Char('/'));
    }

    gp_list_unref(clist);

    emit signalFolderList(subFolderList);

    return true;
#else
    Q_UNUSED(folder);
    return false;
#endif /* HAVE_GPHOTO2 */
}
Beispiel #7
0
void Camera::for_each_file_in_folder(const FileFunc& func, const std::string& folder) {
    int ret;
    CameraList *files;
    gp_list_new(&files);
    if ((ret = gp_camera_folder_list_files(camera, folder.c_str(), files, ctx->context)) < GP_OK) {
        throw Exception("gp_camera_folder_list_files", ret);
    }
    for (int i = 0; i < gp_list_count(files); ++i) {
        std::string file_name;
        {
            const char *c_file_name;
            gp_list_get_name(files, i, &c_file_name);
            file_name = c_file_name;
        }
        CameraFileInfo file_info;
        if ((ret = gp_camera_file_get_info(camera, folder.c_str(), file_name.c_str(), &file_info, ctx->context)) < GP_OK) {
            throw Exception("gp_camera_file_get_info", ret);
        }
        FileInfo info;
        info.folder = folder;
        info.name = file_name;
        if (file_info.file.fields & GP_FILE_INFO_MTIME) {
            info.fields |= FILE_INFO_TIME;
            info.time = file_info.file.mtime;
        }
        if (file_info.file.fields & GP_FILE_INFO_TYPE) {
            info.fields |= FILE_INFO_TYPE;
            info.type = file_info.file.type;
        }
        func(info);
    }
    gp_list_free(files);

    CameraList *folders;
    gp_list_new(&folders);
    if ((ret = gp_camera_folder_list_folders(camera, folder.c_str(), folders, ctx->context)) < GP_OK) {
        throw Exception("gp_camera_folder_list_folders", ret);
    }
    for (int i = 0; i < gp_list_count(folders); ++i) {
        const char *child_name;
        gp_list_get_name(folders, i, &child_name);
        std::string absolute_path = folder + "/" + child_name;
        for_each_file_in_folder(func, absolute_path);
    }
    gp_list_free(folders);
}
Beispiel #8
0
static int 
recursive_directory(Camera *camera, const char *folder, GPContext *context, int *foundfile) {
	int		i, ret;
	CameraList	*list;
	const char	*newfile;
	CameraFileInfo	fileinfo;
	CameraFile	*file;

	ret = gp_list_new (&list);
	if (ret < GP_OK) {
		printf ("Could not allocate list.\n");
		return ret;
	}

	ret = gp_camera_folder_list_folders (camera, folder, list, context);
	if (ret < GP_OK) {
		printf ("Could not list folders.\n");
		gp_list_free (list);
		return ret;
	}
	gp_list_sort (list);

	for (i = 0; i < gp_list_count (list); i++) {
		const char *newfolder;
		char *buf;
		int havefile = 0;

		gp_list_get_name (list, i, &newfolder);

		buf = malloc (strlen(folder) + 1 + strlen(newfolder) + 1);
		strcpy(buf, folder);
		if (strcmp(folder,"/"))		/* avoid double / */
			strcat(buf, "/");
		strcat(buf, newfolder);

		ret = recursive_directory (camera, buf, context, &havefile);
		free (buf);
		if (ret != GP_OK) {
			gp_list_free (list);
			printf ("Failed to recursively list folders.\n");
			return ret;
		}
		if (havefile) /* only look for the first directory with a file */
			break;
	}
	gp_list_reset (list);

	ret = gp_camera_folder_list_files (camera, folder, list, context);
	if (ret < GP_OK) {
		gp_list_free (list);
		printf ("Could not list files.\n");
		return ret;
	}
	gp_list_sort (list);
	if (gp_list_count (list) <= 0) {
		gp_list_free (list);
		return GP_OK;
	}

	gp_list_get_name (list, 0, &newfile); /* only entry 0 needed */
	ret = gp_camera_file_get_info (camera, folder, newfile, &fileinfo, context);
	if (ret != GP_OK) {
		gp_list_free (list);
		printf ("Could not get file info.\n");
		return ret;
	}

	/* Trigger the ptp things */
	gp_file_new (&file);
	ret = gp_camera_file_get (camera, folder, newfile, GP_FILE_TYPE_METADATA, file, context);
	if ((ret != GP_OK) && (ret != GP_ERROR_NOT_SUPPORTED)) {
		gp_list_free (list);
		printf ("Could not get file metadata.\n");
		return ret;
	}
	gp_file_free (file);
	if (foundfile) *foundfile = 1;
	gp_list_free (list);
	return GP_OK;
}
Beispiel #9
0
static void
load_filesystem(const char *folder) {
#ifdef HAVE_GPHOTO2
    int		i, count, ret;
    CameraList	*list;

    ret = gp_list_new (&list);
    if (ret < GP_OK)
	return;
    ret = gp_camera_folder_list_files (activeDS.camera, folder, list, activeDS.context);
    if (ret < GP_OK) {
	gp_list_free (list);
	return;
    }
    count = gp_list_count (list);
    if (count < GP_OK) {
	gp_list_free (list);
	return;
    }
    for (i = 0; i < count; i++) {
	const char *name;
	struct gphoto2_file *gpfile;

	ret = gp_list_get_name (list, i, &name);
	if (ret < GP_OK)
	    continue;
	gpfile = malloc(sizeof(struct gphoto2_file));
	if (!gpfile)
	    continue;
	TRACE("adding %s/%s\n", folder, name);
	gpfile->folder = strdup(folder);
	gpfile->filename = strdup(name);
	gpfile->download = FALSE;
	list_add_head( &activeDS.files, &gpfile->entry );
    }
    gp_list_reset (list);

    ret = gp_camera_folder_list_folders (activeDS.camera, folder, list, activeDS.context);
    if (ret < GP_OK) {
	FIXME("list_folders failed\n");
	gp_list_free (list);
	return;
    }
    count = gp_list_count (list);
    if (count < GP_OK) {
	FIXME("list_folders failed\n");
	gp_list_free (list);
	return;
    }
    for (i = 0; i < count; i++) {
	const char *name;
	char *newfolder;
	ret = gp_list_get_name (list, i, &name);
	if (ret < GP_OK)
	    continue;
	TRACE("recursing into %s\n", name);
	newfolder = malloc(strlen(folder)+1+strlen(name)+1);
	if (!strcmp(folder,"/"))
	    sprintf (newfolder, "/%s", name);
	else
	    sprintf (newfolder, "%s/%s", folder, name);
	load_filesystem (newfolder); /* recurse ... happily */
    }
    gp_list_free (list);
#endif
}
Beispiel #10
0
int
for_each_folder (GPParams *p, FolderAction action)
{
	CameraList *list;
	int r, i, count;
	const char *name = NULL;
	char *f = NULL;

	if (!p)
		return (GP_ERROR_BAD_PARAMETERS);

	/* Execute the action for this folder. */
	for (i = 0; FolderActions[i].name; i++)
		if (FolderActions[i].action == action)
			break;
	gp_log (GP_LOG_DEBUG, "foreach",
		"Executing action '%s' for folder '%s'.",
		FolderActions[i].name, p->folder);
	CR (action (p));

	/* If no recursion is requested, we are done. */
	if (!(p->flags & FLAGS_RECURSE))
		return GP_OK;

	CR (gp_list_new (&list));
	/* Recursion requested. Descend into subfolders. */
	CL (gp_camera_folder_list_folders (p->camera, p->folder, list,
					   p->context), list);
	CL (count = gp_list_count (list), list); 
	if (p->flags & FLAGS_REVERSE) {
		for (i = count - 1; i >= 0; i--) {
			CL (gp_list_get_name (list, i, &name), list);
			f = p->folder;
			p->folder = malloc (sizeof (char) *
				(strlen (f) + 1 + strlen (name) + 1));
			if (!p->folder) {
				p->folder = f;
				gp_list_free (list);
				return (GP_ERROR_NO_MEMORY);
			}
			strcpy (p->folder, f);
			if (p->folder[strlen (p->folder) - 1] != '/')
				strcat (p->folder, "/");
			strcat (p->folder, name);
			r = for_each_folder (p, action);
			free (p->folder);
			p->folder = f;
			CL (r, list);
		}
	} else {
		for (i = 0; i < count; i++) {
			CL (gp_list_get_name (list, i, &name), list);
			f = p->folder;
			p->folder = malloc (sizeof (char) * 
				(strlen (f) + 1 + strlen (name) + 1));
			if (!p->folder) {
				p->folder = f;
				gp_list_free (list);
				return (GP_ERROR_NO_MEMORY);
			}
			strcpy (p->folder, f);
			if (p->folder[strlen (p->folder) - 1] != '/')
				strcat (p->folder, "/");
			strcat (p->folder, name);
			r = for_each_folder (p, action);
			free (p->folder);
			p->folder = f;
			CL (r, list);
		}
	}
	gp_list_free (list);
	return (GP_OK);
}
Beispiel #11
0
int _camctl_recursive_get_previews(const dt_camctl_t *c,dt_camera_preview_flags_t flags,char *path)
{
  CameraList *files;
  CameraList *folders;
  const char *filename;
  const char *foldername;

  gp_list_new (&files);
  gp_list_new (&folders);

  // Process files in current folder...
  if( gp_camera_folder_list_files(c->active_camera->gpcam,path,files,c->gpcontext) == GP_OK )
  {
    for(int i=0; i < gp_list_count(files); i++)
    {
      gp_list_get_name (files, i, &filename);
      char *file = g_strconcat(path, "/", filename, NULL);

      // Lets check the type of file...
      CameraFileInfo cfi;
      if( gp_camera_file_get_info(c->active_camera->gpcam, path, filename,&cfi,c->gpcontext) == GP_OK)
      {
        CameraFile *preview=NULL;
        CameraFile *exif=NULL;

        /*
         * Fetch image preview if flagged...
         */
        if( flags & CAMCTL_IMAGE_PREVIEW_DATA )
        {
          gp_file_new(&preview);
          if( gp_camera_file_get(c->active_camera->gpcam, path, filename, GP_FILE_TYPE_PREVIEW,preview,c->gpcontext) < GP_OK )
          {
            // No preview for file lets check image size to se if we should download full image for preview...
            if( cfi.file.size > 0  && cfi.file.size < 512000 )
              if( gp_camera_file_get(c->active_camera->gpcam, path, filename, GP_FILE_TYPE_NORMAL,preview,c->gpcontext) < GP_OK )
              {
                preview=NULL;
                dt_print(DT_DEBUG_CAMCTL,"[camera_control] failed to retreive preview of file %s\n",filename);
              }
          }
        }

        if( flags & CAMCTL_IMAGE_EXIF_DATA )
        {
          gp_file_new(&exif);
          if( gp_camera_file_get(c->active_camera->gpcam, path, filename, GP_FILE_TYPE_EXIF,exif,c->gpcontext) < GP_OK )
          {
            exif=NULL;
            dt_print(DT_DEBUG_CAMCTL,"[camera_control] failed to retreive exif of file %s\n",filename);
          }
        }

        // let's dispatch to host app.. return if we should stop...
        if (!_dispatch_camera_storage_image_filename(c,c->active_camera,file,preview,exif))
        {
          g_free(file);
          return 0;
        }
      }
      else
        dt_print(DT_DEBUG_CAMCTL,"[camera_control] failed to get file information of %s in folder %s on device\n",filename,path);
      g_free(file);
    }
  }

  // Recurse into folders in current folder...
  if( gp_camera_folder_list_folders(c->active_camera->gpcam,path,folders,c->gpcontext)==GP_OK)
  {
    for(int i=0; i < gp_list_count(folders); i++)
    {
      char buffer[4096]= {0};
      g_strlcat(buffer,path, 4096);
      if(path[1]!='\0') g_strlcat(buffer,"/", 4096);
      gp_list_get_name (folders, i, &foldername);
      g_strlcat(buffer,foldername, 4096);
      if( !_camctl_recursive_get_previews(c,flags,buffer))
        return 0;
    }
  }
  gp_list_free (files);
  gp_list_free (folders);
  return 1;
}
Beispiel #12
0
static char *
shell_path_generator (const char *text, int state)
{
	static int x;
	const char *slash, *name;
	CameraList *list;
	int file_count, folder_count, r, len;
	char folder[MAX_FOLDER_LEN], basename[MAX_FILE_LEN], *path;

#if 0
	printf ("shell_path_generator ('%s', %i)\n", text, state);
#endif

	r = shell_construct_path (p->folder, text, folder, basename);
	if (r < 0)
		return (NULL);
	len = strlen (basename);

#if 0
	printf ("Searching for '%s' in '%s'...\n", basename, folder);
#endif

	/* If this is a new path to complete, reinitialize */
	if (!state)
		x = 0;

	r = gp_list_new (&list);
	if (r < 0)
		return (NULL);
	/* First search for matching file */
	r = gp_camera_folder_list_files (p->camera, folder, list, p->context);
	if (r < 0) {
		gp_list_free (list);
		return (NULL);
	}
	file_count = gp_list_count (list);
	if (file_count < 0) {
		gp_list_free (list);
		return (NULL);
	}
	if (x < file_count) {
		for (; x < file_count; x++) {
			r = gp_list_get_name (list, x, &name);
			if (r < 0)
				return (NULL);
			if (!strncmp (name, basename, len)) {
				x++;
				slash = strrchr (text, '/');
				if (!slash) {
					path = malloc (strlen (name) + 2);
					if (!path)
						return (NULL);
					strcpy (path, name);
					strcat (path, " ");
				} else {
					path = malloc (slash - text + 1 + strlen (name) + 2);
					if (!path)
						return (NULL);
					memset (path, 0, slash - text + 1 + strlen (name) + 2);
					strncpy (path, text, slash - text);
					strcat (path, "/");
					strcat (path, name);
					strcat (path, " ");
				}
				return (path);
			}
		}
	}

	/* Ok, we listed all matching files. Now, list matching folders. */
	r = gp_camera_folder_list_folders (p->camera, folder, list,
					   p->context);
	if (r < 0) {
		gp_list_free (list);
		return (NULL);
	}
	folder_count = gp_list_count (list);
	if (folder_count < 0) {
		gp_list_free (list);
		return (NULL);
	}
	if (x - file_count < folder_count) {
		for (; x - file_count < folder_count; x++) {
			r = gp_list_get_name (list, x - file_count, &name);
			if (r < 0) {
				gp_list_free (list);
				return (NULL);
			}
			if (!strncmp (name, basename, len)) {
				x++;
				slash = strrchr (text, '/');
				if (!slash) {
					path = malloc (strlen (name) + 2);
					if (!path)
						return (NULL);
					strcpy (path, name);
					strcat (path, "/");
				} else {
					path = malloc (slash - text + 1 + strlen (name) + 2);
					if (!path)
						return (NULL);
					memset (path, 0, slash - text + 1 + strlen (name) + 2);
					strncpy (path, text, slash - text);
					strcat (path, "/");
					strcat (path, name);
					strcat (path, "/");
				}
				gp_list_free (list);
				return (path);
			}
		}
		gp_list_free (list);
		return (NULL);
	}

	gp_list_free (list);
	return (NULL);
}
Beispiel #13
0
static GnomeVFSResult do_get_file_info (
    GnomeVFSMethod*                 method,
    GnomeVFSURI*                    uri,
    GnomeVFSFileInfo*               info,
    GnomeVFSFileInfoOptions         options,
    GnomeVFSContext*                context)
{
    GnomeVFSResult result;
    GnomeVFSURI *parent;
    Camera *camera;
    CameraFileInfo camera_info;
    CameraList *list;
    const gchar *path, *name;
    char *basename;
    guint i;
    int count;

    printf ("ENTER: do_get_file_info (%s)\n", camera_uri_get_path (uri));

    G_LOCK (cameras);

    /* Is this root? */
    if (!gnome_vfs_uri_has_parent (uri)) {
        info->name = g_strdup ("/");
        info->valid_fields = GNOME_VFS_FILE_INFO_FIELDS_TYPE |
                             GNOME_VFS_FILE_INFO_FIELDS_MIME_TYPE;
        info->type = GNOME_VFS_FILE_TYPE_DIRECTORY;
        info->mime_type = g_strdup ("x-directory/normal");
        G_UNLOCK (cameras);
        return (GNOME_VFS_OK);
    }

    printf ("Getting camera (do_get_file_info)...\n");
    result = get_camera (uri, &camera);
    if (result != GNOME_VFS_OK) {
        G_UNLOCK (cameras);
        return (result);
    }

    result = GNOME_VFS_RESULT (gp_list_new (&list));
    if (result != GNOME_VFS_OK) {
        unref_camera (camera);
        G_UNLOCK (cameras);
        return (result);
    }

    /*
     * We cannot use get_basename here because of potential trailing
     * slashes.
     */
    basename = gnome_vfs_uri_extract_short_name (uri);

    parent = camera_uri_get_parent (uri);
    path = camera_uri_get_path (parent);

    result = GNOME_VFS_RESULT (gp_camera_folder_list_folders (camera, path,
                               list, NULL));
    if (result != GNOME_VFS_OK) {
        gnome_vfs_uri_unref (parent);
        unref_camera (camera);
        gp_list_free (list);
        g_free (basename);
        G_UNLOCK (cameras);
        return (result);
    }

    count = gp_list_count (list);
    if (count < 0) {
        gnome_vfs_uri_unref (parent);
        unref_camera (camera);
        gp_list_free (list);
        g_free (basename);
        G_UNLOCK (cameras);
        return (GNOME_VFS_RESULT (count));
    }

    for (i = 0; i < count; i++) {
        result = GNOME_VFS_RESULT (gp_list_get_name (list, i, &name));
        if (result != GNOME_VFS_OK) {
            gnome_vfs_uri_unref (parent);
            unref_camera (camera);
            gp_list_free (list);
            g_free (basename);
            G_UNLOCK (cameras);
            return (result);
        }
        if (!strcmp (name, basename)) {
            info->name = g_strdup (basename);
            info->valid_fields = GNOME_VFS_FILE_INFO_FIELDS_TYPE |
                                 GNOME_VFS_FILE_INFO_FIELDS_MIME_TYPE;
            info->type = GNOME_VFS_FILE_TYPE_DIRECTORY;
            info->mime_type = g_strdup ("x-directory/normal");
            gnome_vfs_uri_unref (parent);
            unref_camera (camera);
            gp_list_free (list);
            g_free (basename);
            G_UNLOCK (cameras);
            printf ("Found folder!\n");
            return (GNOME_VFS_OK);
        }
    }

    result = GNOME_VFS_RESULT (gp_camera_folder_list_files (camera, path,
                               list, NULL));
    if (result != GNOME_VFS_OK) {
        gnome_vfs_uri_unref (parent);
        unref_camera (camera);
        gp_list_free (list);
        g_free (basename);
        G_UNLOCK (cameras);
        return (result);
    }

    count = gp_list_count (list);
    if (count < 0) {
        gnome_vfs_uri_unref (parent);
        unref_camera (camera);
        gp_list_free (list);
        g_free (basename);
        G_UNLOCK (cameras);
        return (GNOME_VFS_RESULT (count));
    }

    for (i = 0; i < count; i++) {
        result = GNOME_VFS_RESULT (gp_list_get_name (list, i, &name));
        if (result != GNOME_VFS_OK) {
            gnome_vfs_uri_unref (parent);
            unref_camera (camera);
            gp_list_free (list);
            g_free (basename);
            G_UNLOCK (cameras);
            return (result);
        }
        if (!strcmp (name, basename)) {
            result = GNOME_VFS_RESULT (gp_camera_file_get_info (
                                           camera, path, basename, &camera_info,
                                           NULL));
            g_free (basename);
            unref_camera (camera);
            gp_list_free (list);
            if (result != GNOME_VFS_OK) {
                G_UNLOCK (cameras);
                return (result);
            }
            get_info_from_camera_info (&camera_info, FALSE, info);
            gnome_vfs_uri_unref (parent);
            G_UNLOCK (cameras);
            printf ("Found file!\n");
            return (GNOME_VFS_OK);
        }
    }

    gnome_vfs_uri_unref (parent);
    g_free (basename);
    unref_camera (camera);
    gp_list_free (list);

    G_UNLOCK (cameras);

    return (GNOME_VFS_ERROR_NOT_FOUND);
}