int delete_or_backup(const char *path, int keep) { int res; char *p, *confp; char *dest; /* get old path */ p = (keep == CONFLICT_KEEP_REMOTE) ? cache_path(path) : remote_path(path); /* get new path (or NULL if no bprefix/bsuffix set) */ dest = conflict_path(p); if (dest) { /* move to backup filename instead of deleting */ /* rename */ res = rename(p, dest); free(dest); /* schedule push/pull for new file */ if (!res) { confp = conflict_path(path); if (keep == CONFLICT_KEEP_REMOTE) job_schedule_push(confp); else job_schedule_pull(confp); free(confp); } } /* no backup prefix or suffix set -> just delete */ else { if (is_dir(path)) res = rmdir_rec(p); else res = unlink(p); } free(p); return res; }
static int transfer_pull_dir(const char *path) { int res; char *pr, *pc; if (!strcmp(path, "/")) return -1; pr = remote_path(path); pc = cache_path(path); if (!pr || !pc) { free(pr); free(pc); return -1; } res = clone_dir(pr, pc); if (res && errno == ENOENT) { int res2; char *parent = dirname_r(path); if (parent) { res2 = transfer_pull_dir(parent); free(parent); if (!res2) res = clone_dir(pr, pc); } } free(pr); free(pc); return res; }
/*! test the file system features */ static int test_fs_features(int *f) { #define TESTFILE1 ".__discofs_test_1__" #define TESTFILE2 ".__discofs_test_2__" char *p, *p2; struct stat st, st2; struct timespec times[2]; VERBOSE("testing remote fs features\n"); /* create test file */ p = remote_path(TESTFILE1); p2 = remote_path(TESTFILE2); if (mknod(p, S_IFREG | S_IRUSR | S_IWUSR, 0)) { perror("failed to create feature test file"); return -1; } #if HAVE_UTIMENSAT && HAVE_CLOCK_GETTIME /* test if timestamps support nanosecond presicion */ /* set atime of file to 0, 1337 */ times[0].tv_sec = 0; times[0].tv_nsec = 1337; utimensat(-1, p, times, AT_SYMLINK_NOFOLLOW); /* get stat */ if (stat(p, &st)) { perror("failed to stat feature test file"); return -1; } /* check if nanoseconds were actually being set */ if (st.st_mtim.tv_nsec == times[0].tv_nsec) *f |= FEAT_NS; #endif #if HAVE_SETXATTR /* test if extended attributes are supported */ if (lsetxattr(p, "user.discofs_test", "1", 1, 0) == 0 || errno != ENOTSUP) *f |= FEAT_XATTR; #endif /* test if hard links are supported */ if (link(p, p2) == 0) { lstat(p, &st); lstat(p2, &st2); if (st.st_ino == st2.st_ino) *f |= FEAT_HARDLINKS; unlink(p2); } else perror("creating hardlink:\n"); /* remove test files */ unlink(p); unlink(p2); free(p); free(p2); return 0; #undef TESTFILE1 #undef TESTFILE2 }
int bpcp(int a1, int a2, int a3, int a4, int a5, int a6, int a7, int a8, int a9, int a10) { int t; char* argv[5]; int argc; /*Initialize CFDP*/ ion_cfdp_init(); /*Recursive flag is a1*/ iamrecursive = atoi((char*)a1); if(iamrecursive!=0 && iamrecursive!=1) { iamrecursive=0; } /*Pretty progress meter always disabled*/ showprogress=0; /*Lifetime is a2. a2=0 results in default lifetime.*/ t=strtol((char*)a2, NULL, 10); if (t > 0) { parms.utParms.lifespan=t; } /*Custody Switch is a3. 1=ON, 0=OFF*/ t = atoi((char*)a3); if(t==1) { parms.utParms.custodySwitch = SourceCustodyRequired; } else { if(t==0) { parms.utParms.custodySwitch = NoCustodyRequested; } } /*Class of Service is a4.*/ t=strtol((char*)a4, NULL, 10); if (t>=0 && t <= 2) { parms.utParms.classOfService=t; } /*Debug flag is a5.*/ debug=atoi((char*)a5); if(debug>0) { version(); } /*a6-a10 are files to copy/destinations*/ argc=0; if((char*)a6!=NULL) { argv[argc]=(char*)a6; argc++; } if((char*)a7!=NULL) { argv[argc]=(char*)a7; argc++; } if((char*)a8!=NULL) { argv[argc]=(char*)a8; argc++; } if((char*)a9!=NULL) { argv[argc]=(char*)a9; argc++; } if((char*)a10!=NULL) { argv[argc]=(char*)a10; argc++; } #else int main(int argc, char **argv) { int ch; extern char *optarg; extern int optind; int tmpoption; /*Initialize CFDP*/ ion_cfdp_init(); /*Parse commandline options*/ while ((ch = getopt(argc, argv, "dqrL:C:S:v")) != -1) { switch (ch) { case 'r': /*Recursive*/ iamrecursive = 1; break; case 'd': /*Debug*/ debug++; break; case 'v': /*Print Version info*/ version(); break; case 'q': /*Quiet*/ showprogress = 0; break; case 'L': /*Lifetime*/ tmpoption=-1; tmpoption=strtol(optarg, NULL, 10); if (tmpoption > 0) { parms.utParms.lifespan=tmpoption; } else { dbgprintf(0, "Error: Invalid BP Lifetime\n"); exit_nicely(1); } break; case 'C': /*Custody Transfer*/ if (strcmp(optarg, "Yes")==0 || strcmp(optarg, "YES")==0 || strcmp(optarg, "yes")==0 || strcmp(optarg, "y")==0 || strcmp(optarg, "On")==0 || strcmp(optarg, "ON")==0 || strcmp(optarg, "on")==0 || strcmp(optarg, "1")==0) { parms.utParms.custodySwitch = SourceCustodyRequired; } else { if (strcmp(optarg, "No")==0 || strcmp(optarg, "NO")==0 || strcmp(optarg, "yes")==0 || strcmp(optarg, "n")==0 || strcmp(optarg, "Off")==0 || strcmp(optarg, "OFF")==0 || strcmp(optarg, "off")==0 || strcmp(optarg, "0")==0) { parms.utParms.custodySwitch = NoCustodyRequested; } else { dbgprintf(0, "Error: Invalid Custody Transfer Setting\n"); } } break; case 'S': /*Class of Service*/ tmpoption=-1; tmpoption=strtol(optarg, NULL, 10); if (tmpoption>=0 && tmpoption <= 2) { parms.utParms.classOfService=tmpoption; } else { dbgprintf(0, "Error: Invalid BP Class of Service\n"); exit_nicely(1); } break; default: usage(); } } argc -= optind; argv += optind; #endif char *targ; /*Initialize tmp file array*/ memset(tmp_files,0, NUM_TMP_FILES*255); #ifdef SIG_HANDLER /*Set SIGTERM and SIGINT handlers*/ isignal(SIGTERM, handle_sigterm); isignal(SIGINT, handle_sigterm); #endif /*Additional argument checks*/ if (!isatty(STDOUT_FILENO)) { showprogress = 0; } if (argc < 2) { usage(); } if (argc > 2) { /*We are moving multiple files, destination must be a directory*/ targetshouldbedirectory = 1; } /*Connect to CFDP*/ if (cfdp_attach() < 0) { dbgprintf(0, "Error: Can't initialize CFDP. Is ION running?\n"); exit(1); } /*Create receiver thread*/ events_sem=sm_SemCreate(SM_NO_KEY, SM_SEM_FIFO); if (events_sem==SM_SEM_NONE || sm_SemTake(events_sem)<0) { dbgprintf(0, "Error: Can't create semaphore\n"); exit(1); } recv_running=1; if (pthread_begin(&rcv_thread, NULL, &rcv_msg_thread, (void*)&recv_running)) { dbgprintf(0, "Error: Can't start message thread\n"); sm_SemDelete(events_sem); exit(1); } /*Parse Paths*/ if ((targ = remote_path(argv[argc - 1]))) { /* Last path is remote path * Destination is remote host*/ toremote(targ, argc, argv); } else { /*Destination is localhost*/ if (targetshouldbedirectory) { /*If we are moving multiple files, check that destination * is directory*/ if (is_dir(argv[argc - 1])) { tolocal(argc, argv); } else { dbgprintf(0, "Error: Destination is not a directory\n"); exit_nicely(1); } } else { /*Single file copy*/ tolocal(argc, argv); } } exit_nicely(0); return 0; }