Exemple #1
0
int
cmd_listall(int argc, char **argv, struct mpd_connection *conn)
{
	const char * listall = "";
	int i = 0;

	if (argc > 0)
		listall = charset_to_utf8(argv[i]);

	do {
		char *tmp = strdup(listall);
		strip_trailing_slash(tmp);

		if (options.custom_format) {
			if (!mpd_send_list_all_meta(conn, tmp))
				printErrorAndExit(conn);

			print_entity_list(conn, MPD_ENTITY_TYPE_UNKNOWN);
		} else {
			if (!mpd_send_list_all(conn, tmp))
				printErrorAndExit(conn);

			print_filenames(conn);
		}

		my_finishCommand(conn);
		free(tmp);
	} while (++i < argc && (listall = charset_to_utf8(argv[i])) != NULL);

	return 0;
}
Exemple #2
0
int cmd_ls ( int argc, char ** argv, struct mpd_connection *conn )
{
	for (int i = 0; i < argc; i++)
		strip_trailing_slash(argv[i]);

	return ls_entity(argc, argv, conn, MPD_ENTITY_TYPE_UNKNOWN);
}
Exemple #3
0
static int simulated_rmdir(char *directory_path) {
  int result = -1;
  size_t path_length;
  BOOL slash_stripped;

  strip_trailing_slash(directory_path, &path_length, &slash_stripped);
  if (DeleteFile(directory_path)) {
    result = 0;
  }
  restore_trailing_slash(directory_path, &path_length, &slash_stripped);
  return result;
}
Exemple #4
0
// START FUNC DECL
int
list_files(
    char *in_data_dir
	 )
// STOP FUNC DECL
{
  int status = 0;
  struct stat st;
  size_t size;
  FILE *ofp = NULL;
  int ddir_id = -1;
  char data_dir[MAX_LEN_DIR_NAME+1];

  if ( ( in_data_dir == NULL ) || ( *in_data_dir == '\0' ) )  {
    chdir(g_data_dir);
  }
  else {
    status = strip_trailing_slash(in_data_dir, data_dir, MAX_LEN_DIR_NAME+1);
    cBYE(status);
    status = get_ddir_id(data_dir, g_ddirs, g_n_ddir, false, &ddir_id);
    cBYE(status);
    chdir(in_data_dir);
  }

  ofp = stdout;
  for ( int i = 0; i < g_n_fld; i++ ) { 
    if ( g_flds[i].name[0] == '\0' ) { continue; } /* null entry */
    int this_ddir_id = g_flds[i].ddir_id;
    if ( ddir_id >= 0 ) { 
      if ( this_ddir_id != ddir_id ) { continue; }
    }
    if ( this_ddir_id < 0 ) { 
      chdir(g_data_dir);
    }
    else {
      chdir(g_ddirs[this_ddir_id].name);
    }
    status = stat(g_flds[i].filename, &st); cBYE(status);
    size = st.st_size;
    if ( size <= 0 ) { go_BYE(-1); }
    fprintf(ofp, "%d,%d,%lld,%s\n", 
	  g_flds[i].is_external, 
	  g_flds[i].ddir_id, 
	  (long long)size, 
	  g_flds[i].filename);
    chdir(g_cwd);
  }
BYE:
  return(status);
}
Exemple #5
0
int cmd_add (int argc, char ** argv, struct mpd_connection *conn )
{
	if (contains_absolute_path(argc, argv) && !path_prepare(conn))
		printErrorAndExit(conn);

	int i;

	if (!mpd_command_list_begin(conn, false))
		printErrorAndExit(conn);

	for(i=0;i<argc;i++) {
		strip_trailing_slash(argv[i]);

		const char *path = argv[i];
		const char *relative_path = to_relative_path(path);
		if (relative_path != NULL)
			path = relative_path;

		if (options.verbosity >= V_VERBOSE)
			printf("adding: %s\n", path);
		mpd_send_add(conn, charset_to_utf8(path));
	}

	if (!mpd_command_list_end(conn))
		printErrorAndExit(conn);

	if (!mpd_response_finish(conn)) {
#if LIBMPDCLIENT_CHECK_VERSION(2,4,0)
		if (mpd_connection_get_error(conn) == MPD_ERROR_SERVER) {
			/* check which of the arguments has failed */
			unsigned location =
				mpd_connection_get_server_error_location(conn);
			if (location < (unsigned)argc) {
				/* we've got a valid location from the
				   server */
				const char *message =
					mpd_connection_get_error_message(conn);
				message = charset_from_utf8(message);
				fprintf(stderr, "error adding %s: %s\n",
					argv[location], message);
				exit(EXIT_FAILURE);
			}
		}
#endif

		printErrorAndExit(conn);
	}

	return 0;
}
Exemple #6
0
// START FUNC DECL
int
init_ddirs(
	   char *dsk_data_dir,
	   char *ram_data_dir
	   )
