32  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
  33  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
  34  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
  35  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
  36  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  37  * POSSIBILITY OF SUCH DAMAGE.
  38  */
  39 #include <stdlib.h>
  40 #include <stdio.h>
  41 #include <string.h>
  42 #include <sys/queue.h>
  43 #include <sys/syslog.h>
  44 #include "tlm.h"
  45 #include "tlm_proto.h"
  46 
  47 #define HL_DBG_INIT             0x0001
  48 #define HL_DBG_CLEANUP  0x0002
  49 #define HL_DBG_GET      0x0004
  50 #define HL_DBG_ADD      0x0008
  51 
  52 static int hardlink_q_dbg = -1;
  53 
  54 
  55 struct hardlink_q *
  56 hardlink_q_init()
  57 {
  58         struct hardlink_q *qhead;
  59 
  60         qhead = (struct hardlink_q *)malloc(sizeof (struct hardlink_q));
  61         if (qhead) {
  62                 SLIST_INIT(qhead);
  63         }
  64 
  65         if (hardlink_q_dbg & HL_DBG_INIT)
  66                 NDMP_LOG(LOG_DEBUG, "qhead = %p", qhead);
  67 
  68         return (qhead);
  69 }
  70 
  71 void
  72 hardlink_q_cleanup(struct hardlink_q *hl_q)
  73 {
  74         struct hardlink_node *hl;
  75 
  76         if (hardlink_q_dbg & HL_DBG_CLEANUP)
  77                 NDMP_LOG(LOG_DEBUG, "(1): qhead = %p", hl_q);
  78 
  79         if (!hl_q)
  80                 return;
  81 
  82         while (!SLIST_EMPTY(hl_q)) {
  83                 hl = SLIST_FIRST(hl_q);
  84 
  85                 if (hardlink_q_dbg & HL_DBG_CLEANUP)
  86                         NDMP_LOG(LOG_DEBUG, "(2): remove node, inode = %lu",
  87                             hl->inode);
  88 
  89                 SLIST_REMOVE_HEAD(hl_q, next_hardlink);
  90 
  91                 /* remove the temporary file */
  92                 if (hl->is_tmp) {
  93                         if (hl->path) {
  94                                 NDMP_LOG(LOG_DEBUG, "(3): remove temp file %s",
  95                                     hl->path);
  96                                 if (remove(hl->path)) {
  97                                         NDMP_LOG(LOG_DEBUG,
  98                                             "error removing temp file");
  99                                 }
 100                         } else {
 101                                 NDMP_LOG(LOG_DEBUG, "no link name, inode = %lu",
 102                                     hl->inode);
 103                         }
 104                 }
 105 
 106                 if (hl->path)
 107                         free(hl->path);
 108                 free(hl);
 109         }
 110 
 111         free(hl_q);
 112 }
 113 
 114 /*
 115  * Return 0 if a list node has the same inode, and initialize offset and path
 116  * with the information in the list node.
 117  * Return -1 if no matching node is found.
 118  */
 119 int
 120 hardlink_q_get(struct hardlink_q *hl_q, unsigned long inode,
 121     unsigned long long *offset, char **path)
 122 {
 123         struct hardlink_node *hl;
 124 
 125         if (hardlink_q_dbg & HL_DBG_GET)
 126                 NDMP_LOG(LOG_DEBUG, "(1): qhead = %p, inode = %lu",
 127                     hl_q, inode);
 128 
 129         if (!hl_q)
 130                 return (-1);
 131 
 132         SLIST_FOREACH(hl, hl_q, next_hardlink) {
 133                 if (hardlink_q_dbg & HL_DBG_GET)
 134                         NDMP_LOG(LOG_DEBUG, "(2): checking, inode = %lu",
 135                             hl->inode);
 136 
 137                 if (hl->inode != inode)
 138                         continue;
 139 
 140                 if (offset)
 141                         *offset = hl->offset;
 142 
 143                 if (path)
 144                         *path = hl->path;
 145 
 146                 return (0);
 147         }
 148 
 149         return (-1);
 150 }
 151 
 152 /*
 153  * Add a node to hardlink_q.  Reject a duplicated entry.
 154  *
 155  * Return 0 if successful, and -1 if failed.
 156  */
 157 int
 158 hardlink_q_add(struct hardlink_q *hl_q, unsigned long inode,
 159     unsigned long long offset, char *path, int is_tmp_file)
 160 {
 161         struct hardlink_node *hl;
 162 
 163         if (hardlink_q_dbg & HL_DBG_ADD)
 164                 NDMP_LOG(LOG_DEBUG,
 165                     "(1): qhead = %p, inode = %lu, path = %p (%s)",
 166                     hl_q, inode, path, path? path : "(--)");
 167 
 168         if (!hl_q)
 169                 return (-1);
 170 
 171         if (!hardlink_q_get(hl_q, inode, 0, 0)) {
 172                 NDMP_LOG(LOG_DEBUG, "hardlink (inode = %lu) exists in queue %p",
 173                     inode, hl_q);
 174                 return (-1);
 175         }
 176 
 177         hl = (struct hardlink_node *)malloc(sizeof (struct hardlink_node));
 178         if (!hl)
 179                 return (-1);
 180 
 181         hl->inode = inode;
 182         hl->offset = offset;
 183         hl->is_tmp = is_tmp_file;
 184         if (path)
 185                 hl->path = strdup(path);
 186         else
 187                 hl->path = NULL;
 188 
 189         if (hardlink_q_dbg & HL_DBG_ADD)
 190                 NDMP_LOG(LOG_DEBUG,
 191                     "(2): added node, inode = %lu, path = %p (%s)",
 192                     hl->inode, hl->path, hl->path? hl->path : "(--)");
 193 
 194         SLIST_INSERT_HEAD(hl_q, hl, next_hardlink);
 195 
 196         return (0);
 197 }
 198 
 199 int
 200 hardlink_q_dump(struct hardlink_q *hl_q)
 201 {
 202         struct hardlink_node *hl;
 203 
 204         if (!hl_q)
 205                 return (0);
 206 
 207         (void) printf("Dumping hardlink_q, head = %p:\n", (void *) hl_q);
 208 
 209         SLIST_FOREACH(hl, hl_q, next_hardlink)
 210                 (void) printf(
 211                     "\t node = %lu, offset = %llu, path = %s, is_tmp = %d\n",
 212                     hl->inode, hl->offset, hl->path? hl->path : "--",
 213                     hl->is_tmp);
 | 
 
 
  32  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
  33  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
  34  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
  35  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
  36  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  37  * POSSIBILITY OF SUCH DAMAGE.
  38  */
  39 #include <stdlib.h>
  40 #include <stdio.h>
  41 #include <string.h>
  42 #include <sys/queue.h>
  43 #include <sys/syslog.h>
  44 #include "tlm.h"
  45 #include "tlm_proto.h"
  46 
  47 #define HL_DBG_INIT             0x0001
  48 #define HL_DBG_CLEANUP  0x0002
  49 #define HL_DBG_GET      0x0004
  50 #define HL_DBG_ADD      0x0008
  51 
  52 struct hardlink_q *
  53 hardlink_q_init()
  54 {
  55         struct hardlink_q *qhead;
  56 
  57         qhead = (struct hardlink_q *)malloc(sizeof (struct hardlink_q));
  58         if (qhead) {
  59                 SLIST_INIT(qhead);
  60         }
  61 
  62         return (qhead);
  63 }
  64 
  65 void
  66 hardlink_q_cleanup(struct hardlink_q *hl_q)
  67 {
  68         struct hardlink_node *hl;
  69 
  70         if (!hl_q)
  71                 return;
  72 
  73         while (!SLIST_EMPTY(hl_q)) {
  74                 hl = SLIST_FIRST(hl_q);
  75 
  76                 SLIST_REMOVE_HEAD(hl_q, next_hardlink);
  77 
  78                 /* remove the temporary file */
  79                 if (hl->is_tmp) {
  80                         if (hl->path) {
  81                                 (void) remove(hl->path);
  82                         }
  83                 }
  84 
  85                 if (hl->path)
  86                         free(hl->path);
  87                 free(hl);
  88         }
  89 
  90         free(hl_q);
  91 }
  92 
  93 /*
  94  * Return 0 if a list node has the same inode, and initialize offset and path
  95  * with the information in the list node.
  96  * Return -1 if no matching node is found.
  97  */
  98 int
  99 hardlink_q_get(struct hardlink_q *hl_q, unsigned long inode,
 100     unsigned long long *offset, char **path)
 101 {
 102         struct hardlink_node *hl;
 103 
 104         if (!hl_q)
 105                 return (-1);
 106 
 107         SLIST_FOREACH(hl, hl_q, next_hardlink) {
 108 
 109                 if (hl->inode != inode)
 110                         continue;
 111 
 112                 if (offset)
 113                         *offset = hl->offset;
 114 
 115                 if (path)
 116                         *path = hl->path;
 117 
 118                 return (0);
 119         }
 120 
 121         return (-1);
 122 }
 123 
 124 /*
 125  * Add a node to hardlink_q.  Reject a duplicated entry.
 126  *
 127  * Return 0 if successful, and -1 if failed.
 128  */
 129 int
 130 hardlink_q_add(struct hardlink_q *hl_q, unsigned long inode,
 131     unsigned long long offset, char *path, int is_tmp_file)
 132 {
 133         struct hardlink_node *hl;
 134 
 135         if (!hl_q)
 136                 return (-1);
 137 
 138         if (!hardlink_q_get(hl_q, inode, 0, 0)) {
 139                 return (-1);
 140         }
 141 
 142         hl = (struct hardlink_node *)malloc(sizeof (struct hardlink_node));
 143         if (!hl)
 144                 return (-1);
 145 
 146         hl->inode = inode;
 147         hl->offset = offset;
 148         hl->is_tmp = is_tmp_file;
 149         if (path)
 150                 hl->path = strdup(path);
 151         else
 152                 hl->path = NULL;
 153 
 154         SLIST_INSERT_HEAD(hl_q, hl, next_hardlink);
 155 
 156         return (0);
 157 }
 158 
 159 int
 160 hardlink_q_dump(struct hardlink_q *hl_q)
 161 {
 162         struct hardlink_node *hl;
 163 
 164         if (!hl_q)
 165                 return (0);
 166 
 167         (void) printf("Dumping hardlink_q, head = %p:\n", (void *) hl_q);
 168 
 169         SLIST_FOREACH(hl, hl_q, next_hardlink)
 170                 (void) printf(
 171                     "\t node = %lu, offset = %llu, path = %s, is_tmp = %d\n",
 172                     hl->inode, hl->offset, hl->path? hl->path : "--",
 173                     hl->is_tmp);
 |