]> git.sur5r.net Git - bacula/bacula/commitdiff
Add Raw file save/restore
authorKern Sibbald <kern@sibbald.com>
Wed, 1 Jan 2003 22:37:49 +0000 (22:37 +0000)
committerKern Sibbald <kern@sibbald.com>
Wed, 1 Jan 2003 22:37:49 +0000 (22:37 +0000)
git-svn-id: https://bacula.svn.sourceforge.net/svnroot/bacula/trunk@258 91ce42f0-d328-0410-95d8-f526ca767f89

18 files changed:
bacula/kernstodo
bacula/src/c
bacula/src/cats/bdb_get.c
bacula/src/cats/cats.h
bacula/src/cats/mysql.c
bacula/src/cats/sql.c
bacula/src/cats/sql_create.c
bacula/src/cats/sqlite.c
bacula/src/cl
bacula/src/dird/fd_cmds.c
bacula/src/filed/backup.c
bacula/src/filed/estimate.c
bacula/src/filed/verify.c
bacula/src/findlib/create_file.c
bacula/src/findlib/find.c
bacula/src/findlib/find.h
bacula/src/findlib/find_one.c
bacula/src/version.h

index 18262346fb65ebafb46ea3ff2bb6f6e4a041d9bb..0675f3cbbf800dc2c7a62069c921cc6f5f49422c 100644 (file)
@@ -1,5 +1,5 @@
                  Kern's ToDo List
-                 29 December 2002
+                 01 January 2003 
 
 Documentation to do: (a little bit at a time)
 - Document running a test version.
@@ -15,8 +15,11 @@ For 1.28 release:
 - Look at ua_prune.c in detail. Why did JobType work at all??????
 - Figure out how to allow multiple simultaneous file Volumes on
   a single device.
+- Why are save/restore of device different sizes (sparse?)
 
 For 1.29 release:
+- Backup of raw partitions
+- Figure out some way to automatically backup all local partitions
 - Enable avoid backing up archive device (findlib/find_one.c:128)
 - Implement FileOptions (see end of this document)
 - Implement Bacula plugins -- design API
index de15677c2982576e963cd81a48209623b81f0ce9..d57a7ad9ed30a37bb50332f5dfc7d2bec1fa7f0a 100644 (file)
@@ -1,5 +1,5 @@
 /*
-   Copyright (C) 2000, 2001, 2002 Kern Sibbald and John Walker
+   Copyright (C) 2000-2003 Kern Sibbald and John Walker
 
    This program is free software; you can redistribute it and/or
    modify it under the terms of the GNU General Public License as
index 60dc10c5c0a51e8878114ab2a397cfc02d4d56b2..dbd1953420572eea51f57413d8c0c4cebe0119f7 100644 (file)
@@ -17,7 +17,7 @@
  */
 
 /*
-   Copyright (C) 2001, 2002 Kern Sibbald and John Walker
+   Copyright (C) 2001-2003 Kern Sibbald and John Walker
 
    This program is free software; you can redistribute it and/or
    modify it under the terms of the GNU General Public License as
@@ -500,8 +500,4 @@ int db_get_job_volume_parameters(B_DB *mdb, uint32_t JobId, VOL_PARAMS **VolPara
 int db_get_client_ids(B_DB *mdb, int *num_ids, uint32_t *ids[])
 { return 0; }
 
-
-int db_get_client_record(B_DB *mdb, CLIENT_DBR *cdbr)
-{ return 0; }
-
 #endif /* HAVE_BACULA_DB */
index 31c6bfe20140005f3c6c52b2e832c0cb9c56ff6e..4f72737f7b5faf9c637d6aed57394f15019e4ae5 100644 (file)
@@ -15,7 +15,7 @@
  */
 
 /*
-   Copyright (C) 2000, 2001, 2002 Kern Sibbald and John Walker
+   Copyright (C) 2000-2003 Kern Sibbald and John Walker
 
    This program is free software; you can redistribute it and/or
    modify it under the terms of the GNU General Public License as
@@ -57,62 +57,68 @@ struct sqlite {
    char dummy;
 };
 
-#define IS_NUM(x)             ((x) == 1)
-#define IS_NOT_NULL(x)        ((x) == 1)
+#define IS_NUM(x)            ((x) == 1)
+#define IS_NOT_NULL(x)       ((x) == 1)
 
 typedef struct s_sql_field {
-   char *name;                        /* name of column */
-   uint32_t length;                   /* length */
-   uint32_t max_length;               /* max length */
-   uint32_t type;                     /* type */
-   uint32_t flags;                    /* flags */
+   char *name;                       /* name of column */
+   uint32_t length;                  /* length */
+   uint32_t max_length;              /* max length */
+   uint32_t type;                    /* type */
+   uint32_t flags;                   /* flags */
 } SQL_FIELD;
 
 /*
  * This is the "real" definition that should only be
  * used inside sql.c and associated database interface
  * subroutines.
- *                    S Q L I T E
+ *                   S Q L I T E
  */
 typedef struct s_db {
-   BQUEUE bq;                         /* queue control */
-   brwlock_t lock;                    /* transaction lock */
+   BQUEUE bq;                        /* queue control */
+   brwlock_t lock;                   /* transaction lock */
    struct sqlite *db;
    char **result;
-   int nrow;                          /* nrow returned from sqlite */
-   int ncolumn;                       /* ncolum returned from sqlite */
-   int num_rows;                      /* used by code */
-   int row;                           /* seek row */
-   int have_insert_id;                /* do not have insert id */
-   int fields_defined;                /* set when fields defined */
-   int field;                         /* seek field */
-   SQL_FIELD **fields;                /* defined fields */
+   int nrow;                         /* nrow returned from sqlite */
+   int ncolumn;                      /* ncolum returned from sqlite */
+   int num_rows;                     /* used by code */
+   int row;                          /* seek row */
+   int have_insert_id;               /* do not have insert id */
+   int fields_defined;               /* set when fields defined */
+   int field;                        /* seek field */
+   SQL_FIELD **fields;               /* defined fields */
    int ref_count;
    char *db_name;
    char *db_user;
    char *db_password;
    int connected;
-   char *sqlite_errmsg;               /* error message returned by sqlite */
-   POOLMEM *errmsg;                   /* nicely edited error message */
-   POOLMEM *cmd;                      /* SQL command string */
-   POOLMEM *cached_path;
-   uint32_t cached_path_id;
-   int transaction;                   /* transaction started */
-   int changes;                       /* changes during transaction */
-   void *jcr;                         /* JCR or NULL */
+   char *sqlite_errmsg;              /* error message returned by sqlite */
+   POOLMEM *errmsg;                  /* nicely edited error message */
+   POOLMEM *cmd;                     /* SQL command string */
+   POOLMEM *cached_path;             /* cached path name */
+   int cached_path_len;              /* length of cached path */
+   uint32_t cached_path_id;          /* cached path id */
+   int transaction;                  /* transaction started */
+   int changes;                      /* changes during transaction */
+   void *jcr;                        /* JCR or NULL */
+   POOLMEM *fname;                   /* Filename only */
+   POOLMEM *path;                    /* Path only */
+   POOLMEM *esc_name;                /* Escaped file/path name */
+   int fnl;                          /* file name length */
+   int pnl;                          /* path name length */
 } B_DB;
 
 
 /* 
  * "Generic" names for easier conversion   
  *
- *                    S Q L I T E
+ *                   S Q L I T E
  */
 #define sql_store_result(x)   x->result
 #define sql_free_result(x)    my_sqlite_free_table(x)
 #define sql_fetch_row(x)      my_sqlite_fetch_row(x)
 #define sql_query(x, y)       my_sqlite_query(x, y)