// STOP FUNC DECL
{
  int status = 0;

  /*-----------------------------------------------------------*/
  char buffer[MAX_LEN_DIR_NAME+1];
  if ( ( dsk_data_dir == NULL ) || ( *dsk_data_dir == '\0' ) ) { go_BYE(-1); }
  if ( is_absolute_path(dsk_data_dir) == false ) { go_BYE(-1); }
  if ( strlen(dsk_data_dir) >= MAX_LEN_DIR_NAME ) { go_BYE(-1); }

  /* 0th position reserved for writable disk access */
  /* 1th position reserved for writable ram  access */
  /* all others reseved for readable access  */
  status = strip_trailing_slash(dsk_data_dir, buffer, MAX_LEN_DIR_NAME+1);
  cBYE(status);
  strcpy(g_ddirs[0].name, buffer); 
  g_ddirs[0].is_writable = true;
  g_ddirs[0].is_ram      = false;

  if ( ( ram_data_dir != NULL ) && ( *ram_data_dir != '\0' ) ) { 
    if ( strcmp(ram_data_dir, dsk_data_dir) == 0 ) { go_BYE(-1); }
    if ( is_absolute_path(ram_data_dir) == false ) { go_BYE(-1); }
    if ( strlen(ram_data_dir) >= MAX_LEN_DIR_NAME ) { go_BYE(-1); }
    status = strip_trailing_slash(ram_data_dir, buffer, MAX_LEN_DIR_NAME+1);
    cBYE(status);
    strcpy(g_ddirs[1].name, buffer); 
    g_ddirs[1].is_writable = true;
    g_ddirs[1].is_ram      = true;
  }
 BYE:
  return(status);
}
/* TODO maybe try not to use string port? */
static SgObject normalise_path(SgObject fullpath)
{
  SgStringPort sp;
  SgObject out = Sg_InitStringOutputPort(&sp, SG_STRING_SIZE(fullpath));
  int64_t pos = 0;
  int i = 0;
  while (i < SG_STRING_SIZE(fullpath)) {
    SgChar c = SG_STRING_VALUE_AT(fullpath, i++);
    if (c == '.') {
      if (i != SG_STRING_SIZE(fullpath)) {
	SgChar c2 = SG_STRING_VALUE_AT(fullpath, i++);
	if (c2 == '.') {
	  if (SG_STRING_VALUE_AT(fullpath, i) == '/' ||
	      SG_STRING_SIZE(fullpath) == i) {
	    if (pos-2 > 0) {
	      SgObject tmp = Sg_GetStringFromStringPort(out);
	      /* skip previous '.' and '/' */
	      pos = search_separator(tmp, pos-2);
	    } else {
	      pos = 1;		/* root */
	    }
	    if (pos <= 0) pos = 1; /* root */
	    Sg_SetPortPosition(out, pos, SG_BEGIN);
	    if (pos == 1) i++;
	  } else {
	    /* ok just a file named '..?' or longer*/
	    Sg_PutcUnsafe(out, '.');
	    Sg_PutcUnsafe(out, '.');
	    pos += 2;
	    for (; i < SG_STRING_SIZE(fullpath); i++) {
	      SgChar c3 = SG_STRING_VALUE_AT(fullpath, i);
	      if (c3 != '.') break;
	      Sg_PutcUnsafe(out, c3);
	      pos++;
	    }
	  }
	} else if (c2 != '/') {
	  Sg_PutcUnsafe(out, '.');
	  Sg_PutcUnsafe(out, c2);
	  pos += 2;
	}
      }
    } else {
      Sg_PutcUnsafe(out, c);
      pos++;
    }
  }
  return strip_trailing_slash(Sg_GetStringFromStringPort(out));
}
Exemple #8
0
static int simulated_mkdir(char *directory_path, int permission) {
  BPTR lock;
  int result = -1;
  size_t path_length;
  BOOL slash_stripped;

  strip_trailing_slash(directory_path, &path_length, &slash_stripped);
  lock = CreateDir(directory_path);
  if (lock != NULL) {
    UnLock(lock);
    result = 0;
  }
  restore_trailing_slash(directory_path, &path_length, &slash_stripped);
  return result;
}
Exemple #9
0
// START FUNC DECL
int
list_files(
    char *in_data_dir
	 )
