Example #1
0
/*
  sync two meta data changes for 2 names
 */
static void syncops_two_names(const char *name1, const char *name2)
{
	TALLOC_CTX *tmp_ctx = talloc_new(NULL);
	char *parent1, *parent2;
	parent1 = parent_dir(tmp_ctx, name1);
	parent2 = parent_dir(tmp_ctx, name2);
	if (!parent1 || !parent2) {
		talloc_free(tmp_ctx);
		return;
	}
	syncops_sync_directory(parent1);
	if (strcmp(parent1, parent2) != 0) {
		syncops_sync_directory(parent2);		
	}
	talloc_free(tmp_ctx);
}
Example #2
0
QIcon* get( NamedSymbol* ns )
{
  Parameter* opts = get_options( ns );
  Locator* l = get_locator( ns );
  int gt = get_grist_type( ns );

  opts = find_by_hash( opts, hashlittle( "cts" ) );
  opts = find_child_by_hash( opts, hashlittle( "icon" ) );
  if( opts && !safe_to_convert( opts, E_VART_STRING ) )
    opts = 0x0;

  QIcon* icon = 0x0;

  if( opts )
  {
    QFileInfo fi( l->m_Buffer );
    QDir parent_dir( fi.absoluteDir() );
    QString qstr = parent_dir.absoluteFilePath( QString( as_string( *opts )->m_Raw ) );
    std::string stdstr( qstr.toStdString() );
    icon = get( stdstr.c_str() );
  }

  if( !icon )
    icon = get( g_NodeSVGResourcePaths[gt] );

  return icon;
}
/**
 * @brief Returns the index of the specified path.
 *
 * The column of the returned index is always FILE_COLUMN.
 *
 * @param path Path of a file.
 * @return The corresponding index. An invalid index is returned if the path
 * does not exist in the model.
 */
QModelIndex QuestFilesModel::get_file_index(const QString& path) const {

  const QModelIndex& index_from_source = mapFromSource(source_model->index(path, 0));
  if (index_from_source.isValid()) {
    // The path exists in the source model and therefore on the filesystem.
    return index_from_source;
  }

  // The file does not exist.
  // It can be a resource element added to the tree but whose file is missing.
  // Find its place in the tree to know the row.
  QDir parent_dir(path);
  if (!parent_dir.cdUp()) {
    return QModelIndex();
  }
  const QModelIndex& parent = get_file_index(parent_dir.path());

  const ExtraPaths* extra_paths = get_extra_paths(parent);
  if (extra_paths == nullptr) {
    // Path not in the model.
    return QModelIndex();
  }

  const auto& it = extra_paths->path_indexes.find(path);
  if (it == extra_paths->path_indexes.end()) {
    // Path not in the model.
    return QModelIndex();
  }
  const int index_in_extra = it.value();
  const int row = QSortFilterProxyModel::rowCount(parent) + index_in_extra;
  return index(row, 0, parent);
}
Example #4
0
static void update_dir_has_rating_color (GjayApp *gjay, const gchar * dir ) {
    gchar * parent;
    gchar * str;
    
	if (dir == NULL)
	  return;
    str = g_hash_table_lookup(gjay->new_song_dirs_hash, dir);
    if (!str) 
        return;

    if (explore_dir_has_new_songs(gjay->gui->explore_page,
                                  gjay->songs->name_hash, dir,
                                  gjay->verbosity))
        return;

    /* This directory used to be marked, but no longer is. Change its
       icon, remove info */
    explore_path_set_icon(gjay->gui->explore_page, dir,
                          gjay->gui->pixbufs[PM_DIR_CLOSED]);
    
    g_hash_table_remove(gjay->new_song_dirs_hash, str);
    gjay->new_song_dirs = g_list_remove(gjay->new_song_dirs, str);
    g_free(str);
    
    /* Check the parent directory */
    parent = parent_dir (gjay->prefs->song_root_dir, gjay->prefs->song_root_dir);
    update_dir_has_rating_color(gjay, parent);
    g_free(parent);
} 
Example #5
0
/*
  sync two meta data changes for 1 names
 */
