Exemplo n.º 1
0
static int cmd_ls(int argc, char **argv) {
  (void)argc;

  RootPtr rootInfo = initRootInfo(argv[1]);

  if (!rootInfo) return EXIT_FAILURE;

  // show files in directory
  {
    DirTraverse dt = rootInfo->root->openDir("/");
    if (dt.valid()) {
      for (string name = dt.nextPlaintextName(); !name.empty();
           name = dt.nextPlaintextName()) {
        shared_ptr<FileNode> fnode =
            rootInfo->root->lookupNode(name.c_str(), "encfsctl-ls");
        struct stat stbuf;
        fnode->getAttr(&stbuf);

        struct tm stm;
        localtime_r(&stbuf.st_mtime, &stm);
        stm.tm_year += 1900;
        // TODO: when I add "%s" to the end and name.c_str(), I get a
        // seg fault from within strlen.  Why ???
        printf("%11i %4i-%02i-%02i %02i:%02i:%02i %s\n", int(stbuf.st_size),
               int(stm.tm_year), int(stm.tm_mon), int(stm.tm_mday),
               int(stm.tm_hour), int(stm.tm_min), int(stm.tm_sec),
               name.c_str());
      }
    }
  }

  return EXIT_SUCCESS;
}
Exemplo n.º 2
0
static int traverseDirs(const shared_ptr<EncFS_Root> &rootInfo,
                        string volumeDir, string destDir) {
  if (!endsWith(volumeDir, '/')) volumeDir.append("/");
  if (!endsWith(destDir, '/')) destDir.append("/");

  // Lookup directory node so we can create a destination directory
  // with the same permissions
  {
    struct stat st;
    shared_ptr<FileNode> dirNode =
        rootInfo->root->lookupNode(volumeDir.c_str(), "encfsctl");
    if (dirNode->getAttr(&st)) return EXIT_FAILURE;

    mkdir(destDir.c_str(), st.st_mode);
  }

  // show files in directory
  DirTraverse dt = rootInfo->root->openDir(volumeDir.c_str());
  if (dt.valid()) {
    for (string name = dt.nextPlaintextName(); !name.empty();
         name = dt.nextPlaintextName()) {
      // Recurse to subdirectories
      if (name != "." && name != "..") {
        string plainPath = volumeDir + name;
        string cpath = rootInfo->root->cipherPath(plainPath.c_str());
        string destName = destDir + name;

        int r = EXIT_SUCCESS;
        struct stat stBuf;
        if (!lstat(cpath.c_str(), &stBuf)) {
          if (S_ISDIR(stBuf.st_mode)) {
            traverseDirs(rootInfo, (plainPath + '/').c_str(), destName + '/');
          } else if (S_ISLNK(stBuf.st_mode)) {
            r = copyLink(stBuf, rootInfo, cpath, destName);
          } else {
            r = copyContents(rootInfo, plainPath.c_str(), destName.c_str());
          }
        } else {
          r = EXIT_FAILURE;
        }

        if (r != EXIT_SUCCESS) return r;
      }
    }
  }
  return EXIT_SUCCESS;
}
Exemplo n.º 3
0
int encfs_getdir(const char *path, fuse_dirh_t h, fuse_dirfil_t filler)
{
    EncFS_Context *ctx = context();

    int res = ESUCCESS;
    shared_ptr<DirNode> FSRoot = ctx->getRoot(&res);
    if(!FSRoot)
	return res;

    try
    {

	DirTraverse dt = FSRoot->openDir( path );

	rLog(Info, "getdir on %s", FSRoot->cipherPath(path).c_str());

	if(dt.valid())
	{
	    int fileType = 0;
	    ino_t inode = 0;

	    std::string name = dt.nextPlaintextName( &fileType, &inode );
	    while( !name.empty() )
	    {
		res = filler( h, name.c_str(), fileType, inode );

		if(res != ESUCCESS)
		    break;

		name = dt.nextPlaintextName( &fileType, &inode );
	    } 
	} else
	{
	    rInfo("getdir request invalid, path: '%s'", path);
	}

	return res;
    } catch( rlog::Error &err )
    {
	rError("Error caught in getdir");
	err.log( _RLWarningChannel );
	return -EIO;
    }
}
Exemplo n.º 4
0
int encfs_readdir(const char *path, void *buf, fuse_fill_dir_t filler,
                  off_t offset, struct fuse_file_info *finfo) {
  EncFS_Context *ctx = context();

  int res = ESUCCESS;
  std::shared_ptr<DirNode> FSRoot = ctx->getRoot(&res);
  if (!FSRoot) return res;

  try {

    DirTraverse dt = FSRoot->openDir(path);

    VLOG(1) << "readdir on " << FSRoot->cipherPath(path);

    if (dt.valid()) {
      int fileType = 0;
      ino_t inode = 0;

      std::string name = dt.nextPlaintextName(&fileType, &inode);
      while (!name.empty()) {
        struct stat st;
        st.st_ino = inode;
        st.st_mode = fileType << 12;

        // TODO: add offset support.
#if defined(fuse_fill_dir_flags)
        if (filler(buf, name.c_str(), &st, 0, 0)) break;
#else
        if (filler(buf, name.c_str(), &st, 0)) break;
#endif

        name = dt.nextPlaintextName(&fileType, &inode);
      }
    } else {
      VLOG(1) << "readdir request invalid, path: '" << path << "'";
    }

    return res;
  } catch (encfs::Error &err) {
    RLOG(ERROR) << "Error caught in readdir";
    return -EIO;
  }
}
Exemplo n.º 5
0
int encfs_getdir(const char *path, fuse_dirh_t h, fuse_dirfil_t filler)
{
  EncFS_Context *ctx = context();

  int res = ESUCCESS;
  shared_ptr<DirNode> FSRoot = ctx->getRoot(&res);
  if(!FSRoot)
    return res;

  try
  {

    DirTraverse dt = FSRoot->openDir( path );

    VLOG(1) << "getdir on " << FSRoot->cipherPath(path);

    if(dt.valid())
    {
      int fileType = 0;
      ino_t inode = 0;

      std::string name = dt.nextPlaintextName( &fileType, &inode );
      while( !name.empty() )
      {
        res = filler( h, name.c_str(), fileType, inode );

        if(res != ESUCCESS)
          break;

        name = dt.nextPlaintextName( &fileType, &inode );
      } 
    } else
    {
      LOG(INFO) << "getdir request invalid, path: '" << path << "'";
    }

    return res;
  } catch( Error &err )
  {
    LOG(ERROR) << "error caught in getdir: " << err.what();
    return -EIO;
  }
}
Exemplo n.º 6
0
int showcruft( const shared_ptr<EncFS_Root> &rootInfo, const char *dirName )
{
    int found = 0;
    DirTraverse dt = rootInfo->root->openDir( dirName );
    if(dt.valid())
    {
	bool showedDir = false;
	for(string name = dt.nextInvalid(); !name.empty(); 
		name = dt.nextInvalid())
	{
	    string cpath = rootInfo->root->cipherPath( dirName );
	    cpath += '/';
	    cpath += name;

	    if(!showedDir)
	    {
		// just before showing a list of files in a directory
		cout << autosprintf(_("In directory %s: \n"), dirName);
		showedDir = true;
	    }
	    ++found;
	    cout << cpath << "\n";
	}

	// now go back and look for directories to recurse into..
	dt = rootInfo->root->openDir( dirName );
	if(dt.valid())
	{
	    for(string name = dt.nextPlaintextName(); !name.empty(); 
		    name = dt.nextPlaintextName())
	    {
		if( name == "." || name == "..")
		    continue;

		string plainPath = dirName;
		plainPath += '/';
		plainPath += name;

		string cpath = rootInfo->root->cipherPath( plainPath.c_str() );

		if(isDirectory( cpath.c_str() ))
		    found += showcruft( rootInfo, plainPath.c_str() );
	    }
	}
    }

    return found;
}
Exemplo n.º 7
0
static int traverseDirs(const shared_ptr<EncFS_Root> &rootInfo, 
                        std::string volumeDir, std::string destDir,
                        const std::set<std::string>& toWrite )
{
    bool fake = toWrite.empty();
    
    if(!endsWith(volumeDir, '/'))
	volumeDir.append("/");
    if(!endsWith(destDir, '/'))
	destDir.append("/");

    std::string test_string = volumeDir;
    if (endsWith(test_string, '/') &&
        test_string.length() != 1) {
        test_string = test_string.substr(0, test_string.length()-1);
    }
    /* Abort if we're in export mode and this directory
     * doesn't need to be written
     */
    if (!toWrite.empty() &&
        toWrite.find(test_string) == toWrite.end()) {
        return EXIT_SUCCESS;
    }

    // Lookup directory node so we can create a destination directory
    // with the same permissions
    {
        struct stat st;
        shared_ptr<FileNode> dirNode = 
            rootInfo->root->lookupNode( volumeDir.c_str(), "encfsctl" );
        if(dirNode->getAttr(&st))
            return EXIT_FAILURE;

        // In fake mode, we always create rw:
        mode_t srcmode = st.st_mode;
        if (fake)
            srcmode = S_IRWXU;
        if (mkdir(destDir.c_str(), srcmode) == -1) {
            if (errno == EACCES /* sic! */ || errno == EROFS || errno == ENOSPC) {
                std::ostringstream out;
                out << "Not creating " << destDir << ": "
                    << strerror(errno);
                LOGE(out.str().c_str());
                return EXIT_FAILURE;
            }
        }
    }
    // show files in directory
    DirTraverse dt = rootInfo->root->openDir(volumeDir.c_str());
    if(dt.valid())
    {
        for(std::string name = dt.nextPlaintextName(); !name.empty(); 
            name = dt.nextPlaintextName())
        {
            bool skip = !toWrite.empty() && toWrite.find(volumeDir+name) == toWrite.end();

            // Recurse to subdirectories
            if(name != "." && name != ".." && !skip)
            {
                std::string plainPath = volumeDir + name;
                std::string cpath = rootInfo->root->cipherPath(plainPath.c_str());
                std::string destName = destDir + name;

                /*std::ostringstream out;
                out << "Decoding " << cpath << " to " << plainPath << " in " << destName;
                LOGI(out.str().c_str()); */
                
                int r = EXIT_SUCCESS;
                struct stat stBuf;
                if( !lstat( cpath.c_str(), &stBuf ))
                {
                    if( S_ISDIR( stBuf.st_mode ) )
                    {
                        r = traverseDirs(rootInfo, (plainPath + '/').c_str(), 
                                         destName + '/', toWrite);
                    } else if( S_ISLNK( stBuf.st_mode ))
                    {
                        r = copyLink( stBuf, rootInfo, cpath, destName );
                    } else
                    {
                        r = copyContents(rootInfo, plainPath.c_str(), 
                                         destName.c_str(), fake);
                    }
                } else
                {
                    r = EXIT_FAILURE;
                }
                if(r != EXIT_SUCCESS)
                    return r;
            }
        }
    }
    return EXIT_SUCCESS;
}