// STOP FUNC DECL
{
  int status = 0;
  struct stat st;
  FILE *ofp = NULL;
  int ddir_id = INT_MAX;
  char data_dir[MAX_LEN_DIR_NAME+1];
  char filename[32];

  if ( ( in_data_dir == NULL ) || ( *in_data_dir == '\0' ) )  {
    ddir_id = 0; 
    status = chdir(g_ddirs[0].name); cBYE(status);
  }
  else {
    status = strip_trailing_slash(in_data_dir, data_dir, MAX_LEN_DIR_NAME+1);
    cBYE(status);
    status = get_ddir_id(data_dir, g_ddirs, g_n_ddir, false, &ddir_id);
    cBYE(status);
    if ( ddir_id < 0 ) { go_BYE(-1); }
    status = chdir(in_data_dir); cBYE(status);
  }

  ofp = stdout;
  for ( int i = 0; i < g_n_fld; i++ ) { 
    if ( g_flds[i].name[0] == '\0' ) { continue; } /* null entry */
    if ( ddir_id != g_flds[i].ddir_id ) { continue; }
    mk_file_name(filename, g_flds[i].fileno);
    status = stat(filename, &st); cBYE(status);
    unsigned long long size = st.st_size;
    if ( size <= 0 ) { go_BYE(-1); }
    fprintf(ofp, "%d,%llu,_%d\n", g_flds[i].is_external,size,g_flds[i].fileno);
  }
BYE:
  status = chdir(g_cwd);
  return(status);
}
Exemple #10
0
static int tar_find(mount_t *mnt, const char *filename, mtar_header_t *h) {
    /* Hash filename and linear search map for matching hash, read header and
     * check against filename if the hashes match */
    tar_mount_t *tm = mnt->udata;
    unsigned hash = hash_string_ignore_case(filename);
    int i;
    for (i = 0; i < tm->nfiles; i++) {

        if (tm->map[i].hash == hash) {
            /* Seek to and load header */
            mtar_seek(&tm->tar, tm->map[i].pos);
            mtar_read_header(&tm->tar, h);
            /* Compare names */
            strip_trailing_slash(h->name);
            if (strings_equal_ignore_case(h->name, filename)) {
                return FILESYSTEM_ESUCCESS;
            }
        }

    }
    return FILESYSTEM_EFAILURE;
}
Exemple #11
0
// START FUNC DECL
int
get_ddir_id(
	    char *in_data_dir,
	    DDIR_REC_TYPE *ddirs,
	    int n_ddirs,
	    bool add_if_missing,
	    int *ptr_ddir_id
	    )