static void syncops_smb_fname(const struct smb_filename *smb_fname)
{
	char *parent;
	parent = parent_dir(NULL, smb_fname->base_name);
	if (parent) {
		syncops_sync_directory(parent);
		talloc_free(parent);
	}
}
Example #6
0
/* Adds any events that should occur given a read from the specified
 * filename.
 *
 * This destroys the contents of filename.
 */
static void add_events(char* filename) {
#ifdef DEBUG
  add_one_event(event_print, filename);
#endif
  if (parent_dir(filename)) {
    if (!hs_test(directories_read, filename)) {
      add_one_event(event_read_siblings, filename);
      hs_put(directories_read, filename);
    }

    do {
      if (!hs_test(directories_traversed, filename)) {
        add_one_event(event_iterate_directory, filename);
        hs_put(directories_traversed, filename);
      }
    } while (parent_dir(filename));
  }
}
Example #7
0
/*
  sync two meta data changes for 1 names
 */
static void syncops_name(const char *name)
{
	char *parent;
	parent = parent_dir(NULL, name);
	if (parent) {
		syncops_sync_directory(parent);
		talloc_free(parent);
	}
}
inline void remove_file()
{
    switch(is_file())
    {
        case true:
        boost::filesystem::remove(file);
        restart_file(parent_dir() + build_slash(), "");
        break;
    }
};
Example #9
0
static void update_song_has_rating_color ( GjayApp *gjay, GjaySong * s ) {
    gchar * dir;
    
    for (; s->repeat_prev; s = s->repeat_prev)
        ;
    for (; s; s = s->repeat_next) {
        dir = parent_dir(gjay->prefs->song_root_dir, s->path);
        update_dir_has_rating_color(gjay, dir);
        g_free(dir);
    }
}
/**
 * @brief Returns the parent of the model item with the given index.
 *
 * Reimplemented from QSortFilterProxyModel to support extra indexes
 * that do not exist in the source model.
 *
 * @param index Index to get the parent of.
 * @return The parent index, or an invalid index if the item has no parent.
 */
