1 #include "compat.h" 2 #include <libbackuppcd.h> 3 4 #define BPC_CLIENT_LIST 0 5 #define BPC_CLIENT_GET_INCR 1 6 #define BPC_CLIENT_GET_FULL 2 7 8 const char *bpc_mungepath(const char *path) { 9 static char ret[8192]; 10 char *path_cp, *path_cp_s; 11 char *retptr, *tmpbuf; 12 13 if (!path) { 14 return(NULL); 15 } 16 17 path_cp_s = path_cp = strdup(path); 18 retptr = ret; 19 ret[0] = '\0'; 20 21 if (path[0] == '/') { 22 strcat(retptr, "f%2f"); 23 retptr += 4; 24 } 25 26 for (; (tmpbuf = strsep(&path_cp, "/")) != NULL;) { 27 if (tmpbuf[0] == '\0') { 28 continue; 29 } 30 31 *retptr = '/'; retptr++; 32 *retptr = 'f'; retptr++; 33 *retptr = '\0'; 34 strcat(retptr, tmpbuf); 35 retptr += strlen(tmpbuf); 36 } 37 38 if (*retptr == '/') { 39 retptr--; 40 } 41 *retptr = '\0'; 42 43 free(path_cp_s); 44 45 return(ret); 46 } 47 48 int main(int argc, char **argv) { 49 BPC_CONN *conn1, *conn2 = NULL; 50 struct bpc_fileinfo *finfo = NULL; 51 char *host, *port_str, *command, *username, *password; 52 char localfile[16384]; 53 int snprintf_ret; 54 int port; 55 int mode; 56 int ret; 57 char type_string[][7] = {"dir", "file", "syml", "sock", "fifo", "blk", "chr", "hrdl"}; 58 const char *pooldir = "/tmp/bpc/cpool"; 59 const char *lastdir = "/tmp/bpc/pc/test/1"; 60 61 if (argc != 6) { 62 printf("Usage: backuppcd-client <host> <port> <username> <password> {GET|LIST|GETFULL}\n"); 63 return(EXIT_FAILURE); 64 } 65 66 host = argv[1]; 67 port_str = argv[2]; 68 username = argv[3]; 69 password = argv[4]; 70 command = argv[5]; 71 72 port = strtoul(port_str, NULL, 10); 73 74 conn1 = bpc_connect(host, port, username, password); 75 if (!conn1) { 76 fprintf(stderr, "Failed (connect)\n"); 77 return(EXIT_FAILURE); 78 } 79 80 if (strcasecmp(command, "list") == 0) { 81 mode = BPC_CLIENT_LIST; 82 } else if (strcasecmp(command, "get") == 0) { 83 mode = BPC_CLIENT_GET_INCR; 84 } else if (strcasecmp(command, "getfull") == 0) { 85 mode = BPC_CLIENT_GET_FULL; 86 } else { 87 fprintf(stderr, "Invalid operation: %s\n", command); 88 return(EXIT_FAILURE); 89 } 90 91 /* 92 * Begin operation 93 */ 94 switch (mode) { 95 case BPC_CLIENT_LIST: 96 ret = bpc_list_open(conn1, "/", 1, BPC_HASH_NONE, NULL, NULL); 97 break; 98 case BPC_CLIENT_GET_INCR: 99 ret = bpc_list_open(conn1, "/", 1, BPC_HASH_BPC, NULL, NULL); 100 101 conn2 = bpc_connect(host, port, username, password); 102 if (!conn2) { 103 fprintf(stderr, "Failed (connect)\n"); 104 return(EXIT_FAILURE); 105 } 106 break; 107 case BPC_CLIENT_GET_FULL: 108 ret = bpc_get_open(conn1, "/", 1, BPC_HASH_NONE, NULL, NULL); 109 break; 110 } 111 112 if (!ret) { 113 fprintf(stderr, "Failed (open)\n"); 114 return(EXIT_FAILURE); 115 } 116 117 /* 118 * Process every entry. 119 */ 120 while (1) { 121 switch (mode) { 122 case BPC_CLIENT_LIST: 123 finfo = bpc_list(conn1); 124 break; 125 case BPC_CLIENT_GET_INCR: 126 finfo = bpc_list(conn1); 127 break; 128 case BPC_CLIENT_GET_FULL: 129 finfo = bpc_get_head(conn1); 130 break; 131 } 132 133 if (!finfo) { 134 printf("--- end ---\n"); 135 break; 136 } 137 138 printf("[%4s] %06o %6lu %6lu %10llu %12lu %s", 139 type_string[finfo->type], 140 (unsigned int) finfo->mode, 141 (unsigned long) finfo->uid, 142 (unsigned long) finfo->gid, 143 (unsigned long long) finfo->size, 144 (unsigned long) finfo->mtime, 145 finfo->name); 146 if (finfo->type == BPC_FILE_SYMLINK || finfo->type == BPC_FILE_HRDLINK) { 147 printf(" -> %s", finfo->linkdest); 148 } 149 printf("\n"); 150 151 if (mode == BPC_CLIENT_LIST) { 152 continue; 153 } 154 155 snprintf_ret = snprintf(localfile, sizeof(localfile), "%s/%s", ".", bpc_mungepath(finfo->name)); 156 if (snprintf_ret < 0 || snprintf_ret >= sizeof(localfile)) { 157 PRINTERR("Filename too long. Something is almost definitely wrong, aborting."); 158 ret = 0; 159 CHECKPOINT; 160 break; 161 } 162 163 switch (mode) { 164 case BPC_CLIENT_GET_INCR: 165 if (finfo->type == BPC_FILE_DIR) { 166 backuppc_mkdir(localfile); 167 } 168 169 if (finfo->type != BPC_FILE_REG) { 170 break; 171 } 172 173 /* 174 * XXX: SIMPLE DUMB CHECK: 175 */ 176 if (access(localfile, F_OK) == 0) { 177 break; 178 } 179 180 CHECKPOINT; 181 SPOTVAR_S(finfo->name); 182 ret = bpc_get_open(conn2, finfo->name, 0, BPC_HASH_NONE, NULL, NULL); 183 CHECKPOINT; 184 if (!ret) { 185 CHECKPOINT; 186 break; 187 } 188 189 CHECKPOINT; 190 finfo = bpc_get_head(conn2); 191 CHECKPOINT; 192 if (!finfo) { 193 ret = bpc_get_close(conn2); 194 CHECKPOINT; 195 break; 196 } 197 198 ret = bpc_copyfile(conn2, finfo, localfile, 0); 199 if (!ret) { 200 CHECKPOINT; 201 } 202 203 finfo = bpc_get_head(conn2); 204 if (finfo != NULL) { 205 ret = 0; 206 break; 207 } 208 209 ret = bpc_get_close(conn2); 210 CHECKPOINT; 211 break; 212 case BPC_CLIENT_GET_FULL: 213 ret = bpc_copyfile(conn1, finfo, localfile, 0); 214 215 CHECKPOINT; 216 break; 217 } 218 219 if (!ret) { 220 printf("---- failed during file copy ----\n"); 221 break; 222 } 223 } 224 225 /* 226 * Cleanup 227 */ 228 switch (mode) { 229 case BPC_CLIENT_LIST: 230 ret = bpc_list_close(conn1); 231 break; 232 case BPC_CLIENT_GET_INCR: 233 ret = bpc_list_close(conn1); 234 break; 235 case BPC_CLIENT_GET_FULL: 236 ret = bpc_get_close(conn1); 237 break; 238 } 239 240 if (!ret) { 241 fprintf(stderr, "Failed (close).\n"); 242 return(EXIT_FAILURE); 243 } 244 245 bpc_disconnect(conn1); 246 if (conn2) { 247 bpc_disconnect(conn2); 248 } 249 250 fprintf(stderr, "Done.\n"); 251 return(EXIT_SUCCESS); 252 } |