// STOP FUNC DECL
{
  int status = 0;
  char data_dir[MAX_LEN_DIR_NAME+1];

  *ptr_ddir_id = INT_MIN;
  if ( is_absolute_path(in_data_dir) == false ) { go_BYE(-1); }

  status = strip_trailing_slash(in_data_dir, data_dir, MAX_LEN_DIR_NAME+1);
  cBYE(status);
  for ( int i = 0; i < n_ddirs; i++ ) { 
    if ( strcmp(ddirs[i].name, data_dir) == 0 ) {
      *ptr_ddir_id = i;
      break;
    }
  }
  if ( ( add_if_missing ) && ( *ptr_ddir_id < 0 ) )  {
    for ( int i = 0; i < n_ddirs; i++ ) { 
      if ( strlen(ddirs[i].name) == 0 ) { /* spot is empty. Pop it in here */
        strcpy(ddirs[i].name, data_dir);
        *ptr_ddir_id = i;
        break;
      }
    }
  }
  if ( *ptr_ddir_id < 0 ) { go_BYE(-1); } // no space 
 BYE:
  return status ;
}
Exemple #12
0
int
cmd_update(int argc, char **argv, struct mpd_connection *conn)
{
	if (contains_absolute_path(argc, argv) && !path_prepare(conn))
		printErrorAndExit(conn);

	if (!mpd_command_list_begin(conn, false))
		printErrorAndExit(conn);

	int i = 0;
	const char *update = "";
	if (argc > 0)
		update = charset_to_utf8(argv[i]);

	do {
		char *tmp = strdup(update);
		strip_trailing_slash(tmp);

		const char *path = tmp;
		const char *relative_path = to_relative_path(path);
		if (relative_path != NULL)
			path = relative_path;

		mpd_send_update(conn, path);
		free(tmp);
	} while (++i < argc && (update = charset_to_utf8(argv[i])) != NULL);

	if (!mpd_command_list_end(conn))
		printErrorAndExit(conn);

	/* obtain the last "update id" response */

	unsigned id = 0;
	while (true) {
		unsigned next_id = mpd_recv_update_id(conn);
		if (next_id == 0)
			break;
		id = next_id;
	}

	my_finishCommand(conn);

	while (options.wait) {
		/* idle until an update finishes */
		enum mpd_idle idle = mpd_run_idle_mask(conn, MPD_IDLE_UPDATE);
		struct mpd_status *status;
		unsigned current_id;

		if (idle == 0)
			printErrorAndExit(conn);

		/* determine the current "update id" */

		status = getStatus(conn);
		current_id = mpd_status_get_update_id(status);
		mpd_status_free(status);

		/* is our last queued update finished now? */

		if (current_id == 0 || current_id > id ||
		    (id > 1 << 30 && id < 1000)) /* wraparound */
			break;
	}

	return 1;
}
Exemple #13
0
struct stat_cache_value *stat_cache_value_get(stat_cache_t *cache, const char *path, bool skip_freshness_check) {
    struct stat_cache_value *value = NULL;
    char *key;
    leveldb_readoptions_t *options;
    size_t vallen;
    char *errptr = NULL;
    //void *f;
    time_t current_time;

    key = path2key(path, false);

    log_print(LOG_DEBUG, "CGET: %s", key);

    options = leveldb_readoptions_create();
    value = (struct stat_cache_value *) leveldb_get(cache, options, key, strlen(key) + 1, &vallen, &errptr);
    leveldb_readoptions_destroy(options);
    free(key);

    //log_print(LOG_DEBUG, "Mode: %04o", value->st.st_mode);

    if (errptr != NULL) {
        log_print(LOG_ERR, "leveldb_get error: %s", errptr);
        free(errptr);
        return NULL;
    }

    if (value == NULL) {
        log_print(LOG_DEBUG, "stat_cache_value_get miss on path: %s", path);
        return NULL;
    }

    if (vallen != sizeof(struct stat_cache_value)) {
        log_print(LOG_ERR, "Length %lu is not expected length %lu.", vallen, sizeof(struct stat_cache_value));
    }