QModelIndex QuestFilesModel::parent(const QModelIndex& index) const {

  QString path;
  if (is_extra_path(index, path)) {
    // Index that does not exist in the source model.
    QDir parent_dir(path);
    if (!parent_dir.cdUp()) {
      return QModelIndex();
    }
    return get_file_index(parent_dir.path());
  }

  // Regular QSortFilterProxyModel index.
  return QSortFilterProxyModel::parent(index);
}
Example #11
0
File: rom.c Project: mrzzzrm/mooboy
static void rom_input_event(int type, int key) {
    menu_list_input(list, type, key);

    if(type == SDL_KEYDOWN) {
        switch(key) {
            case SDLK_RIGHT:
                if(!direntries[list->selected]->is_file && strcmp(direntries[list->selected]->name, "..")) {
                    change_dir();
                }
            break;
            case SDLK_LEFT:
                parent_dir();
            break;
        }
        if(isprint(key)) {
            if(!jump_to(list->selected + 1, key)) {
                jump_to(0, key);
            }
        }
    }
}
Example #12
0
bool SLAVLogic::needToOverwriteBaseInstall() {
    // case 1: we run from temp installation and CurrentChannel != BaseChannel || CurrentVersion>=BaseVersion
    QString apppath = qApp->applicationDirPath();
    QString workdir = QDir::currentPath();
    if(workdir.endsWith("install_temp")) {
        QDir parent_dir(workdir);
        if(!parent_dir.cdUp()) {
            qDebug() << "Cd up from temp install dir fails";
            return false;
        }
        AppVersionManifest parent_dir_manifest;
        if(QFile::exists(parent_dir.filePath("project.manifest"))) {
            QFile manifest_contents(parent_dir.filePath("project.manifest"));
            if(!manifest_contents.open(QFile::ReadOnly)) {
                qDebug() << "Cannot open parent dir manifest";
                return false;
            }
            if(!loadFrom(parent_dir_manifest,manifest_contents.readAll())) {
                qDebug() << "Failed to parse manifest contents";
                parent_dir_manifest.buildFromFileSystem(parent_dir.path());
            }
        }
    }
    AppVersionManifest current_manifest;
    QString manifest_path = workdir + "/project.manifest";
    if(QFile::exists(manifest_path)) {
        QFile manifest_contents(manifest_path);
        if(!manifest_contents.open(QFile::ReadOnly)) {
            qDebug() << "Cannot open parent dir manifest";
            return false;
        }
        if(!loadFrom(current_manifest,manifest_contents.readAll())) {
            qDebug() << "Failed to parse manifest contents";
        }
    }
    current_manifest.buildFromFileSystem(workdir);
    return false;
}
Example #13
0
status_t 
FolderShaper::ShapeRef	(entry_ref * a_ref, const char * a_template, bool a_do_open)
{
	PRINT(("ShapeRef(%s, %s)\n", a_ref->name, a_template));

	status_t	status;

// store original_name
	
	BEntry	original_entry	(a_ref, true);
	original_entry.	GetRef	(a_ref);
	BString original_name 	= a_ref->name;
	BPath	original_path	(& original_entry);
	
	BString original_path_string = original_path.Path();
	NameSafe(& original_path_string);

	BPath	original_parent_path;
	original_path.GetParent(& original_parent_path);

	BDirectory parent_dir(original_parent_path.Path());

//	temp name
	BString new_name	=	a_ref->name;
	new_name.Prepend("New ");

	int32	counter	=	2;
	while(parent_dir.Contains(new_name.String()))
	{
		new_name = a_ref->name;
		new_name.Append(" (temporary ");
		new_name << counter;
		new_name.Append(")");		
		counter	++;
	}

	PRINT(("original_name: %s\n", original_name.String()));
	PRINT(("new_name: %s\n", new_name.String()));	
	
	PRINT(("original_path: %s\n", original_path.Path()));	
	PRINT(("original_path_string: %s\n", original_path_string.String()));	
	PRINT(("original_parent_path: %s\n", original_parent_path.Path()));	

	
	BPath	template_path	(m_tmpl_dir, a_template);

	BEntry	tmp_entry;		// traverse link to template
	if ((status = tmp_entry.SetTo(template_path.Path(), true)) != B_OK)
	{
		// message
		return status;
	}
	template_path.SetTo(& tmp_entry);
	
	BString	template_path_string 	=	template_path.Path();
	NameSafe(& template_path_string);
	PRINT(("template_path_string: %s\n", template_path_string.String()));		

	BPath	new_path	(original_parent_path.Path(), new_name.String());
	BString	new_path_string	=	new_path.Path();
	NameSafe(& new_path_string);
	PRINT(("new_path_string: %s\n", new_path_string.String()));			

	BString command;

	if(m_do_keep_position)
	{
		//	copy X/Y position attribute from Original Folder

		command = "copyattr -n _trk/pinfo_le ";
		command.Append(original_path_string);
		command.Append(" ");
		command.Append(template_path_string);
		
		PRINT(("copy X/Y position: \n%s\n", command.String()));
	
		system(command.String());
	}
	else
	{
		BNode template_node(& tmp_entry);
		template_node.RemoveAttr("_trk/pinfo_le");
	}
		
	
//	copy template -> "New name" (temp)

	command = "copyattr -d -r ";
	command.Append(template_path_string);
	command.Append(" ");
	command.Append(new_path_string);
	
	PRINT(("copy template -> temp: \n%s\n", command.String()));
	
	system(command.String());
	
//	New folder exists?

	BDirectory	new_directory;
	if((status = new_directory.SetTo(new_path.Path())) != B_OK)
	{
		ErrorMessage("new_directory.SetTo() ", status);	// ... probably want a BAlert
		return status;
	}
	
	BDirectory original_dir;
	if((status = original_dir.SetTo(original_path.Path())) != B_OK)
	{
		ErrorMessage("original_dir.SetTo() ", status);	// ... probably want a BAlert
		return status;
	}
	
//	Move stuff from original folder to new folder	
	BEntry	original_content_entry;
	while(original_dir.GetNextEntry(&original_content_entry) == B_OK)
	{
		if ((status = original_content_entry
			.MoveTo(& new_directory, NULL, ! m_do_clobber))	!= B_OK 
			&& (status != B_FILE_EXISTS || (! m_do_clobber) == true))
		{	
			ErrorMessage("original_content_entry.MoveTo() ", status);
			return status;							// ... definitely needs a fat BAlert
		}
	}

//	Move original folder to Trash
//	alt.
//  Delete

	bool was_open = false;
	
	if (m_do_move)
	{
		//	Is Folder Open ?
		was_open =	IsFolderOpen(a_ref);
		
		//	Close Original Folder	
		status	=	MoveRefToTrash(a_ref);	// This calls Tracker to move the ref.
											// If the folder is open, Tracker will close it.

		for (int j = 0; j < 250; j++)
		{
			PRINT(("loop: %d\n", j));
		
			if (original_entry.Exists() == false)
				break;
			
			snooze(20000);		// give Tracker some Time to Move
			// .... consider using node-monitoring instead to 
			// catch when Tracker has moved the folder to Trash
		}
	}
	else
	{
		status = original_entry.Remove();
		if (status != B_OK)
		{
			ErrorMessage("original_content_entry.MoveTo() ", status);
			// BAlert.. Could not remove original folder
			// return status;
		}
	}	
	
//	Rename New Folder -> Original Name
	BEntry	new_entry(new_path.Path());
	status = new_entry.Rename(original_name.String());
	if (status != B_OK)
		ErrorMessage("new_entry.Rename() ", status);
	
	entry_ref	new_ref;
	status = new_entry.GetRef(& new_ref);
	if (status != B_OK)
		ErrorMessage("new_entry.GetRef() ", status);
	
//	Open New Folder
	if (was_open) PRINT(("was_open == true\n"));
	if (! was_open) PRINT(("was_open == false\n"));
		
	if (((m_do_open == FS_IF_ORIGINAL_OPEN) && was_open) || m_do_open == FS_ALWAYS_OPEN)
	{
		// open folder
		command =	original_path_string;
		command.Prepend("/boot/system/Tracker ");
		command.Append(" &");
		
		system(command.String());
		
		// wait for new folder to open
		WaitForOpeningFolder(& new_ref);
		
		//	Clean Up All	
		if (m_do_clean_up)
			CleanUpWindow(& new_ref);
	}
	
	return B_OK;
}
static int
process_regular_file(int pl_id, char *path)
{
  struct query_params qp;
  char filter[PATH_MAX];
  const char *a;
  const char *b;
  char *dbpath;
  char *winner;
  int score;
  int i;
  int ret;

  // Playlist might be from Windows so we change backslash to forward slash
  for (i = 0; i < strlen(path); i++)
    {
      if (path[i] == '\\')
	path[i] = '/';
    }

  ret = db_snprintf(filter, sizeof(filter), "f.fname = '%q' COLLATE NOCASE", filename_from_path(path));
  if (ret < 0)
    {
      DPRINTF(E_LOG, L_SCAN, "Path in playlist is too long: '%s'\n", path);
      return -1;
    }

  memset(&qp, 0, sizeof(struct query_params));

  qp.type = Q_BROWSE_PATH;
  qp.sort = S_NONE;
  qp.filter = filter;

  ret = db_query_start(&qp);
  if (ret < 0)
    {
      db_query_end(&qp);
      return -1;
    }

  winner = NULL;
  score = 0;
  while ((db_query_fetch_string(&qp, &dbpath) == 0) && dbpath)
    {
      if (qp.results == 1)
	{
	  winner = strdup(dbpath);
	  break;
	}

      for (i = 0, a = NULL, b = NULL; (parent_dir(&a, path) == 0) && (parent_dir(&b, dbpath) == 0) && (strcasecmp(a, b) == 0); i++)
	;

      DPRINTF(E_SPAM, L_SCAN, "Comparison of '%s' and '%s' gave score %d\n", dbpath, path, i);

      if (i > score)
	{
	  free(winner);
	  winner = strdup(dbpath);
	  score = i;
	}
      else if (i == score)
	{
	  free(winner);
	  winner = NULL;
	}
    }

  db_query_end(&qp);

  if (!winner)
    {
      DPRINTF(E_LOG, L_SCAN, "No file in the library matches playlist entry '%s'\n", path);
      return -1;
    }

  DPRINTF(E_DBG, L_SCAN, "Adding '%s' to playlist %d (results %d)\n", winner, pl_id, qp.results);

  db_pl_add_item_bypath(pl_id, winner);
  free(winner);

  return 0;
}
Example #15
0
/*
 * This is called during restore to create the file (if necessary) We must return in rp->create_status:
 *
 *  CF_ERROR    -- error
 *  CF_SKIP     -- skip processing this file
 *  CF_EXTRACT  -- extract the file (i.e.call i/o routines)
 *  CF_CREATED  -- created, but no content to extract (typically directories)
 */