-#define sql_close(x)          sqlite_close(x->db)  
+#define sql_close(x)         sqlite_close(x->db)  
 #define sql_strerror(x)       x->sqlite_errmsg?x->sqlite_errmsg:"unknown"
 #define sql_num_rows(x)       x->nrow
 #define sql_data_seek(x, i)   x->row = i
@@ -121,7 +127,7 @@ typedef struct s_db {
 #define sql_field_seek(x, y)  my_sqlite_field_seek(x, y)
 #define sql_fetch_field(x)    my_sqlite_fetch_field(x)
 #define sql_num_fields(x)     (unsigned)((x)->ncolumn)
-#define SQL_ROW               char**   
+#define SQL_ROW              char**   
 
 
 
@@ -143,11 +149,11 @@ extern void my_sqlite_free_table(B_DB *mdb);
  * used inside sql.c and associated database interface
  * subroutines.
  *
- *                     M Y S Q L
+ *                    M Y S Q L
  */
 typedef struct s_db {
-   BQUEUE bq;                         /* queue control */
-   brwlock_t lock;                    /* transaction lock */
+   BQUEUE bq;                        /* queue control */
+   brwlock_t lock;                   /* transaction lock */
    MYSQL mysql;
    MYSQL *db;
    MYSQL_RES *result;
@@ -156,14 +162,19 @@ typedef struct s_db {
    char *db_name;
    char *db_user;
    char *db_password;
-   int have_insert_id;                /* do have insert_id() */
+   int have_insert_id;               /* do have insert_id() */
    int connected;
-   POOLMEM *errmsg;                   /* nicely edited error message */
-   POOLMEM *cmd;                      /* SQL command string */
+   POOLMEM *errmsg;                  /* nicely edited error message */
+   POOLMEM *cmd;                     /* SQL command string */
    POOLMEM *cached_path;
    uint32_t cached_path_id;
-   int changes;                       /* changes made to db */
-   void *jcr;                         /* JCR or NULL */
+   int changes;                      /* changes made to db */
+   void *jcr;                        /* JCR or NULL */
+   POOLMEM *fname;                   /* Filename only */
+   POOLMEM *path;                    /* Path only */
+   POOLMEM *esc_name;                /* Escaped file/path name */
+   int fnl;                          /* file name length */
+   int pnl;                          /* path name length */
 } B_DB;
 
 
@@ -172,7 +183,7 @@ typedef struct s_db {
 #define sql_free_result(x)    mysql_free_result(x->result)
 #define sql_fetch_row(x)      mysql_fetch_row(x->result)
 #define sql_query(x, y)       mysql_query(x->db, y)
-#define sql_close(x)          mysql_close(x->db)  
+#define sql_close(x)         mysql_close(x->db)  
 #define sql_strerror(x)       mysql_error(x->db)
 #define sql_num_rows(x)       mysql_num_rows(x->result)
 #define sql_data_seek(x, i)   mysql_data_seek(x->result, i)
@@ -181,8 +192,8 @@ typedef struct s_db {
 #define sql_field_seek(x, y)  mysql_field_seek(x->result, y)
 #define sql_fetch_field(x)    mysql_fetch_field(x->result)
 #define sql_num_fields(x)     mysql_num_fields(x->result)
-#define SQL_ROW               MYSQL_ROW
-#define SQL_FIELD             MYSQL_FIELD
+#define SQL_ROW              MYSQL_ROW
+#define SQL_FIELD            MYSQL_FIELD
 
 #else  /* USE BACULA DB routines */
 
@@ -191,17 +202,17 @@ typedef struct s_db {
 /* Change this each time there is some incompatible
  * file format change!!!!
  */
-#define BDB_VERSION 11                /* file version number */
+#define BDB_VERSION 11               /* file version number */
 
 struct s_control {
-   int bdb_version;                   /* Version number */
-   uint32_t JobId;                    /* next Job Id */
-   uint32_t PoolId;                   /* next Pool Id */
-   uint32_t MediaId;                  /* next Media Id */
-   uint32_t JobMediaId;               /* next JobMedia Id */
-   uint32_t ClientId;                 /* next Client Id */
-   uint32_t FileSetId;                /* nest FileSet Id */
-   time_t time;                       /* time file written */
+   int bdb_version;                  /* Version number */
+   uint32_t JobId;                   /* next Job Id */
+   uint32_t PoolId;                  /* next Pool Id */
+   uint32_t MediaId;                 /* next Media Id */
+   uint32_t JobMediaId;              /* next JobMedia Id */
+   uint32_t ClientId;                /* next Client Id */
+   uint32_t FileSetId;               /* nest FileSet Id */
+   time_t time;                      /* time file written */
 };
 
 
@@ -209,24 +220,24 @@ struct s_control {
  *  Bacula internal DB
  */
 typedef struct s_db {
-   BQUEUE bq;                         /* queue control */
-/* pthread_mutex_t mutex;  */         /* single thread lock */
-   brwlock_t lock;                    /* transaction lock */
-   int ref_count;                     /* number of times opened */
-   struct s_control control;          /* control file structure */
-   int cfd;                           /* control file device */
-   FILE *jobfd;                       /* Jobs records file descriptor */
-   FILE *poolfd;                      /* Pool records fd */
-   FILE *mediafd;                     /* Media records fd */
-   FILE *jobmediafd;                  /* JobMedia records fd */
-   FILE *clientfd;                    /* Client records fd */
-   FILE *filesetfd;                   /* FileSet records fd */
-   char *db_name;                     /* name of database */
-   POOLMEM *errmsg;                   /* nicely edited error message */
-   POOLMEM *cmd;                      /* Command string */
+   BQUEUE bq;                        /* queue control */
+/* pthread_mutex_t mutex;  */        /* single thread lock */
+   brwlock_t lock;                   /* transaction lock */
+   int ref_count;                    /* number of times opened */
+   struct s_control control;         /* control file structure */
+   int cfd;                          /* control file device */
+   FILE *jobfd;                      /* Jobs records file descriptor */
+   FILE *poolfd;                     /* Pool records fd */
+   FILE *mediafd;                    /* Media records fd */
+   FILE *jobmediafd;                 /* JobMedia records fd */
+   FILE *clientfd;                   /* Client records fd */
+   FILE *filesetfd;                  /* FileSet records fd */
+   char *db_name;                    /* name of database */
+   POOLMEM *errmsg;                  /* nicely edited error message */
+   POOLMEM *cmd;                     /* Command string */
    POOLMEM *cached_path;
    uint32_t cached_path_id;
-   void *jcr;                         /* JCR or NULL */
+   void *jcr;                        /* JCR or NULL */
 } B_DB;
 
 #endif /* HAVE_MYSQL */
@@ -239,19 +250,19 @@ typedef struct s_db {
 #define DELETE_DB(db, cmd) DeleteDB(__FILE__, __LINE__, db, cmd)
 
 
-#else    /* not __SQL_C */
+#else   /* not __SQL_C */
 
 /* This is a "dummy" definition for use outside of sql.c
  */
-typedef struct s_db {     
-   int dummy;                         /* for SunOS compiler */
+typedef struct s_db {    
+   int dummy;                        /* for SunOS compiler */
 } B_DB;  
 
 #endif /*  __SQL_C */
 
 /* ***FIXME*** FileId_t should be uint64_t */
 typedef uint32_t FileId_t;
-typedef uint32_t DBId_t;              /* general DB id type */
+typedef uint32_t DBId_t;             /* general DB id type */
 typedef uint32_t JobId_t;
 
 
@@ -263,18 +274,18 @@ typedef uint32_t JobId_t;
 /* Job record */
 typedef struct {
    JobId_t JobId;
-   char Job[MAX_NAME_LENGTH];         /* Job unique name */
-   char Name[MAX_NAME_LENGTH];        /* Job base name */
-   int Type;                          /* actually char(1) */
-   int Level;                         /* actually char(1) */
-   int JobStatus;                     /* actually char(1) */
-   uint32_t ClientId;                 /* Id of client */
-   uint32_t PoolId;                   /* Id of pool */
-   uint32_t FileSetId;                /* Id of FileSet */
-   time_t SchedTime;                  /* Time job scheduled */
-   time_t StartTime;                  /* Job start time */
-   time_t EndTime;                    /* Job termination time */
-   utime_t JobTDate;                  /* Backup time/date in seconds */
+   char Job[MAX_NAME_LENGTH];        /* Job unique name */
+   char Name[MAX_NAME_LENGTH];       /* Job base name */
+   int Type;                         /* actually char(1) */
+   int Level;                        /* actually char(1) */
+   int JobStatus;                    /* actually char(1) */
+   uint32_t ClientId;                /* Id of client */
+   uint32_t PoolId;                  /* Id of pool */
+   uint32_t FileSetId;               /* Id of FileSet */
+   time_t SchedTime;                 /* Time job scheduled */
+   time_t StartTime;                 /* Job start time */
+   time_t EndTime;                   /* Job termination time */
+   utime_t JobTDate;                 /* Backup time/date in seconds */
    uint32_t VolSessionId;
    uint32_t VolSessionTime;
    uint32_t JobFiles;
@@ -285,8 +296,8 @@ typedef struct {
    /* Note, FirstIndex, LastIndex, Start/End File and Block
     * are only used in the JobMedia record.
     */
-   uint32_t FirstIndex;               /* First index this Volume */
-   uint32_t LastIndex;                /* Last index this Volume */
+   uint32_t FirstIndex;              /* First index this Volume */
+   uint32_t LastIndex;               /* Last index this Volume */
    uint32_t StartFile;
    uint32_t EndFile;
    uint32_t StartBlock;
@@ -304,26 +315,26 @@ typedef struct {
  */
 /* JobMedia record */
 typedef struct {
-   uint32_t JobMediaId;               /* record id */
-   JobId_t  JobId;                    /* JobId */
-   uint32_t MediaId;                  /* MediaId */
-   uint32_t FirstIndex;               /* First index this Volume */
-   uint32_t LastIndex;                /* Last index this Volume */
-   uint32_t StartFile;                /* File for start of data */
-   uint32_t EndFile;                  /* End file on Volume */
-   uint32_t StartBlock;               /* start block on tape */
-   uint32_t EndBlock;                 /* last block */
+   uint32_t JobMediaId;              /* record id */
+   JobId_t  JobId;                   /* JobId */
+   uint32_t MediaId;                 /* MediaId */
+   uint32_t FirstIndex;              /* First index this Volume */
+   uint32_t LastIndex;               /* Last index this Volume */
+   uint32_t StartFile;               /* File for start of data */
+   uint32_t EndFile;                 /* End file on Volume */
+   uint32_t StartBlock;              /* start block on tape */
+   uint32_t EndBlock;                /* last block */
 } JOBMEDIA_DBR;
 
 /* Volume Parameter structure */
 typedef struct {
    char VolumeName[MAX_NAME_LENGTH];  /* Volume name */
-   uint32_t FirstIndex;               /* First index this Volume */
-   uint32_t LastIndex;                /* Last index this Volume */
-   uint32_t StartFile;                /* File for start of data */
-   uint32_t EndFile;                  /* End file on Volume */
-   uint32_t StartBlock;               /* start block on tape */
-   uint32_t EndBlock;                 /* last block */
+   uint32_t FirstIndex;              /* First index this Volume */
+   uint32_t LastIndex;               /* Last index this Volume */
+   uint32_t StartFile;               /* File for start of data */
+   uint32_t EndFile;                 /* End file on Volume */
+   uint32_t StartBlock;              /* start block on tape */
+   uint32_t EndBlock;                /* last block */
 } VOL_PARAMS;
 
 
@@ -332,9 +343,9 @@ typedef struct {
  *  records (e.g. pathname, filename, fileattributes).
  */
 typedef struct {
-   char *fname;                       /* full path & filename */
-   char *link;                        /* link if any */
-   char *attr;                        /* attributes statp */
+   char *fname;                      /* full path & filename */
+   char *link;                       /* link if any */
+   char *attr;                       /* attributes statp */
    uint32_t FileIndex;
    uint32_t Stream;
    JobId_t  JobId;
@@ -361,20 +372,20 @@ typedef struct {
 /* Pool record -- same format as database */
 typedef struct {
    uint32_t PoolId;
-   char Name[MAX_NAME_LENGTH];        /* Pool name */
-   uint32_t NumVols;                  /* total number of volumes */
-   uint32_t MaxVols;                  /* max allowed volumes */
-   int UseOnce;                       /* set to use once only */
-   int UseCatalog;                    /* set to use catalog */
-   int AcceptAnyVolume;               /* set to accept any volume sequence */
-   int AutoPrune;                     /* set to prune automatically */
-   int Recycle;                       /* default Vol recycle flag */
-   utime_t  VolRetention;             /* retention period in seconds */
-   utime_t  VolUseDuration;           /* time in secs volume can be used */
-   uint32_t MaxVolJobs;               /* Max Jobs on Volume */
-   uint32_t MaxVolFiles;              /* Max files on Volume */
-   uint64_t MaxVolBytes;              /* Max bytes on Volume */
-   char PoolType[MAX_NAME_LENGTH];             
+   char Name[MAX_NAME_LENGTH];       /* Pool name */
+   uint32_t NumVols;                 /* total number of volumes */
+   uint32_t MaxVols;                 /* max allowed volumes */
+   int UseOnce;                      /* set to use once only */
+   int UseCatalog;                   /* set to use catalog */
+   int AcceptAnyVolume;              /* set to accept any volume sequence */
+   int AutoPrune;                    /* set to prune automatically */
+   int Recycle;                      /* default Vol recycle flag */
+   utime_t  VolRetention;            /* retention period in seconds */
+   utime_t  VolUseDuration;          /* time in secs volume can be used */
+   uint32_t MaxVolJobs;              /* Max Jobs on Volume */
+   uint32_t MaxVolFiles;             /* Max files on Volume */
+   uint64_t MaxVolBytes;             /* Max bytes on Volume */
+   char PoolType[MAX_NAME_LENGTH];            
    char LabelFormat[MAX_NAME_LENGTH];
    /* Extra stuff not in DB */
    faddr_t rec_addr;
@@ -382,34 +393,34 @@ typedef struct {
 
 /* Media record -- same as the database */
 typedef struct {
-   uint32_t MediaId;                  /* Unique volume id */
+   uint32_t MediaId;                 /* Unique volume id */
    char VolumeName[MAX_NAME_LENGTH];  /* Volume name */
    char MediaType[MAX_NAME_LENGTH];   /* Media type */
-   uint32_t PoolId;                   /* Pool id */
-   time_t   FirstWritten;             /* Time Volume first written */
-   time_t   LastWritten;              /* Time Volume last written */
-   time_t   LabelDate;                /* Date/Time Volume labeled */
-   uint32_t VolJobs;                  /* number of jobs on this medium */
-   uint32_t VolFiles;                 /* Number of files */
-   uint32_t VolBlocks;                /* Number of blocks */
-   uint32_t VolMounts;                /* Number of times mounted */
-   uint32_t VolErrors;                /* Number of read/write errors */
-   uint32_t VolWrites;                /* Number of writes */
-   uint32_t VolReads;                 /* Number of reads */
-   uint64_t VolBytes;                 /* Number of bytes written */
-   uint64_t MaxVolBytes;              /* Max bytes to write to Volume */
-   uint64_t VolCapacityBytes;         /* capacity estimate */
-   utime_t  VolRetention;             /* Volume retention in seconds */
-   utime_t  VolUseDuration;           /* time in secs volume can be used */
-   uint32_t MaxVolJobs;               /* Max Jobs on Volume */
-   uint32_t MaxVolFiles;              /* Max files on Volume */
-   int      Recycle;                  /* recycle yes/no */
-   int32_t  Slot;                     /* slot in changer */
-   char VolStatus[20];                /* Volume status */
+   uint32_t PoolId;                  /* Pool id */
+   time_t   FirstWritten;            /* Time Volume first written */
+   time_t   LastWritten;             /* Time Volume last written */
+   time_t   LabelDate;               /* Date/Time Volume labeled */
+   uint32_t VolJobs;                 /* number of jobs on this medium */
+   uint32_t VolFiles;                /* Number of files */
+   uint32_t VolBlocks;               /* Number of blocks */
+   uint32_t VolMounts;               /* Number of times mounted */
+   uint32_t VolErrors;               /* Number of read/write errors */
+   uint32_t VolWrites;               /* Number of writes */
+   uint32_t VolReads;                /* Number of reads */
+   uint64_t VolBytes;                /* Number of bytes written */
+   uint64_t MaxVolBytes;             /* Max bytes to write to Volume */
+   uint64_t VolCapacityBytes;        /* capacity estimate */
+   utime_t  VolRetention;            /* Volume retention in seconds */
+   utime_t  VolUseDuration;          /* time in secs volume can be used */
+   uint32_t MaxVolJobs;              /* Max Jobs on Volume */
+   uint32_t MaxVolFiles;             /* Max files on Volume */
+   int     Recycle;                  /* recycle yes/no */
+   int32_t  Slot;                    /* slot in changer */
+   char VolStatus[20];               /* Volume status */
    /* Extra stuff not in DB */
-   faddr_t rec_addr;                  /* found record address */
+   faddr_t rec_addr;                 /* found record address */
    /* Since the database returns times as strings, this is how we pass
-    *   them back.
+    *  them back.
     */
    char    cFirstWritten[MAX_TIME_LENGTH];  /* FirstWritten returned from DB */
    char    cLastWritten[MAX_TIME_LENGTH];  /* LastWritten returned from DB */
@@ -418,19 +429,19 @@ typedef struct {
 
 /* Client record -- same as the database */
 typedef struct {
-   uint32_t ClientId;                 /* Unique Client id */
+   uint32_t ClientId;                /* Unique Client id */
    int AutoPrune;
    utime_t FileRetention;
    utime_t JobRetention;
-   char Name[MAX_NAME_LENGTH];        /* Client name */
-   char Uname[256];                   /* Uname for client */
+   char Name[MAX_NAME_LENGTH];       /* Client name */
+   char Uname[256];                  /* Uname for client */
 } CLIENT_DBR;
 
 /* FileSet record -- same as the database */
 typedef struct {
-   uint32_t FileSetId;                /* Unique FileSet id */
+   uint32_t FileSetId;               /* Unique FileSet id */
    char FileSet[MAX_NAME_LENGTH];     /* FileSet name */
-   char MD5[50];                      /* MD5 signature of include/exclude */
+   char MD5[50];                     /* MD5 signature of include/exclude */
 } FILESET_DBR;
 
 
index b4f139f65bf41a15b003aeef68d3d431db9f3f6a..8e5736f1bf898c52ce7c96ed5fe118f4ba93a0b8 100644 (file)
@@ -9,7 +9,7 @@
  */
 
 /*
-   Copyright (C) 2000, 2001, 2002 Kern Sibbald and John Walker
+   Copyright (C) 2000-2003 Kern Sibbald and John Walker
 
    This program is free software; you can redistribute it and/or
    modify it under the terms of the GNU General Public License as
@@ -83,6 +83,9 @@ db_init_database(void *jcr, char *db_name, char *db_user, char *db_password)
    mdb->cached_path = get_pool_memory(PM_FNAME);
    mdb->cached_path_id = 0;
    mdb->ref_count = 1;
+   mdb->fname = get_pool_memory(PM_FNAME);
+   mdb->path = get_pool_memory(PM_FNAME);
+   mdb->esc_name = get_pool_memory(PM_FNAME);
    qinsert(&db_list, &mdb->bq);           /* put db in list */
    mdb->jcr = jcr;
    V(mutex);
@@ -182,6 +185,9 @@ db_close_database(B_DB *mdb)
       free_pool_memory(mdb->errmsg);
       free_pool_memory(mdb->cmd);
       free_pool_memory(mdb->cached_path);
+      free_pool_memory(mdb->fname);
+      free_pool_memory(mdb->path);
+      free_pool_memory(mdb->esc_name);
       if (mdb->db_name) {
         free(mdb->db_name);
       }
index 29f9cb5e9e20c1f58dadde0adcf5173fbab9940d..131887723d5ed7a95f5f5f42b6f766703130d1b5 100644 (file)
@@ -10,7 +10,7 @@
  */
 
 /*
-   Copyright (C) 2000, 2001, 2002 Kern Sibbald and John Walker
+   Copyright (C) 2000-2003 Kern Sibbald and John Walker
 
    This program is free software; you can redistribute it and/or
    modify it under the terms of the GNU General Public License as
@@ -254,5 +254,57 @@ void db_end_transaction(B_DB *mdb)
 #endif
 }
 
+void split_path_and_filename(B_DB *mdb, char *fname)
+{
+   char *p, *f;
+
+   /* Find path without the filename.  
+    * I.e. everything after the last / is a "filename".
+    * OK, maybe it is a directory name, but we treat it like
+    * a filename. If we don't find a / then the whole name
+    * must be a path name (e.g. c:).
+    */
+   for (p=f=fname; *p; p++) {
+      if (*p == '/') {
+        f = p;                       /* set pos of last slash */
+      }
+   }
+   if (*f == '/') {                   /* did we find a slash? */
+      f++;                           /* yes, point to filename */
+   } else {                          /* no, whole thing must be path name */
+      f = p;
+   }
+
+   /* If filename doesn't exist (i.e. root directory), we
+    * simply create a blank name consisting of a single 
+    * space. This makes handling zero length filenames
+    * easier.
+    */
+   mdb->fnl = p - f;
+   if (mdb->fnl > 0) {
+      mdb->fname = check_pool_memory_size(mdb->fname, mdb->fnl+1);
+      strncpy(mdb->fname, f, mdb->fnl);    /* copy filename */
+      mdb->fname[mdb->fnl] = 0;
+   } else {
+      mdb->fname[0] = ' ';            /* blank filename */
+      mdb->fname[1] = 0;
+      mdb->fnl = 1;
+   }
+
+   mdb->pnl = f - fname;    
+   if (mdb->pnl > 0) {
+      mdb->path = check_pool_memory_size(mdb->path, mdb->pnl+1);
+      strncpy(mdb->path, fname, mdb->pnl);
+      mdb->path[mdb->pnl] = 0;
+   } else {
+      Mmsg1(&mdb->errmsg, _("Path length is zero. File=%s\n"), fname);
+      Jmsg(mdb->jcr, M_ERROR, 0, "%s", mdb->errmsg);
+      mdb->path[0] = ' ';
+      mdb->path[1] = 0;
+      mdb->pnl = 1;
+   }
+
+   Dmsg2(100, "sllit path=%s file=%s\n", mdb->path, mdb->fname);
+}
 
 #endif /* HAVE_MYSQL | HAVE_SQLITE */
index b4337c93dacf3f8e16219a03e707ea7f70c44c65..be30de82b24e220ed7170c20aefcabb2fd712c3a 100644 (file)
@@ -7,7 +7,7 @@
  */
 
 /*
-   Copyright (C) 2000, 2001, 2002 Kern Sibbald and John Walker
+   Copyright (C) 2000-2003 Kern Sibbald and John Walker
 
    This program is free software; you can redistribute it and/or
    modify it under the terms of the GNU General Public License as
@@ -47,8 +47,8 @@
 
 /* Forward referenced subroutines */
 static int db_create_file_record(B_DB *mdb, ATTR_DBR *ar);
-static int db_create_filename_record(B_DB *mdb, ATTR_DBR *ar, char *fname);
-static int db_create_path_record(B_DB *mdb, ATTR_DBR *ar, char *path);
+static int db_create_filename_record(B_DB *mdb, ATTR_DBR *ar);
+static int db_create_path_record(B_DB *mdb, ATTR_DBR *ar);
 
 
 /* Imported subroutines */
@@ -56,6 +56,7 @@ extern void print_dashes(B_DB *mdb);
 extern void print_result(B_DB *mdb);
 extern int QueryDB(char *file, int line, B_DB *db, char *select_cmd);
 extern int InsertDB(char *file, int line, B_DB *db, char *select_cmd);
+extern void split_path_and_filename(B_DB *mdb, char *fname);
 
 
 /* Create a new record for the Job
@@ -431,17 +432,11 @@ FileSet='%s' and MD5='%s'", fsr->FileSet, fsr->MD5);
  */
 int db_create_file_attributes_record(B_DB *mdb, ATTR_DBR *ar)
 {
-   int fnl, pnl;
-   char *l, *p;
-   /* ****FIXME***** malloc these */
-   char file[MAXSTRING];
-   char spath[MAXSTRING];
-   char buf[MAXSTRING];
 
    Dmsg1(100, "Fname=%s\n", ar->fname);
    Dmsg0(50, "put_file_into_catalog\n");
-   /* For the moment, we only handle Unix attributes.  Note, we are
-    * also getting any MD5 signature that was computed.
+   /*
+    * Make sure we have an acceptable attributes record.
     */
    if (!(ar->Stream == STREAM_UNIX_ATTRIBUTES || ar->Stream == STREAM_WIN32_ATTRIBUTES)) {
       Mmsg0(&mdb->errmsg, _("Attempt to put non-attributes into catalog\n"));
@@ -449,84 +444,39 @@ int db_create_file_attributes_record(B_DB *mdb, ATTR_DBR *ar)
       return 0;
    }
 
-   /* Find path without the filename.  
-    * I.e. everything after the last / is a "filename".
-    * OK, maybe it is a directory name, but we treat it like
-    * a filename. If we don't find a / then the whole name
-    * must be a path name (e.g. c:).
-    */
-   for (p=l=ar->fname; *p; p++) {
-      if (*p == '/') {
-        l = p;                       /* set pos of last slash */
-      }
-   }
-   if (*l == '/') {                   /* did we find a slash? */
-      l++;                           /* yes, point to filename */
-   } else {                          /* no, whole thing must be path name */
-      l = p;
-   }
-
-   /* If filename doesn't exist (i.e. root directory), we
-    * simply create a blank name consisting of a single 
-    * space. This makes handling zero length filenames
-    * easier.
-    */
-   fnl = p - l;
-   if (fnl > 255) {
-      Jmsg(mdb->jcr, M_WARNING, 0, _("Filename truncated to 255 chars: %s\n"), l);
-      fnl = 255;
-   }
-   if (fnl > 0) {
-      strncpy(file, l, fnl);         /* copy filename */
-      file[fnl] = 0;
-   } else {
-      file[0] = ' ';                  /* blank filename */
-      file[1] = 0;
-      fnl = 1;
-   }
-
-   pnl = l - ar->fname;    
-   if (pnl > 255) {
-      Jmsg(mdb->jcr, M_WARNING, 0, _("Path name truncated to 255 chars: %s\n"), ar->fname);
-      pnl = 255;
-   }
-   strncpy(spath, ar->fname, pnl);
-   spath[pnl] = 0;
-
-   if (pnl == 0) {
-      Mmsg1(&mdb->errmsg, _("Path length is zero. File=%s\n"), ar->fname);
-      Jmsg(mdb->jcr, M_ERROR, 0, "%s", mdb->errmsg);
-      spath[0] = ' ';
-      spath[1] = 0;
-      pnl = 1;
-   }
-
-   Dmsg1(100, "spath=%s\n", spath);
-   Dmsg1(100, "file=%s\n", file);
+   db_lock(mdb);
 
-   db_escape_string(buf, file, fnl);
+   split_path_and_filename(mdb, ar->fname);
 
-   if (!db_create_filename_record(mdb, ar, buf)) {
+   if (!db_create_filename_record(mdb, ar)) {
+      db_unlock(mdb);
       return 0;
    }
-   Dmsg1(100, "db_create_filename_record: %s\n", buf);
+   Dmsg1(100, "db_create_filename_record: %s\n", mdb->esc_name);
 
-   db_escape_string(buf, spath, pnl);
 
-   if (!db_create_path_record(mdb, ar, buf)) {
+   if (!db_create_path_record(mdb, ar)) {
+      db_unlock(mdb);
       return 0;
    }
-   Dmsg1(100, "db_create_path_record\n", buf);
+   Dmsg1(100, "db_create_path_record\n", mdb->esc_name);
 
+   /* Now create master File record */
    if (!db_create_file_record(mdb, ar)) {
+      db_unlock(mdb);
       return 0;
    }
    Dmsg0(50, "db_create_file_record\n");
 
-   Dmsg3(100, "Path=%s File=%s FilenameId=%d\n", spath, file, ar->FilenameId);
+   Dmsg3(100, "Path=%s File=%s FilenameId=%d\n", mdb->path, mdb->fname, ar->FilenameId);
+   db_unlock(mdb);
    return 1;
 }
 
+/*
+ * This is the master File entry containing the attributes.
+ *  The filename and path records have already been created.
+ */
 static int db_create_file_record(B_DB *mdb, ATTR_DBR *ar)
 {
    int stat;
@@ -535,7 +485,6 @@ static int db_create_file_record(B_DB *mdb, ATTR_DBR *ar)
    ASSERT(ar->PathId);
    ASSERT(ar->FilenameId);
 
-   db_lock(mdb);
    /* Must create it */
    Mmsg(&mdb->cmd,
 "INSERT INTO File (FileIndex, JobId, PathId, FilenameId, \
@@ -553,34 +502,26 @@ LStat, MD5) VALUES (%u, %u, %u, %u, '%s', '0')",
       ar->FileId = sql_insert_id(mdb);
       stat = 1;
    }
-   db_unlock(mdb);
    return stat;
 }
 
 /* Create a Unique record for the Path -- no duplicates */
-static int db_create_path_record(B_DB *mdb, ATTR_DBR *ar, char *path)
+static int db_create_path_record(B_DB *mdb, ATTR_DBR *ar)
 {
    SQL_ROW row;
    int stat;
 
-   if (*path == 0) {
-      Mmsg0(&mdb->errmsg, _("Null path given to db_create_path_record\n"));
-      Jmsg(mdb->jcr, M_ERROR, 0, "%s", mdb->errmsg);
-      ar->PathId = 0;
-      ASSERT(ar->PathId);
-      return 0;
-   }
-
-   db_lock(mdb);
+   mdb->esc_name = check_pool_memory_size(mdb->esc_name, mdb->pnl+1);
+   db_escape_string(mdb->esc_name, mdb->path, mdb->pnl);
 
-   if (mdb->cached_path_id != 0 && strcmp(mdb->cached_path, path) == 0) {
+   if (mdb->cached_path_id != 0 && mdb->cached_path_len == mdb->pnl &&
+       strcmp(mdb->cached_path, mdb->path) == 0) {
       ar->PathId = mdb->cached_path_id;
       ASSERT(ar->PathId);
-      db_unlock(mdb);
       return 1;
    }         
 
-   Mmsg(&mdb->cmd, "SELECT PathId FROM Path WHERE Path='%s'", path);
+   Mmsg(&mdb->cmd, "SELECT PathId FROM Path WHERE Path='%s'", mdb->path);
 
    if (QUERY_DB(mdb, mdb->cmd)) {
 
@@ -589,12 +530,11 @@ static int db_create_path_record(B_DB *mdb, ATTR_DBR *ar, char *path)
       if (mdb->num_rows > 1) {
         char ed1[30];
          Mmsg2(&mdb->errmsg, _("More than one Path!: %s for Path=%s\n"), 
-           edit_uint64(mdb->num_rows, ed1), path);
+           edit_uint64(mdb->num_rows, ed1), mdb->path);
          Jmsg(mdb->jcr, M_ERROR, 0, "%s", mdb->errmsg);
       }
       if (mdb->num_rows >= 1) {
         if ((row = sql_fetch_row(mdb)) == NULL) {
-           db_unlock(mdb);
             Mmsg1(&mdb->errmsg, _("error fetching row: %s\n"), sql_strerror(mdb));
             Jmsg(mdb->jcr, M_ERROR, 0, "%s", mdb->errmsg);
            sql_free_result(mdb);
@@ -607,19 +547,17 @@ static int db_create_path_record(B_DB *mdb, ATTR_DBR *ar, char *path)
         /* Cache path */
         if (ar->PathId != mdb->cached_path_id) {
            mdb->cached_path_id = ar->PathId;
-           mdb->cached_path = check_pool_memory_size(mdb->cached_path,
-              strlen(path)+1);
-           strcpy(mdb->cached_path, path);
+           mdb->cached_path_len = mdb->pnl;
+           pm_strcpy(&mdb->cached_path, mdb->path);
         }
         ASSERT(ar->PathId);
-        db_unlock(mdb);
         return 1;
       }
 
       sql_free_result(mdb);
    }
 
-   Mmsg(&mdb->cmd, "INSERT INTO Path (Path)  VALUES ('%s')", path);
+   Mmsg(&mdb->cmd, "INSERT INTO Path (Path)  VALUES ('%s')", mdb->path);
 
    if (!INSERT_DB(mdb, mdb->cmd)) {
       Mmsg2(&mdb->errmsg, _("Create db Path record %s failed. ERR=%s\n"), 
@@ -635,48 +573,48 @@ static int db_create_path_record(B_DB *mdb, ATTR_DBR *ar, char *path)
    /* Cache path */
    if (ar->PathId != mdb->cached_path_id) {
       mdb->cached_path_id = ar->PathId;
-      mdb->cached_path = check_pool_memory_size(mdb->cached_path,
-        strlen(path)+1);
-      strcpy(mdb->cached_path, path);
+      mdb->cached_path_len = mdb->pnl;
+      pm_strcpy(&mdb->cached_path, mdb->path);
    }
    ASSERT(ar->PathId);
-   db_unlock(mdb);
    return stat;
 }
 
 /* Create a Unique record for the filename -- no duplicates */
-static int db_create_filename_record(B_DB *mdb, ATTR_DBR *ar, char *fname
+static int db_create_filename_record(B_DB *mdb, ATTR_DBR *ar) 
 {
    SQL_ROW row;
 
-   db_lock(mdb);
-   Mmsg(&mdb->cmd, "SELECT FilenameId FROM Filename WHERE Name='%s'", fname);
+   
+   mdb->esc_name = check_pool_memory_size(mdb->esc_name, mdb->fnl+1);
+   db_escape_string(mdb->esc_name, mdb->fname, mdb->fnl);
+
+   Mmsg(&mdb->cmd, "SELECT FilenameId FROM Filename WHERE Name='%s'", mdb->esc_name);
 
    if (QUERY_DB(mdb, mdb->cmd)) {
       mdb->num_rows = sql_num_rows(mdb);
       if (mdb->num_rows > 1) {
          Mmsg2(&mdb->errmsg, _("More than one Filename!: %d File=%s\n"), 
-           (int)(mdb->num_rows), fname);
+           (int)(mdb->num_rows), mdb->esc_name);
          Jmsg(mdb->jcr, M_ERROR, 0, "%s", mdb->errmsg);
       }
       if (mdb->num_rows >= 1) {
         if ((row = sql_fetch_row(mdb)) == NULL) {
             Mmsg2(&mdb->errmsg, _("error fetching row for file=%s: ERR=%s\n"), 
-               fname, sql_strerror(mdb));
+               mdb->fname, sql_strerror(mdb));
             Jmsg(mdb->jcr, M_ERROR, 0, "%s", mdb->errmsg);
            ar->FilenameId = 0;
         } else {
            ar->FilenameId = atoi(row[0]);
         }
         sql_free_result(mdb);
-        db_unlock(mdb);
         return ar->FilenameId > 0;
       }
       sql_free_result(mdb);
    }
 
    Mmsg(&mdb->cmd, "INSERT INTO Filename (Name) \
-VALUES ('%s')", fname);
+VALUES ('%s')", mdb->fname);
 
    if (!INSERT_DB(mdb, mdb->cmd)) {
       Mmsg2(&mdb->errmsg, _("Create db Filename record %s failed. ERR=%s\n"), 
@@ -687,7 +625,6 @@ VALUES ('%s')", fname);
       ar->FilenameId = sql_insert_id(mdb);
    }
 
-   db_unlock(mdb);
    return ar->FilenameId > 0;
 }
 
index 1e9781906ecaa0a82b09cf191ad9a94ca28bc628..d26c69dea60e50973f40d43223c60048c6364fc4 100644 (file)
@@ -7,7 +7,7 @@
  */
 
 /*
-   Copyright (C) 2002 Kern Sibbald and John Walker
+   Copyright (C) 2002-2003 Kern Sibbald and John Walker
 
    This program is free software; you can redistribute it and/or
    modify it under the terms of the GNU General Public License as
@@ -84,6 +84,9 @@ db_init_database(void *jcr, char *db_name, char *db_user, char *db_password)
    mdb->cached_path = get_pool_memory(PM_FNAME);
    mdb->cached_path_id = 0;
    mdb->ref_count = 1;
+   mdb->fname = get_pool_memory(PM_FNAME);
+   mdb->path = get_pool_memory(PM_FNAME);
+   mdb->esc_name = get_pool_memory(PM_FNAME);
    qinsert(&db_list, &mdb->bq);           /* put db in list */
    mdb->jcr = jcr;
    V(mutex);
@@ -169,6 +172,9 @@ db_close_database(B_DB *mdb)
       free_pool_memory(mdb->errmsg);
       free_pool_memory(mdb->cmd);
       free_pool_memory(mdb->cached_path);
+      free_pool_memory(mdb->fname);
+      free_pool_memory(mdb->path);
+      free_pool_memory(mdb->esc_name);
       if (mdb->db_name) {
         free(mdb->db_name);
       }
index c5431ee6b7431dfe39371500e422d1c73a048ad1..7e525864ce578b7491d0ef513860f429e7fcba6c 100644 (file)
@@ -1,5 +1,5 @@
 /*
-   Copyright (C) 2000, 2001, 2002 Kern Sibbald and John Walker
+   Copyright (C) 2000-2003 Kern Sibbald and John Walker
 
    This library is free software; you can redistribute it and/or
    modify it under the terms of the GNU Lesser General Public
index 8ec2304133d2686e7a7231b0e8456b24d0758150..80079a6c2db6fd98c7fd5ee6a698bff624eda2b9 100644 (file)
@@ -13,7 +13,7 @@
  *   Version $Id$
  */
 /*
-   Copyright (C) 2000, 2001, 2002 Kern Sibbald and John Walker
+   Copyright (C) 2000-2003 Kern Sibbald and John Walker
 
    This program is free software; you can redistribute it and/or
    modify it under the terms of the GNU General Public License as
@@ -244,7 +244,6 @@ msglen=%d msg=%s\n"), len, fd->msglen, fd->msg);
          Dmsg2(111, "dird<filed: stream=%d %s\n", stream, jcr->fname);
          Dmsg1(120, "dird<filed: attr=%s\n", attr);
 
-        /* ***FIXME*** fix link field */
         if (!db_create_file_attributes_record(jcr->db, &ar)) {
             Jmsg1(jcr, M_ERROR, 0, "%s", db_strerror(jcr->db));
            jcr->JobStatus = JS_Error;
index 40c5143a27a2419bdca4c30b0cef5c7cee460fce..bf834a40e281531b0601a5e3389daebe117dfe1c 100644 (file)
@@ -8,7 +8,7 @@
  *
  */
 /*
-   Copyright (C) 2000, 2001, 2002 Kern Sibbald and John Walker
+   Copyright (C) 2000-2003 Kern Sibbald and John Walker
 
    This program is free software; you can redistribute it and/or
    modify it under the terms of the GNU General Public License as
@@ -67,7 +67,6 @@ int blast_data_to_storage_daemon(JCR *jcr, char *addr)
    Dmsg0(110, "start find files\n");
 
    /* Subroutine save_file() is called for each file */
-   /* ***FIXME**** add FSM code */
    if (!find_files(jcr->ff, save_file, (void *)jcr)) {
       stat = 0;                      /* error */
    }
@@ -130,6 +129,9 @@ static int save_file(FF_PKT *ff_pkt, void *ijcr)
    case FT_SPEC:
       Dmsg1(130, "FT_SPEC saving: %s\n", ff_pkt->fname);
       break;
+   case FT_RAW:
+      Dmsg1(130, "FT_RAW saving: %s\n", ff_pkt->fname);
+      break;
    case FT_NOACCESS:
       Jmsg(jcr, M_NOTSAVED, -1, _("     Could not access %s: ERR=%s\n"), ff_pkt->fname, 
         strerror(ff_pkt->ff_errno));
@@ -166,8 +168,8 @@ static int save_file(FF_PKT *ff_pkt, void *ijcr)
       return 1;
    }
 
-   if (ff_pkt->type != FT_LNKSAVED && S_ISREG(ff_pkt->statp.st_mode) && 
-        ff_pkt->statp.st_size > 0) {
+   if (ff_pkt->type != FT_LNKSAVED && (S_ISREG(ff_pkt->statp.st_mode) && 
+        ff_pkt->statp.st_size > 0) || ff_pkt->type == FT_RAW) {
       if ((ff_pkt->fid = open(ff_pkt->fname, O_RDONLY | O_BINARY)) < 0) {
         ff_pkt->ff_errno = errno;
          Jmsg(jcr, M_NOTSAVED, -1, _("     Cannot open %s: ERR=%s.\n"), ff_pkt->fname, strerror(ff_pkt->ff_errno));
index c5821b69c2ccba6d2561ff0770297bb2c11196e8..95275fe9a328e505058a82ced0e78d3e0fe35812 100644 (file)
@@ -8,7 +8,7 @@
  *
  */
 /*
-   Copyright (C) 2000, 2001, 2002 Kern Sibbald and John Walker
+   Copyright (C) 2000-2003 Kern Sibbald and John Walker
 
    This program is free software; you can redistribute it and/or
    modify it under the terms of the GNU General Public License as
@@ -51,8 +51,6 @@ int make_estimate(JCR *jcr)
 /* 
  * Called here by find() for each file included.
  *
- *  *****FIXME*****   add FSMs File System Modules
- *
  */
 static int tally_file(FF_PKT *ff_pkt, void *ijcr)
 {
@@ -66,6 +64,7 @@ static int tally_file(FF_PKT *ff_pkt, void *ijcr)
    case FT_LNK:
    case FT_DIR:
    case FT_SPEC:
+   case FT_RAW:
       break;
    case FT_NOACCESS:
    case FT_NOFOLLOW:
index 75e8d32bd0fe3e7ad77d17f72e919a2c4fb32491..1888bf5be46a40107afe4e141bc05bde9ff5ccb7 100644 (file)
@@ -7,7 +7,7 @@
  *
  */
 /*
-   Copyright (C) 2000, 2001, 2002 Kern Sibbald and John Walker
+   Copyright (C) 2000-2003 Kern Sibbald and John Walker
 
    This program is free software; you can redistribute it and/or
    modify it under the terms of the GNU General Public License as
@@ -60,9 +60,6 @@ void do_verify(JCR *jcr)
 
 /* 
  * Called here by find() for each file.
-
-    *****FIXME*****   add FSMs File System Modules
  *
  *  Find the file, compute the MD5 and send it back to the Director
  */
@@ -102,6 +99,9 @@ static int verify_file(FF_PKT *ff_pkt, void *pkt)
    case FT_SPEC:
       Dmsg1(30, "FT_SPEC saving: %s\n", ff_pkt->fname);
       break;
+   case FT_RAW:
+      Dmsg1(30, "FT_RAW saving: %s\n", ff_pkt->fname);
+      break;
    case FT_NOACCESS:
       Jmsg(jcr, M_NOTSAVED, -1, _("     Could not access %s: ERR=%s\n"), ff_pkt->fname, strerror(ff_pkt->ff_errno));
       return 1;
@@ -133,8 +133,8 @@ static int verify_file(FF_PKT *ff_pkt, void *pkt)
    }
 
 
-   if (ff_pkt->type != FT_LNKSAVED && S_ISREG(ff_pkt->statp.st_mode) && 
-        ff_pkt->statp.st_size > 0) {
+   if (ff_pkt->type != FT_LNKSAVED && (S_ISREG(ff_pkt->statp.st_mode) && 
+        ff_pkt->statp.st_size > 0) || ff_pkt->type == FT_RAW) {
       if ((fid = open(ff_pkt->fname, O_RDONLY | O_BINARY)) < 0) {
         ff_pkt->ff_errno = errno;
          Jmsg(jcr, M_NOTSAVED, -1, _("     Cannot open %s: ERR=%s.\n"), ff_pkt->fname, strerror(ff_pkt->ff_errno));
index 42b62033366b42cea5835574733b7bef1bb860d2..33e75690d61008a860561ec11af69d8079653c14 100644 (file)
@@ -7,7 +7,7 @@
  *
  */
 /*
-   Copyright (C) 2000, 2001, 2002 Kern Sibbald and John Walker
+   Copyright (C) 2000-2003 Kern Sibbald and John Walker
 
    This program is free software; you can redistribute it and/or
    modify it under the terms of the GNU General Public License as
@@ -123,31 +123,38 @@ int create_file(void *jcr, char *fname, char *ofile, char *lname,
 
       fnl = p - f;
       if (fnl == 0) {
+        /* The filename length must not be zero here because we
+         *  are dealing with a file (i.e. FT_REGE or FT_REG).
+         */
          Jmsg1(jcr, M_ERROR, 0, _("Zero length filename: %s\n"), fname);
         return CF_ERROR;
       }
 
       pnl = f - ofile - 1;    
-      if (pnl <= 0) {
-         Jmsg1(jcr, M_ERROR, 0, _("Zero length path: %s\n"), fname);
-        return CF_ERROR;
-      }
-      savechr = ofile[pnl];
-      ofile[pnl] = 0;                /* terminate path */
 
-      Dmsg1(50, "Make path %s\n", ofile);
       /*
-       * If we need to make the directory, ensure that it is with
-       * execute bit set (i.e. parent_mode), and preserve what already
-       * exists. Normally, this should do nothing.
+       * If path length is <= 0 we are making a file in the root
+       *  directory. Assume that the directory already exists.
        */
-      stat = !make_path(jcr, ofile, parent_mode, parent_mode, uid, gid, 1, NULL);
-      if (stat == 0) {
-         Dmsg1(0, "Could not make path. %s\n", ofile);
-        return CF_ERROR;
-      }
+      if (pnl > 0) {
+        savechr = ofile[pnl];
+        ofile[pnl] = 0;                 /* terminate path */
+
+         Dmsg1(50, "Make path %s\n", ofile);
+        /*
+         * If we need to make the directory, ensure that it is with
+         * execute bit set (i.e. parent_mode), and preserve what already
+         * exists. Normally, this should do nothing.
+         */
+        stat = !make_path(jcr, ofile, parent_mode, parent_mode, uid, gid, 1, NULL);
+        if (stat == 0) {
+            Dmsg1(0, "Could not make path. %s\n", ofile);
+           return CF_ERROR;
+        }
       
-      ofile[pnl] = savechr;          /* restore full name */
+        ofile[pnl] = savechr;           /* restore full name */
+      }
+
       Dmsg1(100, "Create file %s\n", ofile);
       mode =  O_WRONLY | O_CREAT | O_TRUNC | O_BINARY;
       if (IS_CTG(statp->st_mode)) {
@@ -174,20 +181,30 @@ int create_file(void *jcr, char *fname, char *ofile, char *lname,
         return CF_ERROR;
       }
       return CF_CREATED;
+   case FT_RAW:
    case FT_SPEC:
       if (S_ISFIFO(statp->st_mode)) {
          Dmsg1(200, "Restore fifo: %s\n", ofile);
-        if (mkfifo(ofile, statp->st_mode) != 0) {
+        if (mkfifo(ofile, statp->st_mode) != 0 && errno != EEXIST) {
             Jmsg2(jcr, M_ERROR, 0, _("Cannot make fifo %s: ERR=%s\n"), ofile, strerror(errno));
            return CF_ERROR;
         }
       } else {         
          Dmsg1(200, "Restore node: %s\n", ofile);
-        if (mknod(ofile, statp->st_mode, statp->st_rdev) != 0) {
+        if (mknod(ofile, statp->st_mode, statp->st_rdev) != 0 && errno != EEXIST) {
             Jmsg2(jcr, M_ERROR, 0, _("Cannot make node %s: ERR=%s\n"), ofile, strerror(errno));
            return CF_ERROR;
         }
       }       
+      if (type == FT_RAW) {
+         Dmsg1(200, "FT_RAW %s\n", ofile);
+        mode =  O_WRONLY | O_BINARY;
+        if ((*ofd = open(ofile, mode)) < 0) {
+            Jmsg2(jcr, M_ERROR, 0, _("Could not open %s: ERR=%s\n"), ofile, strerror(errno));
+           return CF_ERROR;
+        }
+        return CF_EXTRACT;
+      }
       Dmsg1(200, "FT_SPEC %s\n", ofile);
       return CF_CREATED;
 
index 06f85ae800fbe14667c99642951fd22c6f17cd5a..afc1097d25a9013a5564972a72f33c11dd94f2d1 100644 (file)
@@ -5,7 +5,7 @@
  *  Kern E. Sibbald, MM
  */
 /*
-   Copyright (C) 2000, 2001, 2002 Kern Sibbald and John Walker
+   Copyright (C) 2000-2003 Kern Sibbald and John Walker
 
    This program is free software; you can redistribute it and/or
    modify it under the terms of the GNU General Public License as
@@ -133,8 +133,8 @@ void
 term_find_files(FF_PKT *ff)
 {
   term_include_exclude_files(ff);
-  term_find_one(ff);
   free_pool_memory(ff->sys_fname);
+  term_find_one(ff);
   free(ff);
   return;
 }
index 4c7ebd9658f501be72b1a28252c7ca8bcfa328e7..1206761abc98036d10091a562db34fac04894231 100755 (executable)
@@ -4,7 +4,7 @@
  *     Kern Sibbald MIM
  */
 /*
-   Copyright (C) 2000, 2001, 2002 Kern Sibbald and John Walker
+   Copyright (C) 2000-2003 Kern Sibbald and John Walker
 
    This program is free software; you can redistribute it and/or
    modify it under the terms of the GNU General Public License as
@@ -72,6 +72,7 @@
 #define FT_NORECURSE 13               /* No recursion into directory */
 #define FT_NOFSCHG   14               /* Different file system, prohibited */
 #define FT_NOOPEN    15               /* Could not open directory */
+#define FT_RAW       16               /* Raw block device */
 
 /* Options saved in "flag" of ff packet */
 #define FO_MD5          0x01          /* Do MD5 checksum */
index b36f798cf65502b0fb61af62582b21ac0a6ae588..b13a9da33f25b524102ccc100f7a470dbb53e644 100755 (executable)
@@ -310,8 +310,16 @@ find_one_file(FF_PKT *ff_pkt, int handle_file(FF_PKT *ff, void *hpkt), void *pkt
        return rtn_stat;
    } /* end check for directory */
 
-   /* The only remaining types are special (character, ...) files */
-   ff_pkt->type = FT_SPEC;
+   /*
+    * If it is explicitly mentioned (i.e. top_level) and is
+    *  a block device, we do a raw backup of it.
+    */
+   if (top_level && S_ISBLK(ff_pkt->statp.st_mode)) {
+      ff_pkt->type = FT_RAW;         /* raw partition */
+   } else {
+      /* The only remaining types are special (character, ...) files */
+      ff_pkt->type = FT_SPEC;
+   }
    return handle_file(ff_pkt, pkt);
 }
 
index 393a34af24b2b21aca43d9317551e3487f549cd8..ecd466b27bae3f3758d202af3932e231759bb6e1 100644 (file)
@@ -1,8 +1,8 @@
 /* */
 #define VERSION "1.28"
 #define VSTRING "1"
-#define DATE    "30 December 2002"
-#define LSMDATE "30Dec02"
+#define DATE    "2 January 2003"
+#define LSMDATE "02Jan03"
 
 /* Debug flags */
 #define DEBUG 1