    if (!skip_freshness_check) {
        current_time = time(NULL);

        // First, check against the stat item itself.
        //log_print(LOG_DEBUG, "Current time: %lu", current_time);
        if (current_time - value->updated > CACHE_TIMEOUT) {
            char *directory;
            time_t directory_updated;
            int is_dir;

            log_print(LOG_DEBUG, "Stat entry %s is %lu seconds old.", path, current_time - value->updated);

            // If that's too old, check the last update of the directory.
            directory = strip_trailing_slash(ne_path_parent(path), &is_dir);
            directory_updated = stat_cache_read_updated_children(cache, directory);
            //log_print(LOG_DEBUG, "Directory contents for %s are %lu seconds old.", directory, (current_time - directory_updated));
            free(directory);
            if (current_time - directory_updated > CACHE_TIMEOUT) {
                log_print(LOG_DEBUG, "%s is too old.", path);
                free(value);
                return NULL;
            }
        }
    }

    /*
    if ((f = file_cache_get(path))) {
        value->st.st_size = file_cache_get_size(f);
        file_cache_unref(cache, f);
    }
    */

    //print_stat(&value->st, "CGET");

    return value;
}
Exemple #14
0
// START FUNC DECL
int
orphan_files(
    char *in_data_dir,
    char *action
    )
