Page Menu
Home
Phabricator
Search
Configure Global Search
Log In
Files
F7687407
affuse.c
No One
Temporary
Actions
Download File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Size
5 KB
Referenced Files
None
Subscribers
None
affuse.c
View Options
/************************************************************
*
* (c) 2007 Olivier Castan castan.o@free.fr
* Modifications (C) 2007 Simson Garfinkel, to fit into the AFFLIB build system.
*
* License: LGPL or AFFLIB. Take your choice.
*
* KISS: based on fuse hello.c example
*
* TODO: - use xattr to display informations from segments
* - use AF_ACQUISITION_DATE for creation date
* - option between BADFLAG and NULLs
* - ...
*
* *********************************************************/
#if HAVE_CONFIG_H
#include "affconfig.h"
#endif
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#ifdef USE_FUSE
/* bool used in afflib.h but not defined within C */
#ifndef bool
#define bool int
#endif
#include "afflib.h"
#include <fuse.h>
#include <fcntl.h>
#include <libgen.h>
#define XCALLOC(type, num) \
((type *) xcalloc ((num), sizeof(type)))
#define XMALLOC(type, num) \
((type *) xmalloc ((num) * sizeof(type)))
#define XFREE(stale) do { \
if (stale) { free ((void *) stale); stale = 0; } \
} while (0)
static char *raw_path = NULL;
static off_t raw_size = 0;
static AFFILE *af_image = NULL;
static const char *raw_ext = ".raw";
static void *
xmalloc (size_t num)
{
void *alloc = malloc (num);
if (!alloc) {
perror ("Memory exhausted");
exit(EXIT_FAILURE);
}
return alloc;
}
static void *
xcalloc (size_t num, size_t size)
{
void *alloc = xmalloc (num * size);
memset (alloc, 0, num * size);
return alloc;
}
static char *
xstrdup(char *string)
{
return strcpy((char *)xmalloc(strlen(string) + 1), string);
}
static int
affuse_getattr(const char *path, struct stat *stbuf)
{
int res = 0;
memset(stbuf, 0, sizeof(struct stat));
if(strcmp(path, "/") == 0) {
stbuf->st_mode = S_IFDIR | 0755;
stbuf->st_nlink = 2;
}
else if(strcmp(path, raw_path) == 0) {
stbuf->st_mode = S_IFREG | 0444;
stbuf->st_nlink = 1;
stbuf->st_size = raw_size;
}
else
res = -ENOENT;
return res;
}
static int
affuse_readdir(const char *path, void *buf, fuse_fill_dir_t filler,
off_t offset, struct fuse_file_info *fi)
{
(void) offset;
(void) fi;
if(strcmp(path, "/") != 0)
return -ENOENT;
filler(buf, ".", NULL, 0);
filler(buf, "..", NULL, 0);
filler(buf, raw_path + 1, NULL, 0);
return 0;
}
static int
affuse_open(const char *path, struct fuse_file_info *fi)
{
if(strcmp(path, raw_path) != 0)
return -ENOENT;
if((fi->flags & 3) != O_RDONLY)
return -EACCES;
return 0;
}
static int
affuse_read(const char *path, char *buf, size_t size, off_t offset,
struct fuse_file_info *fi)
{
int res = 0;
(void) fi;
if(strcmp(path, raw_path) != 0){
return -ENOENT;
}
/* TODO: change to sector aligned readings to write NULLs to bad
* blocks... */
/* looks like af_seek never fails */
af_seek(af_image, (uint64_t)offset, SEEK_SET);
errno = 0;
res = af_read(af_image, (unsigned char *)buf, (int)size);
if (res<0){
if (errno==0) errno=-EIO;
else res = -errno;
}
return res;
}
static void
affuse_destroy(void* param)
{
af_close(af_image);
XFREE(raw_path);
return;
}
static struct fuse_operations affuse_oper = {
.getattr = affuse_getattr,
.readdir = affuse_readdir,
.open = affuse_open,
.read = affuse_read,
.destroy = affuse_destroy,
};
static void
usage(void)
{
char *cmdline[] = {"affuse", "-ho"};
printf("affuse version %s\n", PACKAGE_VERSION);
printf("Usage: affuse [<FUSE library options>] af_image mount_point\n");
/* dirty, just to get current libfuse option list */
fuse_main(2, cmdline, &affuse_oper, NULL);
printf("\nUse fusermount -u mount_point, to unmount\n");
}
int main(int argc, char **argv)
{
char *af_path = NULL, *af_basename = NULL;
size_t raw_path_len = 0;
char **fargv = NULL;
int fargc = 0;
if (argc < 3) {
usage();
exit(EXIT_FAILURE);
}
/* Prepare fuse args, af_image is omitted, but "-s" is added */
fargv = XCALLOC(char *, argc); /* usually not free'd */
fargv[0] = argv[0];
fargv[1] = argv[argc - 1];
fargc = 2;
while (fargc <= (argc - 2)) {
fargv[fargc] = argv[fargc - 1];
if (strcmp(fargv[fargc], "-h") == 0 ||
strcmp(fargv[fargc], "--help") == 0 ) {
usage();
XFREE(fargv);
exit(EXIT_SUCCESS);
}
fargc++;
}
/* disable multi-threaded operation
* (we don't know if afflib is thread safe!)
*/
fargv[fargc] = "-s";
fargc++;
if ((af_image = af_open(argv[argc - 2], O_RDONLY|O_EXCL, 0)) == NULL) {
perror("Can't open image file");
XFREE(fargv);
exit(EXIT_FAILURE);
}
af_path = xstrdup(argv[argc - 2]);
af_basename = basename(af_path);
/* "/" af_basename raw_ext "/0"*/
raw_path_len = 1 + strlen(af_basename) + strlen(raw_ext) + 1;
raw_path = XCALLOC(char, raw_path_len);
raw_path[0] = '/';
strcat(raw_path, af_basename);
strcat(raw_path, raw_ext);
raw_path[raw_path_len -1] = 0;
XFREE(af_path);
raw_size = af_get_imagesize(af_image);
return fuse_main(fargc, fargv, &affuse_oper, NULL);
}
#else
int main(int argc,char **argv)
{
fprintf(stderr,"affuse: FUSE support is disabled.\n");
#ifndef linux
fprintf(stderr,"affuse was compiled on a platform that does not support FUSE\n");
#else
fprintf(stderr,"affuse was compiled on a Linux system that did not\n");
fprintf(stderr,"have the FUSE developer libraries installed\n");
fprintf(stderr,"You need to install the fuse-devl package.\n");
#endif
exit(1);
}
#endif
File Metadata
Details
Attached
Mime Type
text/x-c
Expires
Wed, Oct 29, 11:54 AM (13 h, 49 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
1347016
Default Alt Text
affuse.c (5 KB)
Attached To
Mode
rXMOUNT xmount
Attached
Detach File
Event Timeline
Log In to Comment