/* efstool.c - efs manipulation tool
Copyright (C) 2000 Maurer IT Systemlösungen KEG
The Gnome Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public License as
published by the Free Software Foundation; either version 2 of the
License, or (at your option) any later version.
The Gnome Library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Library General Public License for more details.
You should have received a copy of the GNU Library General Public
License along with the Gnome Library; see the file COPYING.LIB. If not,
write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA.
Author: Dietmar Maurer <dietmar@maurer-it.com>
*/
#include <sys/stat.h>
#include <unistd.h>
#include <string.h>
#include <dirent.h>
#include <stdio.h>
#include <stdlib.h>
#include "efs_internal.h"
EFSDir *root;
gchar path[EFS_MAXPATHLEN];
static gchar*
get_passwd (const gchar *filename, gboolean new)
{
static gchar passwd[1024];
if (new) printf("This File (%s) is password protected.\n", filename);
printf("Please enter the password: ");
passwd[0] = 0;
fgets (passwd, sizeof(passwd)-2, stdin);
passwd[sizeof(passwd)] = 0;
if (passwd[0] && (passwd[strlen(passwd)-1] == '\n'))
passwd[strlen(passwd)-1] = 0;
return passwd;
}
static void
prompt (void)
{
fprintf (stdout, "efs:%s# ",path);
fflush (stdout);
}
static const char *
full_path (const char *name)
{
static gchar buf[EFS_MAXPATHLEN];
if (name[0]==EFS_FDEL) return name;
strcpy (buf, path);
if (path[strlen(buf)-1]!=EFS_FDEL) strcat (buf, "/");
strcat (buf, name);
return buf;
}
static void
stat_command ()
{
EFSFSStat stat;
if (!efs_fsstat(root, &stat)) {
printf("EFS Filesystem Summary:\n");
printf("Driver: %s\n",stat.drivername);
printf("Size: %d\n",stat.size);
printf("Name length: %d\n",stat.namelen);
printf("Version: %d\n",stat.version);
printf("Free: %d\n",stat.free);
} else {
printf("stat command failed\n");
}
}
static void
ls_command ()
{
EFSDir *dir;
EFSNode *node;
EFSStat fs;
EFSDirEntry de;
const char *name = strtok (NULL, " \t\n");
gchar *ctype;
guint32 type;
if (name) name = strdup(full_path(name));
else name = path;
if (efs_dir_open (&dir, root, name, 0)) {
fprintf (stderr, "ls failed!\n");
return;
}
while (!efs_dir_read(dir, &de)) {
if (de.type==EFS_DIR) printf("D ");
else printf(" ");
printf("%s",de.name);
if (!efs_node_open (&node, dir, de.name, EFS_READ, 0)) {
efs_node_stat (node, &fs);
efs_type_get (node, &type);
efs_strtype_get (node, &ctype);
printf (" (%d, %d, %s)",fs.size, type, ctype);
}
printf("\n");
}
efs_dir_close (dir);
}
static void
mv_command ()
{
const char* from = strtok (NULL, " \t\n");
const char* to = strtok (NULL, " \t\n");
if (!to || !from) {
fprintf (stderr, "usage: mv TO FROM\n");
return;
}
from = strdup(full_path(from));
to = strdup(full_path(to));
if (efs_rename(root, from, to)) {
fprintf (stderr, "move failed!\n");
return;
}
}
static void
rm_command ()
{
const char *name;
name = strtok (NULL, " \t\n");
if (!name) {
fprintf (stderr, "usage: rm filename\n");
return;
}
name = strdup(full_path(name));
if (efs_erase(root, name))
fprintf(stderr,"rm failed (%s)\n", name);
}
static void
get_command ()
{
const char *name;
const char *lname;
FILE *fdest;
EFSFile *fsrc;
name = strtok (NULL, " \t\n");
if (!name) {
fprintf (stderr, "usage: get filename\n");
return;
}
name = strdup (full_path (name));
if (efs_file_open (&fsrc, root, name, EFS_READ)) {
fprintf (stderr,"efs open failed (%s)\n", name);
return;
}
lname = strrchr (name, '/');
if (!lname)
lname = name;
else
lname++;
if (!(fdest = fopen (lname, "wb+"))) {
fprintf (stderr,"open failed (%s)\n", lname);
efs_file_close (fsrc);
return;
}
while (1) {
char buffer [1024];
gint32 br;
if (efs_file_read (fsrc, buffer, 1024, &br)) break;
fwrite (buffer, br, 1, fdest);
}
efs_file_close (fsrc);
fclose (fdest);
}
static void
mkdir_command ()
{
const char *name;
EFSDir *dir;
name = strtok (NULL, " \t\n");
if (!name) {
fprintf (stderr, "usage: mkdir dirname\n");
return;
}
name = strdup(full_path(name));
if (efs_dir_open(&dir, root, name, EFS_CREATE|EFS_EXCL)) {
fprintf(stderr,"mkdir failed (%s)\n", name);
} else efs_dir_close (dir);
}
static void
cd_command ()
{
EFSDir *dir;
const char* to;
static char *op = NULL;
if (op) g_free(op);
op = strdup(path);
to = strtok (NULL, " \t\n");
if (!to) {
fprintf (stderr, "usage: cd DIR\n");
return;
}
if (!strcmp(to,"..")) {
gint i;
i = strlen(path);
while ((i>0) && (path[i-1]==EFS_FDEL)) i--;
while ((i>0) && (path[i-1]!=EFS_FDEL)) i--;
while ((i>0) && (path[i-1]==EFS_FDEL)) i--;
if (!i) path[1]=0;
else path[i]=0;
} else if (to[0]==EFS_FDEL) {
strcpy (path, to);
} else {
if (path[strlen(path)-1]!=EFS_FDEL) strcat (path, "/");
strcat (path, to);
}
if (efs_dir_open(&dir, root, path, 0)) {
fprintf(stderr,"No such directory\n");
strcpy (path, op);
return;
}
efs_dir_close (dir);
}
static void
help_command ()
{
printf("Available commands:\n");
printf("ls list directory contents\n");
printf("cd dir change directory\n");
printf("get file extract a file\n");
printf("mv old new move file or directory\n");
printf("rm name delete a file or directory\n");
printf("mkdir name create a directory\n");
printf("commit commit changes\n");
printf("stat print filesystem status\n");
printf("exit quit efstool\n");
printf("help print this screen\n");
}
static void
add_file_or_dir (gchar *name)
{
struct stat sb;
EFSFile *file;
EFSDir *dir;
gint fd, i, j;
gchar buf[512],*nn;
DIR *d;
struct dirent *de;
if (lstat(name,&sb) == -1) {
printf("add %s failed!\n", name);
return;
}
if (S_ISDIR(sb.st_mode)) {
if (!(d = opendir (name))) return;
if (efs_dir_open(&dir, root, name, EFS_CREATE|EFS_EXCL))
return;
efs_dir_close (dir);
while ((de = readdir (d))) {
if (!strcmp(de->d_name,".")) continue;
if (!strcmp(de->d_name,"..")) continue;
nn = g_strconcat (name,"/", de->d_name, NULL);
add_file_or_dir (nn);
g_free(nn);
}
closedir(d);
return;
}
if (S_ISREG(sb.st_mode)) {
if (efs_file_open (&file, root, name, EFS_CREATE|EFS_EXCL))
return;
if ((fd = open (name, O_RDONLY)) == -1) return;
while ((i=read (fd, buf, 512))) {
j = efs_file_write(file, buf, i);
}
efs_file_close(file);
close (fd);
return;
}
printf("add %s failed (not a file)!\n", name);
}
static void
list_contents (EFSDir *dir)
{
EFSDir *d;
EFSDirEntry de;
efs_dir_seek (dir, 0);
while (efs_dir_read (dir, &de) > 0) {
printf("%s\n", de.name);
}
efs_dir_seek (dir, 0);
while (efs_dir_read (dir, &de) > 0) {
if (de.type == EFS_DIR) {
if (!efs_dir_open (&d, dir, de.name, EFS_READ)) {
printf("\n%s:\n",de.name);
list_contents(d);
efs_dir_close(d);
}
}
}
}
static void
print_usage()
{
fprintf (stderr, "usage: efstool efs-file\n");
fprintf (stderr, " efstool c efs-file {files}\n");
fprintf (stderr, " efstool t efs-file\n");
}
int
main(int argc, char *argv[])
{
char read_buf[1024];
gint i;
if (argc < 2) {
print_usage();
exit (1);
}
if (argc == 2) { /* interactive mode */
if (efs_open_cb(&root,argv[1],EFS_RDWR,0644,get_passwd)) {
fprintf (stderr, "efs_open failed\n");
exit (1);
}
strcpy (path, "/");
prompt ();
while (fgets (read_buf, 1024, stdin) != NULL) {
const char* cmd = strtok (read_buf, " \t\n");
if (cmd == NULL) {
/* nothing */
} else if (strcmp (cmd, "ls") == 0) {
ls_command ();
} else if (strcmp (cmd, "mv") == 0) {
mv_command ();
} else if (strcmp (cmd, "cd") == 0) {
cd_command ();
} else if (strcmp (cmd, "get") == 0) {
get_command ();
} else if (strcmp (cmd, "rm") == 0) {
rm_command ();
} else if (strcmp (cmd, "mkdir") == 0) {
mkdir_command ();
} else if (strcmp (cmd, "commit") == 0) {
efs_commit (root);
} else if (strcmp (cmd, "stat") == 0) {
stat_command ();
} else if (strcmp (cmd, "help") == 0) {
help_command ();
} else if (strcmp (cmd, "exit") == 0) {
break;
} else if (strcmp (cmd, "quit") == 0) {
break;
} else {
fprintf (stderr, "unrecognized command: %s\n",
cmd);
}
prompt ();
}
efs_close (root);
} else {
if (!strcmp(argv[1], "c")&&(argc>=4)) {
if (efs_open(&root, argv[2], EFS_CREATE|EFS_EXCL,
0644, NULL)) {
fprintf (stderr, "efs_open failed\n");
exit (1);
}
for (i = 3; i < argc; i++) {
add_file_or_dir (argv[i]);
}
efs_commit (root);
efs_close (root);
exit (0);
}
if (!strcmp (argv[1], "t")&&(argc==3)) {
if (efs_open(&root, argv[2], EFS_READ, 0, NULL)) {
fprintf (stderr, "efs_open failed\n");
exit (1);
}
list_contents (root);
efs_close (root);
exit(0);
}
print_usage();
}
return 0;
}
syntax highlighted by Code2HTML, v. 0.9.1