// STOP FUNC DECL
{
  int status = 0;
  DIR *dp = NULL; FILE *ofp = NULL;
  struct dirent *ep = NULL;     
  char Xopfile[MAX_LEN_FILE_NAME+1];
  char Yopfile[MAX_LEN_FILE_NAME+1];
  char *X = NULL; size_t nX = 0;
  char *Y = NULL; size_t nY = 0;
  char nullc = '\0';
  int Xnum_files = 0, Ynum_files = 0;
  int ddir_id;
  char data_dir[MAX_LEN_DIR_NAME+1];

  if ( ( in_data_dir == NULL ) || ( *in_data_dir == '\0' ) ) {
    status = chdir(g_data_dir); cBYE(status);
    ddir_id = -1;
    if ( strlen(g_data_dir) >= MAX_LEN_DIR_NAME ) { go_BYE(-1); }
    strcpy(data_dir, g_data_dir);
  }
  else {
    status = strip_trailing_slash(in_data_dir, data_dir, MAX_LEN_DIR_NAME+1);
    cBYE(status);
    status = get_ddir_id(data_dir, g_ddirs, g_n_ddir, false, &ddir_id);
    cBYE(status);
    status = chdir(data_dir); cBYE(status);
  }

  zero_string(Xopfile, MAX_LEN_FILE_NAME+1);
  zero_string(Yopfile, MAX_LEN_FILE_NAME+1);

  /* START: Create X. X = filenames listed in the meta data (whose 
   * ddir_id matches that requested) in sorted order */
  status = open_temp_file(g_cwd, g_cwd, Xopfile, 0); cBYE(status);
  ofp = fopen(Xopfile, "w"); 
  return_if_fopen_failed(ofp, Xopfile, "w");
  for ( int i = 0; i < g_n_fld; i++ ) { 
    if ( g_flds[i].name[0] == '\0' ) { continue; }
    if ( g_flds[i].ddir_id != ddir_id ) { continue; }
    Xnum_files++;
    fwrite(g_flds[i].filename, sizeof(char), MAX_LEN_FILE_NAME+1, ofp);
  }
  fclose_if_non_null(ofp);
  if ( Xnum_files > 0 ) { 
    status = rs_mmap(Xopfile, &X, &nX, 1);
    qsort(X, Xnum_files, MAX_LEN_FILE_NAME+1, str_compare);
  }
  /* STOP ---- */

  status = open_temp_file(g_cwd, g_cwd, Yopfile, 0); cBYE(status);
  ofp = fopen(Yopfile, "w"); 
  return_if_fopen_failed(ofp, Xopfile, "w");
  dp = opendir(data_dir);
  if ( dp == NULL) { go_BYE(-1); }
  for ( ; ; ) { 
    ep = readdir (dp);
    if ( ep == NULL ) { break; }
    char *filename = ep->d_name;
    if ( ( filename == NULL ) || ( *filename == '\0' ) )  { break; }
    if ( strncmp(filename, "docroot", 7) == 0  ) { continue; }
    if ( strncmp(filename, ".LDB_META", 9) == 0  ) { continue; }
    if ( strcmp(filename, "..") == 0  ) { continue; }
    if ( strcmp(filename, ".") == 0  ) { continue; }
    int len = strlen(filename);
    if ( len >= MAX_LEN_FILE_NAME ) {
      // This is clearly no good 
      fprintf(stdout, "%s\n", filename);
    }
    else {
      Ynum_files++;
      fwrite(filename, sizeof(char), len, ofp);
      for ( int i = len; i < MAX_LEN_FILE_NAME+1; i++ ) { 
        fwrite(&nullc, sizeof(char), 1, ofp);
      }
    }
  }
  fclose_if_non_null(ofp);
  (void) closedir (dp);
  if ( Ynum_files > 0 ) { 
    status = rs_mmap(Yopfile, &Y, &nY, 1);
    qsort(Y, Ynum_files, MAX_LEN_FILE_NAME+1, str_compare);
  }
  /* Now compare X against Y */
  char *xptr = X;
  char *yptr = Y;
  int seenX = 0, seenY = 0;
  for ( ; ( ( seenX < Xnum_files ) && ( seenY < Ynum_files ) ) ; ) {
    int cmpval = str_compare(xptr, yptr);
    switch ( cmpval ) { 
      case 0 : 
      /* File in meta data exists on disk. This is good */
      xptr += MAX_LEN_FILE_NAME+1;
      yptr += MAX_LEN_FILE_NAME+1;
      seenX++;
      seenY++;
      break;
      case -1 : 
      /* File exists in meta data but not on disk. This is horrendous */
      printf("HORRENDOUS %s\n", yptr);
      xptr += MAX_LEN_FILE_NAME+1;
      seenX++;

      break;
      case 1 : 
      /* File on disk but not in meta data. This is an "orphan" * */
      printf("%s\n", yptr);
      yptr += MAX_LEN_FILE_NAME+1;
      seenY++;
      break;
      default : 
      go_BYE(-1);
      break;
    }
  }
  if ( seenX < Xnum_files ) {
    for ( ; seenX < Xnum_files ; seenX++ ) {
      fprintf(stderr, "MISSING FILE %s\n", xptr);
      xptr += MAX_LEN_FILE_NAME;
      seenX++;
    }
  }
  if ( seenY < Ynum_files ) {
    for ( ; seenY < Ynum_files ; seenY++ ) {
      fprintf(stderr, "%s\n", yptr);
      yptr += MAX_LEN_FILE_NAME;
      seenY++;
    }
  }


BYE:
  fclose_if_non_null(ofp);
  unlink_if_non_null(Xopfile); 
  unlink_if_non_null(Yopfile);
  return(status);
}
Exemple #15
0
int main(int argc, char** argv)
{
    // Print an error if the user invokes Far with an incorrect number of
    // arguments. There should be at least "Far key archive"
    if (argc < 3) {
        ERROR("Usage: Far key archive [name]*");
        return 1;
    }

    char* key = argv[1];
    char* archive_name = argv[2];

    int num_files = argc - 3;
    char** filenames = argv + 3;

    // Ignore trailing / in NAME arguments
    for (int i = 0; i < num_files; i++) strip_trailing_slash(filenames[i]);

    if (!strcmp(key, "r")) {
        member_list* members = make_list_recursive(filenames, num_files);
        archive_t* archive = open_archive(archive_name, true);
        member_list* processed_members =
          process_members(archive, members, replace_current_member);
        // Now that previously existing files have been deleted, add the
        // files to the end of the archive
        member_node* cur_member = members;
        while (cur_member) {
            add_member(archive, cur_member->filename);
            cur_member = cur_member->next;
        }
        delete_list(processed_members);
        close_archive(archive, true);

        delete_list(members);
        return 0;
    } else if (!strcmp(key, "x")) {
        member_list* members = make_list(filenames, num_files);
        archive_t* archive = open_archive(archive_name, false);
        member_list* processed_members =
          process_members(archive, members, extract_current_member);
        // Error handling for unprocessed NAME arguments
        for (int i = 0; i < num_files; i++) {
            char* name = filenames[i];
            if (!find_member(name, processed_members)) {
                ERROR_CREATE(name);
            }
        }
        delete_list(processed_members);
        close_archive(archive, false);

        delete_list(members);
        return 0;
    } else if (!strcmp(key, "d")) {
        member_list* members = make_list(filenames, num_files);
        archive_t* archive = open_archive(archive_name, false);
        member_list* processed_members =
          process_members(archive, members, delete_current_member);
        // Error handling for unprocessed NAME arguments
        for (int i = 0; i < num_files; i++) {
            char* name = filenames[i];
            if (!find_member(name, processed_members) &&
                !find_child(name, processed_members)) {
                ERROR_FIND(name);
            }
        }
        delete_list(processed_members);
        close_archive(archive, true);

        delete_list(members);
        return 0;
    } else if (!strcmp(key, "t")) {
        archive_t* archive = open_archive(archive_name, false);
        member_list* processed_members =
          process_members(archive, NULL, print_current_member);
        delete_list(processed_members);
        close_archive(archive, false);
        return 0;
    } else {
        ERROR("Key options: 'r', 'x', 'd', 't'");
        return 1;
    }
}
Exemple #16
0
static int tar_mount(mount_t *mnt, const char *path) {
    tar_mount_t *tm = NULL;
    FILE *fp = NULL;

    /* Try to open file */
    fp = fopen(path, "rb");
    if (!fp) {
        goto fail;
    }

    /* Init tar_mount_t */
    tm = dmt_calloc(1, sizeof(*tm));
    tm->fp = fp;

    /* Init tar */
    mtar_t *tar = &tm->tar;
    tar->read = tar_stream_read;
    tar->seek = tar_stream_seek;
    tar->close = tar_stream_close;
    tar->stream = tm;

    /* Check start of file for valid tar header */
    mtar_header_t h;
    int err = mtar_read_header(tar, &h);

    /* If checking the start of the file failed then check the end of file for a
     * "TAR\0" tag and offset, this would have been added when packaging (see
     * `package.c`) to indicate the offset of the tar archive's beginning from the
     * file's end */
    if (err) {
        int offset;
        char buf[4] = "";
        fseek(fp, -8, SEEK_END);
        fread(buf, 1, 4, fp);
        fread(&offset, 1, 4, fp);
        if ( !memcmp(buf, "TAR\0", 4) ) {
            fseek(fp, -offset, SEEK_END);
            tm->offset = ftell(fp);
        }
        mtar_rewind(tar);
        err = mtar_read_header(tar, &h);
        if (err) {
            goto fail;
        }
    }

    /* Iterate all files and store [namehash:position] pairs; this is used by
     * tar_find() */
    mtar_rewind(tar);
    int n = 0;
    int cap = 0;
    while ( (mtar_read_header(tar, &h)) == MTAR_ESUCCESS ) {
        /* Realloc if map capacity was reached */
        if (n >= cap) {
            cap = cap ? (cap << 1) : 16;
            tm->map = dmt_realloc(tm->map, cap * sizeof(*tm->map));
        }
        /* Store entry */
        strip_trailing_slash(h.name);
        tm->map[n].hash = hash_string_ignore_case(h.name);
        tm->map[n].pos = tar->pos;
        /* Next */
        mtar_next(tar);
        n++;
    }
    tm->nfiles = n;

    /* Init mount */
    mnt->udata = tar;
    mnt->unmount = tar_unmount;
    mnt->exists = tar_exists;
    mnt->isFile = tar_isFile;
    mnt->isDirectory = tar_isDirectory;
    mnt->read = tar_read;

    /* Return ok */
    return FILESYSTEM_ESUCCESS;

fail:
    if (fp) fclose(fp);
    if (tm) {
        dmt_free(tm->map);
        dmt_free(tm);
    }
    return FILESYSTEM_EFAILURE;
}
Exemple #17
0
// START FUNC DECL
int
orphan_files(
    char *in_data_dir
    )