static bRC createFile(bpContext *ctx, struct restore_pkt *rp)
{
   int status;
   bool exists = false;
   struct stat st;
   plugin_ctx *p_ctx = (plugin_ctx *)ctx->pContext;

   if (!p_ctx) {
      return bRC_Error;
   }

   /*
    * See if the file already exists.
    */
   Dmsg2(400, "Replace=%c %d\n", (char)rp->replace, rp->replace);
   status = ceph_lstat(p_ctx->cmount, rp->ofname, &st);
   if (status == 0) {
      exists = true;

      switch (rp->replace) {
      case REPLACE_IFNEWER:
         if (rp->statp.st_mtime <= st.st_mtime) {
            Jmsg(ctx, M_SKIPPED, 0, _("File skipped. Not newer: %s\n"), rp->ofname);
            rp->create_status = CF_SKIP;
            goto bail_out;
         }
         break;
      case REPLACE_IFOLDER:
         if (rp->statp.st_mtime >= st.st_mtime) {
            Jmsg(ctx, M_SKIPPED, 0, _("File skipped. Not older: %s\n"), rp->ofname);
            rp->create_status = CF_SKIP;
            goto bail_out;
         }
         break;
      case REPLACE_NEVER:
         /*
          * Set attributes if we created this directory
          */
         if (rp->type == FT_DIREND && path_list_lookup(p_ctx->path_list, rp->ofname)) {
            break;
         }
         Jmsg(ctx, M_SKIPPED, 0, _("File skipped. Already exists: %s\n"), rp->ofname);
         rp->create_status = CF_SKIP;
         goto bail_out;
      case REPLACE_ALWAYS:
         break;
      }
   }

   switch (rp->type) {
   case FT_LNKSAVED:                  /* Hard linked, file already saved */
   case FT_LNK:
   case FT_SPEC:                      /* Fifo, ... to be backed up */
   case FT_REGE:                      /* Empty file */
   case FT_REG:                       /* Regular file */
      /*
       * See if file already exists then we need to unlink it.
       */
      if (exists) {
         Dmsg1(400, "unlink %s\n", rp->ofname);
         status = ceph_unlink(p_ctx->cmount, rp->ofname);
         if (status != 0) {
            berrno be;

            Jmsg(ctx, M_ERROR, 0,
                 _("File %s already exists and could not be replaced. ERR=%s.\n"),
                 rp->ofname, be.bstrerror(-status));
            /*
             * Continue despite error
             */
         }
      } else {
         /*
          * File doesn't exist see if we need to create the parent directory.
          */
         POOL_MEM parent_dir(PM_FNAME);
         char *bp;

         pm_strcpy(parent_dir, rp->ofname);
         bp = strrchr(parent_dir.c_str(), '/');
         if (bp) {
            *bp = '\0';
            if (strlen(parent_dir.c_str())) {
               if (!cephfs_makedirs(p_ctx, parent_dir.c_str())) {
                  rp->create_status = CF_ERROR;
                  goto bail_out;
               }
            }
         }
      }

      /*
       * See if we need to perform anything special for the restore file type.
       */
      switch (rp->type) {
      case FT_LNKSAVED:
         status = ceph_link(p_ctx->cmount, rp->olname, rp->ofname);
         if (status < 0) {
            berrno be;

            Jmsg(ctx, M_ERROR, "ceph_link(%s) failed: %s\n", rp->ofname, be.bstrerror(-status));
            rp->create_status = CF_ERROR;
         } else {
            rp->create_status = CF_CREATED;
         }
         break;
      case FT_LNK:
         status = ceph_symlink(p_ctx->cmount, rp->olname, rp->ofname);
         if (status < 0) {
            berrno be;

            Jmsg(ctx, M_ERROR, "ceph_symlink(%s) failed: %s\n", rp->ofname, be.bstrerror(-status));
            rp->create_status = CF_ERROR;
         } else {
            rp->create_status = CF_CREATED;
         }
         break;
      case FT_SPEC:
         status = ceph_mknod(p_ctx->cmount, rp->olname, rp->statp.st_mode, rp->statp.st_rdev);
         if (status < 0) {
            berrno be;

            Jmsg(ctx, M_ERROR, "ceph_mknod(%s) failed: %s\n", rp->ofname, be.bstrerror(-status));
            rp->create_status = CF_ERROR;
         } else {
            rp->create_status = CF_CREATED;
         }
         break;
      default:
         rp->create_status = CF_EXTRACT;
         break;
      }
      break;
   case FT_DIRBEGIN:
   case FT_DIREND:
      if (!cephfs_makedirs(p_ctx, rp->ofname)) {
         rp->create_status = CF_ERROR;
      } else {
         rp->create_status = CF_CREATED;
      }
      break;
   case FT_DELETED:
      Jmsg(ctx, M_INFO, 0, _("Original file %s have been deleted: type=%d\n"), rp->ofname, rp->type);
      break;
   default:
      Jmsg(ctx, M_ERROR, 0, _("Unknown file type %d; not restored: %s\n"), rp->type, rp->ofname);
      break;
   }

bail_out:
   return bRC_OK;
}
static int
mfi_id_find(const char *path)
{
  struct query_params qp;
  char filter[PATH_MAX];
  const char *a;
  const char *b;
  char *dbpath;
  char *winner;
  int score;
  int i;
  int ret;

  ret = db_snprintf(filter, sizeof(filter), "f.fname = '%q' COLLATE NOCASE", filename_from_path(path));
  if (ret < 0)
    {
      DPRINTF(E_LOG, L_SCAN, "Location in iTunes XML is too long: '%s'\n", path);
      return -1;
    }

  memset(&qp, 0, sizeof(struct query_params));

  qp.type = Q_BROWSE_PATH;
  qp.sort = S_NONE;
  qp.filter = filter;

  ret = db_query_start(&qp);
  if (ret < 0)
    {
      db_query_end(&qp);
      return -1;
    }

  winner = NULL;
  score = 0;
  while ((db_query_fetch_string(&qp, &dbpath) == 0) && dbpath)
    {
      if (qp.results == 1)
	{
	  winner = strdup(dbpath);
	  break;
	}

      for (i = 0, a = NULL, b = NULL; (parent_dir(&a, path) == 0) && (parent_dir(&b, dbpath) == 0) && (strcasecmp(a, b) == 0); i++)
	;

      DPRINTF(E_SPAM, L_SCAN, "Comparison of '%s' and '%s' gave score %d\n", dbpath, path, i);

      if (i > score)
	{
	  free(winner);
	  winner = strdup(dbpath);
	  score = i;
	}
      else if (i == score)
	{
	  free(winner);
	  winner = NULL;
	}
    }

  db_query_end(&qp);

  if (!winner)
    {
      DPRINTF(E_LOG, L_SCAN, "No file matches iTunes XML entry '%s'\n", path);
      return -1;
    }

  DPRINTF(E_DBG, L_SCAN, "Found '%s' from iTunes XML (results %d)\n", path, qp.results);

  ret = db_file_id_bypath(winner);
  free(winner);

  return ret;
}
Example #17
0
File: ur-cmd.c Project: spolu/ur
int
cmd_add (const char *path, bool recursive)
{
  char *prt_dir = NULL, *fname = NULL, *dname = NULL;
  struct stat64 st_buf;
  state_t ur = STATE_INITIALIZER;
  struct index index = INDEX_INITIALIZER; 
  int status;

  if (lstat64 (path, &st_buf) != 0) fail("%s does not exist", path);

  prt_dir = (char *) malloc (strlen (path) + 4);
  parent_dir (path, prt_dir);

  if (st_buf.st_mode & S_IFREG) {

    fname = (char *) malloc (strlen (path) + 4);
    filename (path, fname);	

    if (ur_check (prt_dir) == 0) 
      {
	if (state_init (&ur, prt_dir) != 0) fail ("fail reading state of %s", prt_dir);
	if (index_read (&ur, &index) != 0) fail ("fail reading index of %s", prt_dir);
	
	status = index_entry_get_status (&index, fname);
	status |= S_IADD;
	if (!(status & S_IPST))
	  status |= S_IPST;
	index_entry_set_status (&index, fname, status);

	if (index_write (&ur, &index) != 0) fail ("fail writing index of %s", prt_dir);

	index_destroy (&index);
	state_destroy (&ur);
      }
    else
      fail ("%s initialization failed", prt_dir);	

    free (fname); fname = NULL;    
  }

  if (st_buf.st_mode & S_IFDIR) 
    {
      dname = (char *) malloc (strlen (path) + 4);
      dirname (path, dname);	

      if (ur_check (path) == 0) {
	if (ur_check (prt_dir) == 0) 
	  {
	    if (state_init (&ur, prt_dir) != 0) fail ("fail reading state of %s", prt_dir);
	    if (index_read (&ur, &index) != 0) fail ("fail reading index of %s", prt_dir);
	    
	    status = index_entry_get_status (&index, dname);
	    status |= S_IADD;
	    if (!(status & S_IPST))
	      status |= S_IPST;	
	    index_entry_set_status (&index, dname, status);

	    if (index_write (&ur, &index) != 0) fail ("fail writing index of %s", prt_dir);
	    index_destroy (&index);
	    state_destroy (&ur);
	}
      }
      else {

	if (ur_create (path) != 0) fail ("%s initialization failed", path);	
	output ("init: %s", path);
	
	if (ur_check (prt_dir) == 0) {
	    if (state_init (&ur, prt_dir) != 0) fail ("fail reading state of %s", prt_dir);
	    if (index_read (&ur, &index) != 0) fail ("fail reading index of %s", prt_dir);
	    
	    status = index_entry_get_status (&index, dname);
	    status |= S_IADD;
	    if (!(status & S_IPST))
	      status |= S_IPST;	
	    index_entry_set_status (&index, dname, status);

	    if (index_write (&ur, &index) != 0) fail ("fail writing index of %s", prt_dir);
	    index_destroy (&index);
	    state_destroy (&ur);
	}
      }

      free (dname); dname = NULL;    
    }
  
  free (prt_dir); prt_dir = NULL;

  /*
   * recursion
   */
  if ((st_buf.st_mode & S_IFDIR) && recursive) 
    {
      DIR *dp;
      struct dirent *ep;
      
      dp = opendir (path);
      if (dp != NULL)
	{
	  while ((ep = readdir (dp))) {
	    if (ep->d_name[0] != '.') 
	      {		
		char *npath;
		npath = (char *) malloc (strlen (path) +
					 strlen (ep->d_name) + 2);
		if (path[strlen (path) -1] == '/')
		  sprintf (npath, "%s%s", path, ep->d_name);
		else
		  sprintf (npath, "%s/%s", path, ep->d_name);
		cmd_add (npath, recursive);
		free (npath);
	      }	    
	  }
	  (void) closedir (dp);
	}
      else
	fail ("could not open directory %s", path);      
    }
  
  return 0;
}