// Return 1 for ok, -1 for error, 0 for too many components stripped. static int strip_path_components(struct asfd *asfd, struct sbuf *sb, int strip, struct cntr *cntr, enum protocol protocol) { int s=0; char *tmp=NULL; char *cp=sb->path.buf; char *dp=NULL; for(s=0; cp && *cp && s<strip; s++) { if(!(dp=strchr(cp, '/'))) { char msg[256]=""; snprintf(msg, sizeof(msg), "Stripped too many components: %s", sb->path.buf); if(restore_interrupt(asfd, sb, msg, cntr, protocol)) return -1; return 0; } cp=dp+1; } if(!cp) { char msg[256]=""; snprintf(msg, sizeof(msg), "Stripped too many components: %s", sb->path.buf); if(restore_interrupt(asfd, sb, msg, cntr, protocol)) return -1; return 0; } if(!(tmp=strdup_w(cp, __func__))) return -1; free_w(&sb->path.buf); sb->path.buf=tmp; return 1; }
static int open_for_restore(struct asfd *asfd, BFILE *bfd, FILE **fp, const char *path, struct sbuf *sb, int vss_restore, struct conf *conf) { #ifdef HAVE_WIN32 if(bfd->mode!=BF_CLOSED) { if(bfd->path && !strcmp(bfd->path, path)) { // Already open after restoring the VSS data. // Time now for the actual file data. return 0; } else { if(bclose(bfd, asfd)) { logp("error closing %s in %s()\n", path, __func__); return -1; } } } binit(bfd, sb->winattr, conf); if(vss_restore) set_win32_backup(bfd); else bfd->use_backup_api=0; if(bopen(bfd, asfd, path, O_WRONLY | O_CREAT | O_TRUNC | O_BINARY, S_IRUSR | S_IWUSR)<=0) { berrno be; char msg[256]=""; snprintf(msg, sizeof(msg), "Could not open for writing %s: %s", path, be.bstrerror(errno)); if(restore_interrupt(asfd, sb, msg, conf)) return -1; } #else if(!(*fp=open_file(path, "wb"))) { char msg[256]=""; snprintf(msg, sizeof(msg), "Could not open for writing %s: %s", path, strerror(errno)); if(restore_interrupt(asfd, sb, msg, conf)) return -1; } #endif // Add attributes to bfd so that they can be set when it is closed. bfd->winattr=sb->winattr; memcpy(&bfd->statp, &sb->statp, sizeof(struct stat)); return 0; }
static int warn_and_interrupt(struct asfd *asfd, struct sbuf *sb, struct cntr *cntr, enum protocol protocol, const char *text, const char *param) { return restore_interrupt(asfd, sb, build_msg(text, param), cntr, protocol); }
bool timer_set(long cycles, bool start) { /* Maximum cycle count expressible in the cycles parameter is 2^31-1 * and the modulus counter is capable of 2^32-1 and as a result there is * no requirement to use a prescaler > 1. This gives a frequency range of * ~0.015366822Hz - 66000000Hz. The highest input frequency gives the * greatest possible accuracy anyway. */ int oldstatus = disable_interrupt_save(IRQ_FIQ_STATUS); /* Halt timer if running - leave module clock enabled */ stop_timer(false); if (start && pfn_unregister != NULL) { pfn_unregister(); pfn_unregister = NULL; } /* CLKSRC = ipg_clk, * EPIT output disconnected, * Enabled in wait mode * Prescale 1 for 66MHz * Reload from modulus register, * Count from load value */ EPITCR2 = EPITCR_CLKSRC_IPG_CLK | EPITCR_WAITEN | EPITCR_IOVW | ((1-1) << EPITCR_PRESCALER_POS) | EPITCR_RLD | EPITCR_ENMOD; EPITLR2 = cycles; /* Event when counter reaches 0 */ EPITCMPR2 = 0; restore_interrupt(oldstatus); return true; }
/*! \brief Read a bit from the bus(es). (Software only driver) * * Generates the waveform for reception of a bit on the 1-Wire(R) bus(es). * * \param pins A bitmask of the bus(es) to read from. * * \return A bitmask of the buses where a '1' was read. */ unsigned char OWI_ReadBit(unsigned char pins) { uint8_t intState; unsigned char bitsRead; // Disable interrupts. intState = save_interrupt(); // __disable_interrupt(); // Drive bus low and delay. OWI_PULL_BUS_LOW(pins); _delay_loop_2((OWI_DELAY_A_STD_MODE) / 4); // Release bus and delay. OWI_RELEASE_BUS(pins); _delay_loop_2((OWI_DELAY_E_STD_MODE) / 4); // Sample bus and delay. bitsRead = OWI_PIN & pins; _delay_loop_2((OWI_DELAY_F_STD_MODE) / 4); // Restore interrupts. restore_interrupt(intState); return bitsRead; }
/*! \brief Send a Reset signal and listen for Presence signal. (software * only driver) * * Generates the waveform for transmission of a Reset pulse on the * 1-Wire(R) bus and listens for presence signals. * * \param pins A bitmask of the buses to send the Reset signal on. * * \return A bitmask of the buses where a presence signal was detected. */ unsigned char OWI_DetectPresence(unsigned char pins) { uint8_t intState; unsigned char presenceDetected; // Disable interrupts. intState = save_interrupt(); // __disable_interrupt(); // Drive bus low and delay. OWI_PULL_BUS_LOW(pins); _delay_loop_2((OWI_DELAY_H_STD_MODE) / 4); // Release bus and delay. OWI_RELEASE_BUS(pins); _delay_loop_2((OWI_DELAY_I_STD_MODE) / 4); // Sample bus to detect presence signal and delay. presenceDetected = ((~OWI_PIN) & pins); _delay_loop_2((OWI_DELAY_J_STD_MODE) / 4); // Restore interrupts. restore_interrupt(intState); return presenceDetected; }
void timer_stop(void) { int oldstatus = disable_interrupt_save(IRQ_FIQ_STATUS); /* Halt timer if running - stop module clock */ stop_timer(true); restore_interrupt(oldstatus); }
void timer_stop(void) { int oldstatus = disable_interrupt_save(IRQ_STATUS); TCFG(4) &= ~TCFG_EN; restore_interrupt(oldstatus); }
// FIX THIS: Maybe should be in bfile.c. enum ofr_e open_for_restore(struct asfd *asfd, BFILE *bfd, const char *path, struct sbuf *sb, int vss_restore, struct cntr *cntr, enum protocol protocol) { static int flags; if(bfd->mode!=BF_CLOSED) { #ifdef HAVE_WIN32 if(bfd->path && !strcmp(bfd->path, path)) { // Already open after restoring the VSS data. // Time now for the actual file data. return OFR_OK; } else { #endif if(bfd->close(bfd, asfd)) { logp("error closing %s in %s()\n", path, __func__); return OFR_ERROR; } #ifdef HAVE_WIN32 } #endif } bfile_init(bfd, sb->winattr, cntr); #ifdef HAVE_WIN32 bfd->set_win32_api(bfd, vss_restore); #endif if(S_ISDIR(sb->statp.st_mode)) { // Windows directories are treated as having file data. flags=O_WRONLY|O_BINARY; mkdir(path, 0777); } else flags=O_WRONLY|O_BINARY|O_CREAT|O_TRUNC; if(bfd->open(bfd, asfd, path, flags, S_IRUSR | S_IWUSR)) { berrno be; berrno_init(&be); char msg[256]=""; snprintf(msg, sizeof(msg), "Could not open for writing %s: %s", path, berrno_bstrerror(&be, errno)); if(restore_interrupt(asfd, sb, msg, cntr, protocol)) return OFR_ERROR; return OFR_CONTINUE; } // Add attributes to bfd so that they can be set when it is closed. bfd->winattr=sb->winattr; memcpy(&bfd->statp, &sb->statp, sizeof(struct stat)); return OFR_OK; }
bool timer_start(void) { int oldstatus = disable_interrupt_save(IRQ_STATUS); TCFG(4) |= TCFG_CLEAR | TCFG_IEN | TCFG_EN; restore_interrupt(oldstatus); return true; }
size_t pcm_get_bytes_waiting(void) { int oldstatus = disable_irq_save(); size_t addr = DMAC_CH_SRC_ADDR(0); size_t start_addr = (size_t)dma_start_addr; size_t start_size = dma_start_size; restore_interrupt(oldstatus); return start_size - addr + start_addr; }
const void * pcm_play_dma_get_peak_buffer(int *count) { int oldstatus = disable_irq_save(); size_t addr = DMAC_CH_SRC_ADDR(0); size_t start_addr = (size_t)dma_start_addr; size_t start_size = dma_start_size; restore_interrupt(oldstatus); *count = (start_size - addr + start_addr) >> 2; return (void*)AS3525_UNCACHED_ADDR(addr); }
static int restore_link(struct asfd *asfd, struct sbuf *sb, const char *fname, const char *restoreprefix, enum action act, struct conf *conf) { int ret=0; if(act==ACTION_RESTORE) { char *rpath=NULL; if(build_path(fname, "", &rpath, NULL)) { char msg[256]=""; // failed - do a warning snprintf(msg, sizeof(msg), "build path failed: %s", fname); if(restore_interrupt(asfd, sb, msg, conf)) ret=-1; goto end; } else if(make_link(asfd, fname, sb->link.buf, sb->link.cmd, restoreprefix, conf)) { // failed - do a warning if(restore_interrupt(asfd, sb, "could not create link", conf)) ret=-1; goto end; } else if(!ret) { attribs_set(asfd, fname, &(sb->statp), sb->winattr, conf); cntr_add(conf->cntr, sb->path.cmd, 1); } if(rpath) free(rpath); } else cntr_add(conf->cntr, sb->path.cmd, 1); end: return ret; }
/* Return 1 for ok, -1 for error, 0 for too many components stripped. */ static int strip_path_components(struct asfd *asfd, struct sbuf *sb, char **path, struct conf *conf) { int s=0; char *tmp=NULL; char *cp=*path; char *dp=NULL; for(s=0; cp && *cp && s<conf->strip; s++) { if(!(dp=strchr(cp, '/'))) { char msg[256]=""; snprintf(msg, sizeof(msg), "Stripped too many components: %s", *path); if(restore_interrupt(asfd, sb, msg, conf)) return -1; return 0; } cp=dp+1; } if(!cp) { char msg[256]=""; snprintf(msg, sizeof(msg), "Stripped too many components: %s", *path); if(restore_interrupt(asfd, sb, msg, conf)) return -1; return 0; } if(!(tmp=strdup(cp))) { log_and_send_oom(asfd, __func__); return -1; } free(*path); *path=tmp; return 1; }
static int restore_dir(struct asfd *asfd, struct sbuf *sb, const char *dname, enum action act, struct conf *conf) { int ret=0; char *rpath=NULL; if(act==ACTION_RESTORE) { if(build_path(dname, "", &rpath, NULL)) { char msg[256]=""; // failed - do a warning snprintf(msg, sizeof(msg), "build path failed: %s", dname); if(restore_interrupt(asfd, sb, msg, conf)) ret=-1; goto end; } else if(!is_dir_lstat(rpath)) { if(mkdir(rpath, 0777)) { char msg[256]=""; snprintf(msg, sizeof(msg), "mkdir error: %s", strerror(errno)); // failed - do a warning if(restore_interrupt(asfd, sb, msg, conf)) ret=-1; goto end; } } attribs_set(asfd, rpath, &(sb->statp), sb->winattr, conf); if(!ret) cntr_add(conf->cntr, sb->path.cmd, 1); } else cntr_add(conf->cntr, sb->path.cmd, 1); end: if(rpath) free(rpath); return ret; }
static int restore_file_or_get_meta(struct asfd *asfd, BFILE *bfd, struct sbuf *sb, const char *fname, enum action act, char **metadata, size_t *metalen, int vss_restore, struct cntr *cntr, const char *encyption_password) { int ret=0; char *rpath=NULL; if(act==ACTION_VERIFY) { cntr_add(cntr, sb->path.cmd, 1); goto end; } if(build_path(fname, "", &rpath, NULL)) { char msg[256]=""; // failed - do a warning snprintf(msg, sizeof(msg), "build path failed: %s", fname); if(restore_interrupt(asfd, sb, msg, cntr, PROTO_1)) ret=-1; goto end; } #ifndef HAVE_WIN32 // We always want to open the file if it is on Windows. Otherwise, // only open it if we are not doing metadata. if(!metadata) { #endif switch(open_for_restore(asfd, bfd, rpath, sb, vss_restore, cntr, PROTO_1)) { case OFR_OK: break; case OFR_CONTINUE: goto end; default: ret=-1; goto end; } #ifndef HAVE_WIN32 } #endif if(!(ret=do_restore_file_or_get_meta(asfd, bfd, sb, fname, metadata, metalen, cntr, rpath, encyption_password))) cntr_add(cntr, sb->path.cmd, 1); end: free_w(&rpath); if(ret) logp("restore_file error\n"); return ret; }
// Return 1 for ok, -1 for error, 0 for too many components stripped. static int strip_path_components(struct asfd *asfd, struct sbuf *sb, struct conf **confs) { int s=0; char *tmp=NULL; char *cp=sb->path.buf; char *dp=NULL; int strip=get_int(confs[OPT_STRIP]); for(s=0; cp && *cp && s<strip; s++) { if(!(dp=strchr(cp, '/'))) { char msg[256]=""; snprintf(msg, sizeof(msg), "Stripped too many components: %s", sb->path.buf); if(restore_interrupt(asfd, sb, msg, confs)) return -1; return 0; } cp=dp+1; } if(!cp) { char msg[256]=""; snprintf(msg, sizeof(msg), "Stripped too many components: %s", sb->path.buf); if(restore_interrupt(asfd, sb, msg, confs)) return -1; return 0; } if(!(tmp=strdup_w(cp, __func__))) return -1; free(sb->path.buf); sb->path.buf=tmp; return 1; }
static int start_restore_file(struct asfd *asfd, BFILE *bfd, struct sbuf *sb, const char *fname, enum action act, const char *encpassword, char **metadata, size_t *metalen, int vss_restore, struct cntr *cntr) { int ret=-1; char *rpath=NULL; if(act==ACTION_VERIFY) { cntr_add(cntr, sb->path.cmd, 1); goto end; } if(build_path(fname, "", &rpath, NULL)) { char msg[256]=""; // Failed - do a warning. snprintf(msg, sizeof(msg), "build path failed: %s", fname); if(restore_interrupt(asfd, sb, msg, cntr, PROTO_2)) goto error; goto end; // Try to carry on with other files. } switch(open_for_restore(asfd, bfd, rpath, sb, vss_restore, cntr, PROTO_2)) { case OFR_OK: break; case OFR_CONTINUE: goto end; default: goto error; } cntr_add(cntr, sb->path.cmd, 1); end: ret=0; error: free_w(&rpath); return ret; }
bool timer_start(void) { int oldstatus = disable_interrupt_save(IRQ_FIQ_STATUS); /* Halt timer if running - leave module clock enabled */ stop_timer(false); /* Enable interrupt */ EPITCR2 |= EPITCR_OCIEN; avic_enable_int(INT_EPIT2, INT_TYPE_IRQ, INT_PRIO_DEFAULT, EPIT2_HANDLER); /* Start timer */ EPITCR2 |= EPITCR_EN; restore_interrupt(oldstatus); return true; }
bool timer_start(void) { int oldstatus = disable_interrupt_save(IRQ_FIQ_STATUS); stop_timer(); /* enable TIMER0 clock */ bitset16(&IO_CLK_MOD2, CLK_MOD2_TMR0); /* Turn Timer0 to Free Run mode */ IO_TIMER0_TMMD = CONFIG_TIMER0_TMMD_FREE_RUN; /* enable TIMER0 interrupt */ bitset16(&IO_INTC_EINT0, INTR_EINT0_TMR0); restore_interrupt(oldstatus); return true; }
/*! \brief Write a '0' to the bus(es). (Software only driver) * * Generates the waveform for transmission of a '0' bit on the 1-Wire(R) * bus. * * \param pins A bitmask of the buses to write to. */ void OWI_WriteBit0(unsigned char pins) { uint8_t intState; // Disable interrupts. intState = save_interrupt(); // __disable_interrupt(); // Drive bus low and delay. OWI_PULL_BUS_LOW(pins); _delay_loop_2((OWI_DELAY_C_STD_MODE) / 4); // Release bus and delay. OWI_RELEASE_BUS(pins); _delay_loop_2((OWI_DELAY_D_STD_MODE) / 4); // Restore interrupts. restore_interrupt(intState); }
void imx233_timrot_setup(unsigned timer_nr, bool reload, unsigned count, unsigned src, unsigned prescale, bool polarity, imx233_timer_fn_t fn) { int oldstatus = disable_interrupt_save(IRQ_FIQ_STATUS); /* only enable interrupt if function is set */ bool irq = fn != NULL; timer_fns[timer_nr] = fn; /* make sure we start from stop state */ HW_TIMROT_TIMCTRLn(timer_nr) = BF_OR2(TIMROT_TIMCTRLn, SELECT(BV_TIMROT_TIMCTRLn_SELECT__NEVER_TICK), UPDATE(1)); /* write count and take effect immediately with UPDATE * manual says count-1 for reload timers */ HW_TIMROT_TIMCOUNTn(timer_nr) = reload ? count - 1 : count; /* start timer */ HW_TIMROT_TIMCTRLn(timer_nr) = BF_OR6(TIMROT_TIMCTRLn, SELECT(src), PRESCALE(prescale), POLARITY(polarity), RELOAD(reload), IRQ(irq), IRQ_EN(irq)); imx233_icoll_enable_interrupt(INT_SRC_TIMER(timer_nr), irq); restore_interrupt(oldstatus); }
int do_restore_client(struct asfd *asfd, struct conf **confs, enum action act, int vss_restore) { int ret=-1; char msg[512]=""; struct sbuf *sb=NULL; struct blk *blk=NULL; BFILE *bfd=NULL; char *fullpath=NULL; char *style=NULL; char *datpath=NULL; struct cntr *cntr=get_cntr(confs); enum protocol protocol=get_protocol(confs); int strip=get_int(confs[OPT_STRIP]); int overwrite=get_int(confs[OPT_OVERWRITE]); const char *backup=get_string(confs[OPT_BACKUP]); const char *regex=get_string(confs[OPT_REGEX]); const char *restore_prefix=get_string(confs[OPT_RESTOREPREFIX]); const char *encryption_password=get_string(confs[OPT_ENCRYPTION_PASSWORD]); if(!(bfd=bfile_alloc())) goto end; bfile_init(bfd, 0, cntr); snprintf(msg, sizeof(msg), "%s %s:%s", act_str(act), backup?backup:"", regex?regex:""); logp("doing %s\n", msg); if(asfd->write_str(asfd, CMD_GEN, msg) || asfd_read_expect(asfd, CMD_GEN, "ok")) goto error; logp("doing %s confirmed\n", act_str(act)); #if defined(HAVE_WIN32) if(act==ACTION_RESTORE) win32_enable_backup_privileges(); #endif if(!(style=get_restore_style(asfd, confs))) goto error; if(!strcmp(style, RESTORE_SPOOL)) { if(restore_spool(asfd, confs, &datpath)) goto error; } else logp("Streaming restore direct\n"); logf("\n"); if(get_int(confs[OPT_SEND_CLIENT_CNTR]) && cntr_recv(asfd, confs)) goto error; if(!(sb=sbuf_alloc(protocol)) || (protocol==PROTO_2 && !(blk=blk_alloc()))) { log_and_send_oom(asfd, __func__); goto error; } while(1) { sbuf_free_content(sb); if(protocol==PROTO_1) sb->flags |= SBUF_CLIENT_RESTORE_HACK; switch(sbuf_fill_from_net(sb, asfd, blk, datpath, cntr)) { case 0: break; case 1: if(asfd->write_str(asfd, CMD_GEN, "restoreend ok")) goto error; goto end; // It was OK. default: case -1: goto error; } if(protocol==PROTO_2) { if(blk->data) { int wret=0; if(act==ACTION_VERIFY) cntr_add(cntr, CMD_DATA, 1); else wret=write_data(asfd, bfd, blk); if(!datpath) blk_free_content(blk); blk->data=NULL; if(wret) goto error; continue; } else if(sb->endfile.buf) { continue; } } switch(sb->path.cmd) { case CMD_DIRECTORY: case CMD_FILE: case CMD_ENC_FILE: case CMD_SOFT_LINK: case CMD_HARD_LINK: case CMD_SPECIAL: case CMD_METADATA: case CMD_ENC_METADATA: case CMD_VSS: case CMD_ENC_VSS: case CMD_VSS_T: case CMD_ENC_VSS_T: case CMD_EFS_FILE: if(strip) { int s; s=strip_path_components(asfd, sb, strip, cntr, protocol); if(s<0) goto error; if(s==0) { // Too many components stripped // - carry on. continue; } // It is OK, sb.path is now stripped. } free_w(&fullpath); if(!(fullpath=prepend_s(restore_prefix, sb->path.buf))) { log_and_send_oom(asfd, __func__); goto error; } if(act==ACTION_RESTORE) { strip_invalid_characters(&fullpath); if(!overwrite_ok(sb, overwrite, #ifdef HAVE_WIN32 bfd, #endif fullpath)) { char msg[512]=""; // Something exists at that path. snprintf(msg, sizeof(msg), "Path exists: %s\n", fullpath); if(restore_interrupt(asfd, sb, msg, cntr, protocol)) goto error; continue; } } break; case CMD_MESSAGE: case CMD_WARNING: log_recvd(&sb->path, cntr, 1); logf("\n"); continue; default: break; } switch(sb->path.cmd) { // These are the same in both protocol1 and protocol2. case CMD_DIRECTORY: if(restore_dir(asfd, sb, fullpath, act, cntr, protocol)) goto error; continue; case CMD_SOFT_LINK: case CMD_HARD_LINK: if(restore_link(asfd, sb, fullpath, act, cntr, protocol, restore_prefix)) goto error; continue; case CMD_SPECIAL: if(restore_special(asfd, sb, fullpath, act, cntr, protocol)) goto error; continue; default: break; } if(protocol==PROTO_2) { if(restore_switch_protocol2(asfd, sb, fullpath, act, bfd, vss_restore, cntr)) goto error; } else { if(restore_switch_protocol1(asfd, sb, fullpath, act, bfd, vss_restore, cntr, encryption_password)) goto error; } } end: ret=0; error: // It is possible for a fd to still be open. bfd->close(bfd, asfd); bfile_free(&bfd); cntr_print_end(cntr); cntr_print(cntr, act); if(!ret) logp("%s finished\n", act_str(act)); else logp("ret: %d\n", ret); sbuf_free(&sb); free_w(&style); if(datpath) { recursive_delete(datpath); free_w(&datpath); } free_w(&fullpath); blk_free(&blk); return ret; }
static int do_restore_file_or_get_meta(struct asfd *asfd, BFILE *bfd, struct sbuf *sb, const char *fname, char **metadata, size_t *metalen, struct cntr *cntr, const char *rpath, const char *encryption_password) { int ret=-1; int enccompressed=0; uint64_t rcvdbytes=0; uint64_t sentbytes=0; const char *encpassword=NULL; if(sbuf_is_encrypted(sb)) encpassword=encryption_password; enccompressed=dpth_protocol1_is_compressed(sb->compression, sb->protocol1->datapth.buf); /* printf("%s \n", fname); if(encpassword && !enccompressed) printf("encrypted and not compressed\n"); else if(!encpassword && enccompressed) printf("not encrypted and compressed\n"); else if(!encpassword && !enccompressed) printf("not encrypted and not compressed\n"); else if(encpassword && enccompressed) printf("encrypted and compressed\n"); */ if(metadata) { ret=transfer_gzfile_inl(asfd, sb, fname, NULL, &rcvdbytes, &sentbytes, encpassword, enccompressed, cntr, metadata); *metalen=sentbytes; // skip setting cntr, as we do not actually // restore until a bit later goto end; } else { ret=transfer_gzfile_inl(asfd, sb, fname, bfd, &rcvdbytes, &sentbytes, encpassword, enccompressed, cntr, NULL); #ifndef HAVE_WIN32 if(bfd && bfd->close(bfd, asfd)) { logp("error closing %s in %s\n", fname, __func__); goto end; } #endif if(!ret) attribs_set(asfd, rpath, &sb->statp, sb->winattr, cntr); } ret=0; end: if(ret) { char msg[256]=""; snprintf(msg, sizeof(msg), "Could not transfer file in: %s", rpath); if(restore_interrupt(asfd, sb, msg, cntr, PROTO_1)) ret=-1; } return ret; }
void timer_stop(void) { int oldstatus = disable_interrupt_save(IRQ_FIQ_STATUS); stop_timer(); restore_interrupt(oldstatus); }
// FIX THIS: Maybe should be in bfile.c. enum ofr_e open_for_restore(struct asfd *asfd, BFILE *bfd, const char *path, struct sbuf *sb, int vss_restore, struct cntr *cntr, enum protocol protocol) { static int flags; if(bfd->mode!=BF_CLOSED) { #ifdef HAVE_WIN32 if(bfd->path && !strcmp(bfd->path, path)) { // Already open after restoring the VSS data. // Time now for the actual file data. return OFR_OK; } else { #endif if(bfd->close(bfd, asfd)) { logp("error closing %s in %s()\n", path, __func__); return OFR_ERROR; } #ifdef HAVE_WIN32 } #endif } #ifdef HAVE_WIN32 // Some massive hacks to work around times that winattr was not // getting set correctly inside server side backups. // The EFS one will stop burp segfaulting when restoring affected // EFS files. if(sb->path.cmd==CMD_EFS_FILE) sb->winattr |= FILE_ATTRIBUTE_ENCRYPTED; if(S_ISDIR(sb->statp.st_mode)) sb->winattr |= FILE_ATTRIBUTE_DIRECTORY; #endif bfile_init(bfd, sb->winattr, cntr); #ifdef HAVE_WIN32 bfd->set_win32_api(bfd, vss_restore); #endif if(S_ISDIR(sb->statp.st_mode)) { // Windows directories are treated as having file data. flags=O_WRONLY|O_BINARY; mkdir(path, 0777); } else flags=O_WRONLY|O_BINARY|O_CREAT|O_TRUNC; if(bfd->open(bfd, asfd, path, flags, S_IRUSR | S_IWUSR)) { berrno be; berrno_init(&be); char msg[256]=""; snprintf(msg, sizeof(msg), "Could not open for writing %s: %s", path, berrno_bstrerror(&be, errno)); if(restore_interrupt(asfd, sb, msg, cntr, protocol)) return OFR_ERROR; return OFR_CONTINUE; } // Add attributes to bfd so that they can be set when it is closed. bfd->winattr=sb->winattr; memcpy(&bfd->statp, &sb->statp, sizeof(struct stat)); return OFR_OK; }
int do_restore_client_burp1(struct asfd *asfd, struct conf *conf, enum action act, int vss_restore) { int ars=0; int ret=-1; char msg[512]=""; struct sbuf *sb=NULL; // Windows needs to have the VSS data written first, and the actual data // written immediately afterwards. The server is transferring them in two // chunks. So, leave bfd open after a Windows metadata transfer. BFILE bfd; #ifdef HAVE_WIN32 binit(&bfd, 0, conf); #endif logp("doing %s\n", act_str(act)); snprintf(msg, sizeof(msg), "%s %s:%s", act_str(act), conf->backup?conf->backup:"", conf->regex?conf->regex:""); if(asfd->write_str(asfd, CMD_GEN, msg) || asfd->read_expect(asfd, CMD_GEN, "ok")) return -1; logp("doing %s confirmed\n", act_str(act)); if(conf->send_client_cntr) { // FIX THIS // if(cntr_recv(conf)) goto end; } #if defined(HAVE_WIN32) if(act==ACTION_RESTORE) win32_enable_backup_privileges(); #endif if(!(sb=sbuf_alloc(conf))) goto end; while(1) { char *fullpath=NULL; sbuf_free_content(sb); if((ars=sbufl_fill(sb, asfd, NULL, NULL, conf->cntr))) { if(ars<0) goto end; else { // ars==1 means it ended ok. //logp("got %s end\n", act_str(act)); if(asfd->write_str(asfd, CMD_GEN, "restoreend ok")) goto end; } break; } switch(sb->path.cmd) { case CMD_DIRECTORY: case CMD_FILE: case CMD_ENC_FILE: case CMD_SOFT_LINK: case CMD_HARD_LINK: case CMD_SPECIAL: case CMD_METADATA: case CMD_ENC_METADATA: case CMD_VSS: case CMD_ENC_VSS: case CMD_VSS_T: case CMD_ENC_VSS_T: case CMD_EFS_FILE: if(conf->strip) { int s; s=strip_path_components(asfd, sb, &(sb->path.buf), conf); if(s<0) goto end; // error else if(s==0) { // Too many components stripped // - carry on. continue; } // It is OK, sb->path is now stripped. } if(!(fullpath=prepend_s(conf->restoreprefix, sb->path.buf))) { log_and_send_oom(asfd, __func__); goto end; } if(act==ACTION_RESTORE) { strip_invalid_characters(&fullpath); if(!overwrite_ok(sb, conf, &bfd, fullpath)) { char msg[512]=""; // Something exists at that path. snprintf(msg, sizeof(msg), "Path exists: %s", fullpath); if(restore_interrupt(asfd, sb, msg, conf)) goto end; else { if(fullpath) free(fullpath); continue; } } } break; default: break; } switch(sb->path.cmd) { case CMD_WARNING: cntr_add(conf->cntr, sb->path.cmd, 1); printf("\n"); logp("%s", sb->path); break; case CMD_DIRECTORY: if(restore_dir(asfd, sb, fullpath, act, conf)) goto end; break; case CMD_FILE: case CMD_VSS_T: // Have it a separate statement to the // encrypted version so that encrypted and not // encrypted files can be restored at the // same time. if(restore_file_or_get_meta(asfd, &bfd, sb, fullpath, act, NULL, NULL, NULL, vss_restore, conf)) { logp("restore_file error\n"); goto end; } break; case CMD_ENC_FILE: case CMD_ENC_VSS_T: if(restore_file_or_get_meta(asfd, &bfd, sb, fullpath, act, conf->encryption_password, NULL, NULL, vss_restore, conf)) { logp("restore_file error\n"); goto end; } break; case CMD_SOFT_LINK: case CMD_HARD_LINK: if(restore_link(asfd, sb, fullpath, conf->restoreprefix, act, conf)) goto end; break; case CMD_SPECIAL: if(restore_special(asfd, sb, fullpath, act, conf)) goto end; break; case CMD_METADATA: case CMD_VSS: if(restore_metadata(asfd, &bfd, sb, fullpath, act, NULL, vss_restore, conf)) goto end; break; case CMD_ENC_METADATA: case CMD_ENC_VSS: if(restore_metadata(asfd, &bfd, sb, fullpath, act, conf->encryption_password, vss_restore, conf)) goto end; break; case CMD_EFS_FILE: if(restore_file_or_get_meta(asfd, &bfd, sb, fullpath, act, NULL, NULL, NULL, vss_restore, conf)) { logp("restore_file error\n"); goto end; } break; default: logp("unknown cmd: %c\n", sb->path.cmd); goto end; break; } if(fullpath) free(fullpath); } ret=0; end: sbuf_free(sb); #ifdef HAVE_WIN32 // It is possible for a bfd to still be open. bclose(&bfd, asfd); #endif cntr_print_end(conf->cntr); cntr_print(conf->cntr, act); if(!ret) logp("%s finished\n", act_str(act)); else logp("ret: %d\n", ret); return ret; }
static int restore_special(struct asfd *asfd, struct sbuf *sb, const char *fname, enum action act, struct cntr *cntr, enum protocol protocol) { int ret=0; char *rpath=NULL; #ifdef HAVE_WIN32 logw(asfd, cntr, "Cannot restore special files to Windows: %s\n", fname); goto end; #else struct stat statp=sb->statp; if(act==ACTION_VERIFY) { cntr_add(cntr, CMD_SPECIAL, 1); return 0; } if(build_path(fname, "", &rpath, NULL)) { // failed - do a warning if(restore_interrupt(asfd, sb, build_msg("build path failed: %s", fname), cntr, protocol)) ret=-1; goto end; } if(S_ISFIFO(statp.st_mode)) { if(mkfifo(rpath, statp.st_mode) && errno!=EEXIST) do_logw(asfd, cntr, "Cannot make fifo: %s\n", strerror(errno)); else { attribs_set(asfd, rpath, &statp, sb->winattr, cntr); cntr_add(cntr, CMD_SPECIAL, 1); } } else if(S_ISSOCK(statp.st_mode)) { if(mksock(rpath)) do_logw(asfd, cntr, "Cannot make socket: %s\n", strerror(errno)); else { attribs_set(asfd, rpath, &statp, sb->winattr, cntr); cntr_add(cntr, CMD_SPECIAL, 1); } } #ifdef S_IFDOOR // Solaris high speed RPC mechanism else if (S_ISDOOR(statp.st_mode)) do_logw(asfd, cntr, "Skipping restore of door file: %s\n", fname); #endif #ifdef S_IFPORT // Solaris event port for handling AIO else if (S_ISPORT(statp.st_mode)) do_logw(asfd, cntr, "Skipping restore of event port file: %s\n", fname); #endif else if(mknod(fname, statp.st_mode, statp.st_rdev) && errno!=EEXIST) do_logw(asfd, cntr, "Cannot make node: %s\n", strerror(errno)); else { attribs_set(asfd, rpath, &statp, sb->winattr, cntr); cntr_add(cntr, CMD_SPECIAL, 1); } #endif end: free_w(&rpath); return ret; }
static int restore_file_or_get_meta(struct asfd *asfd, BFILE *bfd, struct sbuf *sb, const char *fname, enum action act, const char *encpassword, char **metadata, size_t *metalen, int vss_restore, struct conf *conf) { int ret=0; char *rpath=NULL; FILE *fp=NULL; if(act==ACTION_VERIFY) { cntr_add(conf->cntr, sb->path.cmd, 1); return 0; } if(build_path(fname, "", &rpath, NULL)) { char msg[256]=""; // failed - do a warning snprintf(msg, sizeof(msg), "build path failed: %s", fname); if(restore_interrupt(asfd, sb, msg, conf)) ret=-1; goto end; } #ifndef HAVE_WIN32 // We always want to open the file if it is on Windows. Otherwise, // only open it if we are not doing metadata. if(!metadata) { #endif if(open_for_restore(asfd, bfd, &fp, rpath, sb, vss_restore, conf)) { ret=-1; goto end; } #ifndef HAVE_WIN32 } #endif if(!ret) { int enccompressed=0; unsigned long long rcvdbytes=0; unsigned long long sentbytes=0; enccompressed=dpthl_is_compressed(sb->compression, sb->burp1->datapth.buf); /* printf("%s \n", fname); if(encpassword && !enccompressed) printf("encrypted and not compressed\n"); else if(!encpassword && enccompressed) printf("not encrypted and compressed\n"); else if(!encpassword && !enccompressed) printf("not encrypted and not compressed\n"); else if(encpassword && enccompressed) printf("encrypted and compressed\n"); */ if(metadata) { ret=transfer_gzfile_inl(asfd, sb, fname, NULL, NULL, &rcvdbytes, &sentbytes, encpassword, enccompressed, conf->cntr, metadata); *metalen=sentbytes; // skip setting cntr, as we do not actually // restore until a bit later goto end; } else { int c=0; #ifdef HAVE_WIN32 ret=transfer_gzfile_inl(asfd, sb, fname, bfd, NULL, &rcvdbytes, &sentbytes, encpassword, enccompressed, conf->cntr, NULL); //c=bclose(bfd); #else ret=transfer_gzfile_inl(asfd, sb, fname, NULL, fp, &rcvdbytes, &sentbytes, encpassword, enccompressed, conf->cntr, NULL); c=close_fp(&fp); #endif if(c) { logp("error closing %s in restore_file_or_get_meta\n", fname); ret=-1; } if(!ret) attribs_set(asfd, rpath, &(sb->statp), sb->winattr, conf); } if(ret) { char msg[256]=""; snprintf(msg, sizeof(msg), "Could not transfer file in: %s", rpath); if(restore_interrupt(asfd, sb, msg, conf)) ret=-1; goto end; } } if(!ret) cntr_add(conf->cntr, sb->path.cmd, 1); end: if(rpath) free(rpath); return ret; }
static int restore_special(struct asfd *asfd, struct sbuf *sb, const char *fname, enum action act, struct conf *conf) { int ret=0; char *rpath=NULL; #ifdef HAVE_WIN32 logw(asfd, conf, "Cannot restore special files to Windows: %s\n", fname); goto end; #else struct stat statp=sb->statp; if(act==ACTION_VERIFY) { cntr_add(conf->cntr, CMD_SPECIAL, 1); return 0; } if(build_path(fname, "", &rpath, NULL)) { char msg[256]=""; // failed - do a warning snprintf(msg, sizeof(msg), "build path failed: %s", fname); if(restore_interrupt(asfd, sb, msg, conf)) ret=-1; goto end; } if(S_ISFIFO(statp.st_mode)) { if(mkfifo(rpath, statp.st_mode) && errno!=EEXIST) { char msg[256]=""; snprintf(msg, sizeof(msg), "Cannot make fifo: %s\n", strerror(errno)); logw(asfd, conf, "%s", msg); } else { attribs_set(asfd, rpath, &statp, sb->winattr, conf); cntr_add(conf->cntr, CMD_SPECIAL, 1); } /* } else if(S_ISSOCK(statp.st_mode)) { char msg[256]=""; snprintf(msg, sizeof(msg), "Skipping restore of socket: %s\n", fname); logw(conf, "%s", msg); */ #ifdef S_IFDOOR // Solaris high speed RPC mechanism } else if (S_ISDOOR(statp.st_mode)) { char msg[256]=""; snprintf(msg, sizeof(msg), "Skipping restore of door file: %s\n", fname); logw(conf, "%s", msg); #endif #ifdef S_IFPORT // Solaris event port for handling AIO } else if (S_ISPORT(statp.st_mode)) { char msg[256]=""; snprintf(msg, sizeof(msg), "Skipping restore of event port file: %s\n", fname); logw(conf, "%s", msg); #endif } else { if(mknod(fname, statp.st_mode, statp.st_rdev) && errno!=EEXIST) { char msg[256]=""; snprintf(msg, sizeof(msg), "Cannot make node: %s\n", strerror(errno)); logw(asfd, conf, "%s", msg); } else { attribs_set(asfd, rpath, &statp, sb->winattr, conf); cntr_add(conf->cntr, CMD_SPECIAL, 1); } } #endif end: if(rpath) free(rpath); return ret; }