// STOP FUNC DECL
{
  int status = 0;
  DIR *dp = NULL; 
  struct dirent *ep = NULL;     
  int ddir_id;
  char data_dir[MAX_LEN_DIR_NAME+1];
  int files_in_meta[MAX_NUM_FLDS]; int num_files_in_meta = 0;
  bool is_seen[MAX_NUM_FLDS];

  zero_string(data_dir, (MAX_LEN_DIR_NAME+1));
  for ( int i = 0; i < MAX_NUM_FLDS; i++ ) { is_seen[i] = 0; } 
  /*------------------------------------------------------------------*/

  if ( ( in_data_dir == NULL ) || ( *in_data_dir == '\0' ) ) {
    if ( strlen(g_data_dir) >= MAX_LEN_DIR_NAME ) { go_BYE(-1); }
    strcpy(data_dir, g_data_dir);
    ddir_id = -1;
    status = chdir(g_data_dir); cBYE(status);
  }
  else {
    status = strip_trailing_slash(in_data_dir, data_dir, MAX_LEN_DIR_NAME+1);
    cBYE(status);
    status = get_ddir_id(data_dir, g_ddirs, g_n_ddir, false, &ddir_id);
    cBYE(status);
    status = chdir(data_dir); cBYE(status);
  }
  /* START: Create files_in_meta =  files listed in the meta data (whose 
   * ddir_id matches that requested) in sorted order */
  for ( int i = 0; i < g_n_fld; i++ ) { 
    if ( g_flds[i].name[0] == '\0' ) { continue; }
    if ( g_flds[i].ddir_id != ddir_id ) { continue; }
    files_in_meta[num_files_in_meta++] = g_flds[i].fileno;
  }
  /* STOP ---- */
  dp = opendir(data_dir);
  if ( dp == NULL) { go_BYE(-1); }
  for ( ; ; ) { 
    ep = readdir (dp);
    if ( ep == NULL ) { break; }
    char *filename = ep->d_name;
    if ( ( filename == NULL ) || ( *filename == '\0' ) )  { break; }
    if ( strncmp(filename, "docroot", 7) == 0  ) { continue; }
    if ( strcmp(filename, "..") == 0  ) { continue; }
    if ( strcmp(filename, ".") == 0  ) { continue; }
    int len = strlen(filename);
    bool is_bad = false;
    if ( len >= MAX_DIGITS_IN_I4 ) { is_bad = true; }
    if ( filename[0] != '_'  ) { is_bad = true; }
    for ( char *cptr = filename+1; *cptr != '\0'; cptr++ ) { 
      if ( !isdigit(*cptr) ) { is_bad = true; break; }
    }
    /* Check if it is in meta data */
    char *endptr;
    int fileno = strtoll(filename+1, &endptr, 10); 
    if ( *endptr != '\0' ) { go_BYE(-1); }
    bool is_in_meta = false;
    for ( int i = 0; i < num_files_in_meta; i++ ) { 
      if ( fileno == files_in_meta[i] ) {
	is_seen[i]= true;
        is_in_meta = true;
	break; 
      }
    }
    if ( is_in_meta == false ) { is_bad = true; }
    if ( is_bad ) { 
      fprintf(stdout, "%s\n", filename);
    }
  }
  /* Now look for files that are not on disk. This is catastrophic */
  for ( int i = 0; i < g_n_fld; i++ ) { 
    if ( g_flds[i].name[0] == '\0' ) { continue; }
    if ( g_flds[i].ddir_id != ddir_id ) { continue; }
    int fileno = g_flds[i].fileno;
    for ( int j = 0; j < num_files_in_meta; j++ ) { 
      if ( files_in_meta[j] != fileno ) { continue; }
      if ( is_seen[j] == false ) { 
	fprintf(stdout,"CATASTROPHIC,%d\n", fileno);
      }
    }
  }
BYE:
  chdir(g_cwd);
  return(status);
}