int open_file_for_send(BFILE *bfd, FILE **fp, const char *fname, int64_t winattr, struct cntr *cntr) { if(fp) { if(!(*fp=fopen(fname, "rb"))) { logw(cntr, "Could not open %s: %s\n", fname, strerror(errno)); return -1; } } #ifdef HAVE_WIN32 else { binit(bfd, winattr); if(bopen(bfd, fname, O_RDONLY | O_BINARY | O_NOATIME, 0, (winattr & FILE_ATTRIBUTE_DIRECTORY))<=0) { berrno be; logw(cntr, "Could not open %s: %s\n", fname, be.bstrerror(errno)); return -1; } } #endif return 0; }
int main (int argc, char *argv[]) { char *dev_name = ".btree"; #if DEVELOPMENT debugon(); fdebugon(); #else debugoff(); fdebugoff(); #endif FN; if (argc > 1) { dev_name = argv[1]; } #if DEVELOPMENT unlink(dev); /* Development only */ #endif binit(20); Dev = bopen(dev_name); if (!Dev) eprintf("Couldn't open %s:", dev_name); blazy(Dev); init_string(Dev); init_shell(quit_callback); init_cmd(); return shell(); }
int main(int argc, char *argv[]) { int do_restore = argc > 1 && strcmp("-r", argv[1]) == 0; const char *mode = (do_restore) ? "r+" : "w+"; /* call perm() and open() before malloc() */ perm(PERM_START, PERM_SIZE); mopen(MMAP_FILE, mode, MMAP_SIZE); bopen(BACK_FILE, mode); if (do_restore) { restore(); } else { home = (home_st *)malloc(sizeof(home_st)); /* initialize home struct... */ mflush(); backup(); } for (;/* each step */;) { /* Application_Step(); */ backup(); } free(home); mclose(); bclose(); return(0); }
int main( int argc, char** argv ) { /* * Initialize the memory allocator. Allow use of malloc and start * with a 60K heap. For each page request approx 8KB is allocated. * 60KB allows for several concurrent page requests. If more space * is required, malloc will be used for the overflow. */ bopen( NULL, ( 60 * 1024 ), B_USE_MALLOC ); signal( SIGPIPE, SIG_IGN ); /* * Initialize the web server */ if ( initWebs() < 0 ) { return -1; } #ifdef WEBS_SSL_SUPPORT websSSLOpen(); #endif /* * Basic event loop. SocketReady returns true when a socket is ready for * service. SocketSelect will block until an event occurs. SocketProcess * will actually do the servicing. */ while ( !finished ) { if ( socketReady( -1 ) || socketSelect( -1, 1000 ) ) { socketProcess( -1 ); } websCgiCleanup(); emfSchedProcess(); } #ifdef WEBS_SSL_SUPPORT websSSLClose(); #endif #ifdef USER_MANAGEMENT_SUPPORT umClose(); #endif /* * Close the socket module, report memory leaks and close the memory allocator */ websCloseServer(); socketClose(); #ifdef B_STATS memLeaks(); #endif bclose(); return 0; }
static void rtems_httpd_daemon(rtems_task_argument args) { /* * Initialize the memory allocator. Allow use of malloc and start with a * 10K heap. */ bopen(NULL, (10 * 1024), B_USE_MALLOC); /* * Initialize the web server */ if (initWebs() < 0) { rtems_panic("Unable to initialize Web server !!\n"); } #ifdef WEBS_SSL_SUPPORT websSSLOpen(); #endif /* * Basic event loop. SocketReady returns true when a socket is ready for * service. SocketSelect will block until an event occurs. SocketProcess * will actually do the servicing. */ while (!finished) { if (socketReady(-1) || socketSelect(-1, 2000)) { socketProcess(-1); } /*websCgiCleanup();*/ emfSchedProcess(); } #ifdef WEBS_SSL_SUPPORT websSSLClose(); #endif #ifdef USER_MANAGEMENT_SUPPORT umClose(); #endif /* * Close the socket module, report memory leaks and close the memory allocator */ websCloseServer(); websDefaultClose(); socketClose(); symSubClose(); #if B_STATS memLeaks(); #endif bclose(); rtems_task_delete( RTEMS_SELF ); }
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; }
int main(int argc, char** argv) { /* * Hook the unload routine in */ signal( SIGTERM, SigTermSignalHandler ) ; /* * Initialize the memory allocator. Allow use of malloc and start * with a 60K heap. For each page request approx 8KB is allocated. * 60KB allows for several concurrent page requests. If more space * is required, malloc will be used for the overflow. */ bopen(NULL, (60 * 1024), B_USE_MALLOC); P( 1 ) ; /* * Switch to LONG name-space. If LONG is not loaded, WEBS will default * to 8.3 */ SetCurrentNameSpace( 4 ) ; /* * Initialize the web server */ if (initWebs() < 0) { return -1; } #ifdef WEBS_SSL_SUPPORT websSSLOpen(); #endif P( 20 ) ; /* * Basic event loop. SocketReady returns true when a socket is ready for * service. SocketSelect will block until an event occurs. SocketProcess * will actually do the servicing. */ while (!finished) { if (socketReady(-1) || socketSelect(-1, 1000)) { socketProcess(-1); ThreadSwitch() ; } websCgiCleanup(); emfSchedProcess(); } NLMcleanup() ; return 0; }
/* * Open the resource fork of a file. */ int bopen_rsrc(BFILE *bfd, const char *fname, int flags, mode_t mode) { POOLMEM *rsrc_fname; rsrc_fname = get_pool_memory(PM_FNAME); pm_strcpy(rsrc_fname, fname); pm_strcat(rsrc_fname, _PATH_RSRCFORKSPEC); bopen(bfd, rsrc_fname, flags, mode, 0); free_pool_memory(rsrc_fname); return bfd->fid; }
/* These receive_a_file() and send_file() functions are for use by extra_comms and the CA stuff, rather than backups/restores. */ int receive_a_file(const char *path, struct cntr *p1cntr) { int c=0; int ret=0; #ifdef HAVE_WIN32 BFILE bfd; #else FILE *fp=NULL; #endif unsigned long long rcvdbytes=0; unsigned long long sentbytes=0; #ifdef HAVE_WIN32 binit(&bfd, 0); bfd.use_backup_api=0; //set_win32_backup(&bfd); if(bopen(&bfd, path, O_WRONLY | O_CREAT | O_TRUNC | O_BINARY, S_IRUSR | S_IWUSR, 0)<=0) { berrno be; logp("Could not open for writing %s: %s\n", path, be.bstrerror(errno)); ret=-1; goto end; } #else if(!(fp=open_file(path, "wb"))) { ret=-1; goto end; } #endif #ifdef HAVE_WIN32 ret=transfer_gzfile_in(NULL, path, &bfd, NULL, &rcvdbytes, &sentbytes, NULL, 0, p1cntr, NULL); c=bclose(&bfd); #else ret=transfer_gzfile_in(NULL, path, NULL, fp, &rcvdbytes, &sentbytes, NULL, 0, p1cntr, NULL); c=close_fp(&fp); #endif end: if(c) { logp("error closing %s in receive_a_file\n", path); ret=-1; } if(!ret) logp("Received: %s\n", path); return ret; }
open_rgb_files() { int i; for (i=0; i<3; i++) { if (!bopen(rgb_names[i], rgb_files+i)) { cant_find(rgb_names[i]); close_rgb_files(); return(0); } } return(1); }
char * la_getdb (char *fn) /* char *fn ; data base file name */ { struct FAB f ; /* file access block */ struct RAB r ; /* record access block */ struct XABFHC x ; /* file header */ struct NAM n; /* added nam block to capture file id (js) */ int4 status ; int4 size ; int k ; char *h= NULL ; /* db in main store */ char *p ; /* current read buffer */ la_prolog *prol ; /* db file prolog */ n = cc$rms_nam; status= bopen(fn,&f,&r,&x,&n); if (status==SS$_NORMAL) { size= 512 * x.xab$l_ebk + PBUF ; if ((h= (char *)malloc(size))!=NULL) { p= h ; while (status==SS$_NORMAL && p<h+size) { status= bread(&r,p,BLKS) ; p += BLKS ; } if (status!=RMS$_EOF) { h= NULL ; } else { prol= h ; if (prol->id!=DBID) /* invalid file ID */ { h= NULL ; } } } bclose(&f) ; } else { h= NULL ; } return(h) ; }
int main (int argc, char *argv[]) { const char *const_str = "ThisStringIsUsedToTestWriteOfMetadata"; char *str; uint8_t size, type; struct bitio *bd; bd = bopen("metadata_test.dat", 'w'); if (bd == NULL) goto error; meta_write(bd, 1, (void*)const_str, strlen(const_str) + 1); meta_write(bd, 2, (void*)const_str, 2); meta_finalize(bd); bclose(bd); bd = bopen("metadata_test.dat", 'r'); if (bd == NULL) goto error; str = meta_read(bd, &type, &size); if (strcmp(str, const_str) != 0 || type != 1 || size != strlen(str) + 1) goto error; str = meta_read(bd, &type, &size); if (str[0] != const_str[0] || str[1] != const_str[1] || type != 2 || size != 2) goto error; bclose(bd); unlink("metadata_test.dat"); exit(EXIT_SUCCESS); error: bclose(bd); unlink("metadata_test.dat"); exit(EXIT_FAILURE); }
/* * Compute message digest for the file specified by ff_pkt. * In case of errors we need the job control record and file name. */ int digest_file(JCR *jcr, FF_PKT *ff_pkt, DIGEST *digest) { BFILE bfd; Dmsg0(50, "=== digest_file\n"); binit(&bfd); if (ff_pkt->statp.st_size > 0 || ff_pkt->type == FT_RAW || ff_pkt->type == FT_FIFO) { int noatime = ff_pkt->flags & FO_NOATIME ? O_NOATIME : 0; if ((bopen(&bfd, ff_pkt->fname, O_RDONLY | O_BINARY | noatime, 0, ff_pkt->statp.st_rdev)) < 0) { ff_pkt->ff_errno = errno; berrno be; be.set_errno(bfd.berrno); Dmsg2(100, "Cannot open %s: ERR=%s\n", ff_pkt->fname, be.bstrerror()); Jmsg(jcr, M_ERROR, 1, _(" Cannot open %s: ERR=%s.\n"), ff_pkt->fname, be.bstrerror()); return 1; } read_digest(&bfd, digest, jcr); bclose(&bfd); } if (have_darwin_os) { /* * Open resource fork if necessary */ if (ff_pkt->flags & FO_HFSPLUS && ff_pkt->hfsinfo.rsrclength > 0) { if (bopen_rsrc(&bfd, ff_pkt->fname, O_RDONLY | O_BINARY, 0) < 0) { ff_pkt->ff_errno = errno; berrno be; Jmsg(jcr, M_ERROR, -1, _(" Cannot open resource fork for %s: ERR=%s.\n"), ff_pkt->fname, be.bstrerror()); if (is_bopen(&ff_pkt->bfd)) { bclose(&ff_pkt->bfd); } return 1; } read_digest(&bfd, digest, jcr); bclose(&bfd); } if (digest && ff_pkt->flags & FO_HFSPLUS) { crypto_digest_update(digest, (uint8_t *)ff_pkt->hfsinfo.fndrinfo, 32); } } return 0; }
int main(int argc, char** argv) { /* * Initialize the memory allocator. Allow use of malloc and start * with a 60K heap. For each page request approx 8KB is allocated. * 60KB allows for several concurrent page requests. If more space * is required, malloc will be used for the overflow. */ bopen(NULL, (60 * 1024), B_USE_MALLOC); /* * Initialize the web server */ if (initWebs() < 0) { return -1; } /* * Basic event loop. SocketReady returns true when a socket is ready for * service. SocketSelect will block until an event occurs. SocketProcess * will actually do the servicing. */ while (!finished) { if (socketReady(-1) || socketSelect(-1, 2000)) { socketProcess(-1); } emfSchedProcess(); } /* * Close the socket module, report memory leaks and close the memory allocator */ websCloseServer(); socketClose(); bclose(); return 0; }
/** * Called here by find() for each file included. * This is a callback. The original is find_files() above. * * Send the file and its data to the Storage daemon. * * Returns: 1 if OK * 0 if error * -1 to ignore file/directory (not used here) */ int save_file(JCR *jcr, FF_PKT *ff_pkt, bool top_level) { bool do_read = false; bool plugin_started = false; bool do_plugin_set = false; int status, data_stream; int rtnstat = 0; b_save_ctx bsctx; bool has_file_data = false; struct save_pkt sp; /* use by option plugin */ BSOCK *sd = jcr->store_bsock; if (jcr->is_canceled() || jcr->is_incomplete()) { return 0; } jcr->num_files_examined++; /* bump total file count */ switch (ff_pkt->type) { case FT_LNKSAVED: /* Hard linked, file already saved */ Dmsg2(130, "FT_LNKSAVED hard link: %s => %s\n", ff_pkt->fname, ff_pkt->link); break; case FT_REGE: Dmsg1(130, "FT_REGE saving: %s\n", ff_pkt->fname); has_file_data = true; break; case FT_REG: Dmsg1(130, "FT_REG saving: %s\n", ff_pkt->fname); has_file_data = true; break; case FT_LNK: Dmsg2(130, "FT_LNK saving: %s -> %s\n", ff_pkt->fname, ff_pkt->link); break; case FT_RESTORE_FIRST: Dmsg1(100, "FT_RESTORE_FIRST saving: %s\n", ff_pkt->fname); break; case FT_PLUGIN_CONFIG: Dmsg1(100, "FT_PLUGIN_CONFIG saving: %s\n", ff_pkt->fname); break; case FT_DIRBEGIN: jcr->num_files_examined--; /* correct file count */ return 1; /* not used */ case FT_NORECURSE: Jmsg(jcr, M_INFO, 1, _(" Recursion turned off. Will not descend from %s into %s\n"), ff_pkt->top_fname, ff_pkt->fname); ff_pkt->type = FT_DIREND; /* Backup only the directory entry */ break; case FT_NOFSCHG: /* Suppress message for /dev filesystems */ if (!is_in_fileset(ff_pkt)) { Jmsg(jcr, M_INFO, 1, _(" %s is a different filesystem. Will not descend from %s into it.\n"), ff_pkt->fname, ff_pkt->top_fname); } ff_pkt->type = FT_DIREND; /* Backup only the directory entry */ break; case FT_INVALIDFS: Jmsg(jcr, M_INFO, 1, _(" Disallowed filesystem. Will not descend from %s into %s\n"), ff_pkt->top_fname, ff_pkt->fname); ff_pkt->type = FT_DIREND; /* Backup only the directory entry */ break; case FT_INVALIDDT: Jmsg(jcr, M_INFO, 1, _(" Disallowed drive type. Will not descend into %s\n"), ff_pkt->fname); break; case FT_REPARSE: case FT_JUNCTION: case FT_DIREND: Dmsg1(130, "FT_DIREND: %s\n", ff_pkt->link); break; case FT_SPEC: Dmsg1(130, "FT_SPEC saving: %s\n", ff_pkt->fname); if (S_ISSOCK(ff_pkt->statp.st_mode)) { Jmsg(jcr, M_SKIPPED, 1, _(" Socket file skipped: %s\n"), ff_pkt->fname); return 1; } break; case FT_RAW: Dmsg1(130, "FT_RAW saving: %s\n", ff_pkt->fname); has_file_data = true; break; case FT_FIFO: Dmsg1(130, "FT_FIFO saving: %s\n", ff_pkt->fname); break; case FT_NOACCESS: { berrno be; Jmsg(jcr, M_NOTSAVED, 0, _(" Could not access \"%s\": ERR=%s\n"), ff_pkt->fname, be.bstrerror(ff_pkt->ff_errno)); jcr->JobErrors++; return 1; } case FT_NOFOLLOW: { berrno be; Jmsg(jcr, M_NOTSAVED, 0, _(" Could not follow link \"%s\": ERR=%s\n"), ff_pkt->fname, be.bstrerror(ff_pkt->ff_errno)); jcr->JobErrors++; return 1; } case FT_NOSTAT: { berrno be; Jmsg(jcr, M_NOTSAVED, 0, _(" Could not stat \"%s\": ERR=%s\n"), ff_pkt->fname, be.bstrerror(ff_pkt->ff_errno)); jcr->JobErrors++; return 1; } case FT_DIRNOCHG: case FT_NOCHG: Jmsg(jcr, M_SKIPPED, 1, _(" Unchanged file skipped: %s\n"), ff_pkt->fname); return 1; case FT_ISARCH: Jmsg(jcr, M_NOTSAVED, 0, _(" Archive file not saved: %s\n"), ff_pkt->fname); return 1; case FT_NOOPEN: { berrno be; Jmsg(jcr, M_NOTSAVED, 0, _(" Could not open directory \"%s\": ERR=%s\n"), ff_pkt->fname, be.bstrerror(ff_pkt->ff_errno)); jcr->JobErrors++; return 1; } case FT_DELETED: Dmsg1(130, "FT_DELETED: %s\n", ff_pkt->fname); break; default: Jmsg(jcr, M_NOTSAVED, 0, _(" Unknown file type %d; not saved: %s\n"), ff_pkt->type, ff_pkt->fname); jcr->JobErrors++; return 1; } Dmsg1(130, "filed: sending %s to stored\n", ff_pkt->fname); /* * Setup backup signing context. */ memset(&bsctx, 0, sizeof(b_save_ctx)); bsctx.digest_stream = STREAM_NONE; bsctx.jcr = jcr; bsctx.ff_pkt = ff_pkt; /* * Digests and encryption are only useful if there's file data */ if (has_file_data) { if (!setup_encryption_digests(bsctx)) { goto good_rtn; } } /* * Initialize the file descriptor we use for data and other streams. */ binit(&ff_pkt->bfd); if (bit_is_set(FO_PORTABLE, ff_pkt->flags)) { set_portable_backup(&ff_pkt->bfd); /* disable Win32 BackupRead() */ } /* * Option and cmd plugin are not compatible together */ if (ff_pkt->cmd_plugin) { do_plugin_set = true; } else if (ff_pkt->opt_plugin) { /* * Ask the option plugin what to do with this file */ switch (plugin_option_handle_file(jcr, ff_pkt, &sp)) { case bRC_OK: Dmsg2(10, "Option plugin %s will be used to backup %s\n", ff_pkt->plugin, ff_pkt->fname); jcr->opt_plugin = true; jcr->plugin_sp = &sp; plugin_update_ff_pkt(ff_pkt, &sp); do_plugin_set = true; break; case bRC_Skip: Dmsg2(10, "Option plugin %s decided to skip %s\n", ff_pkt->plugin, ff_pkt->fname); goto good_rtn; case bRC_Core: Dmsg2(10, "Option plugin %s decided to let bareos handle %s\n", ff_pkt->plugin, ff_pkt->fname); break; default: goto bail_out; } } if (do_plugin_set) { /* * Tell bfile that it needs to call plugin */ if (!set_cmd_plugin(&ff_pkt->bfd, jcr)) { goto bail_out; } send_plugin_name(jcr, sd, true); /* signal start of plugin data */ plugin_started = true; } /* * Send attributes -- must be done after binit() */ if (!encode_and_send_attributes(jcr, ff_pkt, data_stream)) { goto bail_out; } /* * Meta data only for restore object */ if (IS_FT_OBJECT(ff_pkt->type)) { goto good_rtn; } /* * Meta data only for deleted files */ if (ff_pkt->type == FT_DELETED) { goto good_rtn; } /* * Set up the encryption context and send the session data to the SD */ if (has_file_data && jcr->crypto.pki_encrypt) { if (!crypto_session_send(jcr, sd)) { goto bail_out; } } /* * For a command plugin use the setting from the plugins savepkt no_read field * which is saved in the ff_pkt->no_read variable. do_read is the inverted * value of this variable as no_read == TRUE means do_read == FALSE */ if (ff_pkt->cmd_plugin) { do_read = !ff_pkt->no_read; } else { /* * Open any file with data that we intend to save, then save it. * * Note, if is_win32_backup, we must open the Directory so that * the BackupRead will save its permissions and ownership streams. */ if (ff_pkt->type != FT_LNKSAVED && S_ISREG(ff_pkt->statp.st_mode)) { #ifdef HAVE_WIN32 do_read = !is_portable_backup(&ff_pkt->bfd) || ff_pkt->statp.st_size > 0; #else do_read = ff_pkt->statp.st_size > 0; #endif } else if (ff_pkt->type == FT_RAW || ff_pkt->type == FT_FIFO || ff_pkt->type == FT_REPARSE || ff_pkt->type == FT_JUNCTION || (!is_portable_backup(&ff_pkt->bfd) && ff_pkt->type == FT_DIREND)) { do_read = true; } } Dmsg2(150, "type=%d do_read=%d\n", ff_pkt->type, do_read); if (do_read) { btimer_t *tid; int noatime; if (ff_pkt->type == FT_FIFO) { tid = start_thread_timer(jcr, pthread_self(), 60); } else { tid = NULL; } noatime = bit_is_set(FO_NOATIME, ff_pkt->flags) ? O_NOATIME : 0; ff_pkt->bfd.reparse_point = (ff_pkt->type == FT_REPARSE || ff_pkt->type == FT_JUNCTION); if (bopen(&ff_pkt->bfd, ff_pkt->fname, O_RDONLY | O_BINARY | noatime, 0, ff_pkt->statp.st_rdev) < 0) { ff_pkt->ff_errno = errno; berrno be; Jmsg(jcr, M_NOTSAVED, 0, _(" Cannot open \"%s\": ERR=%s.\n"), ff_pkt->fname, be.bstrerror()); jcr->JobErrors++; if (tid) { stop_thread_timer(tid); tid = NULL; } goto good_rtn; } if (tid) { stop_thread_timer(tid); tid = NULL; } status = send_data(jcr, data_stream, ff_pkt, bsctx.digest, bsctx.signing_digest); if (bit_is_set(FO_CHKCHANGES, ff_pkt->flags)) { has_file_changed(jcr, ff_pkt); } bclose(&ff_pkt->bfd); if (!status) { goto bail_out; } } if (have_darwin_os) { /* * Regular files can have resource forks and Finder Info */ if (ff_pkt->type != FT_LNKSAVED && (S_ISREG(ff_pkt->statp.st_mode) && bit_is_set(FO_HFSPLUS, ff_pkt->flags))) { if (!save_rsrc_and_finder(bsctx)) { goto bail_out; } } } /* * Save ACLs when requested and available for anything not being a symlink. */ if (have_acl) { if (bit_is_set(FO_ACL, ff_pkt->flags) && ff_pkt->type != FT_LNK) { if (!do_backup_acl(jcr, ff_pkt)) { goto bail_out; } } } /* * Save Extended Attributes when requested and available for all files. */ if (have_xattr) { if (bit_is_set(FO_XATTR, ff_pkt->flags)) { if (!do_backup_xattr(jcr, ff_pkt)) { goto bail_out; } } } /* * Terminate the signing digest and send it to the Storage daemon */ if (bsctx.signing_digest) { if (!terminate_signing_digest(bsctx)) { goto bail_out; } } /* * Terminate any digest and send it to Storage daemon */ if (bsctx.digest) { if (!terminate_digest(bsctx)) { goto bail_out; } } /* * Check if original file has a digest, and send it */ if (ff_pkt->type == FT_LNKSAVED && ff_pkt->digest) { Dmsg2(300, "Link %s digest %d\n", ff_pkt->fname, ff_pkt->digest_len); sd->fsend("%ld %d 0", jcr->JobFiles, ff_pkt->digest_stream); sd->msg = check_pool_memory_size(sd->msg, ff_pkt->digest_len); memcpy(sd->msg, ff_pkt->digest, ff_pkt->digest_len); sd->msglen = ff_pkt->digest_len; sd->send(); sd->signal(BNET_EOD); /* end of hardlink record */ } good_rtn: rtnstat = jcr->is_canceled() ? 0 : 1; /* good return if not canceled */ bail_out: if (jcr->is_incomplete() || jcr->is_canceled()) { rtnstat = 0; } if (plugin_started) { send_plugin_name(jcr, sd, false); /* signal end of plugin data */ } if (ff_pkt->opt_plugin) { jcr->plugin_sp = NULL; /* sp is local to this function */ jcr->opt_plugin = false; } if (bsctx.digest) { crypto_digest_free(bsctx.digest); } if (bsctx.signing_digest) { crypto_digest_free(bsctx.signing_digest); } return rtnstat; }
/** * Set Extended File Attributes for Win32 * * fname is the original filename * ofile is the output filename (may be in a different directory) * * Returns: true on success * false on failure */ static bool set_win32_attributes(JCR *jcr, ATTR *attr, BFILE *ofd) { char *p = attr->attrEx; int64_t val; WIN32_FILE_ATTRIBUTE_DATA atts; ULARGE_INTEGER li; POOLMEM *win32_ofile; /** if we have neither Win ansi nor wchar API, get out */ if (!(p_SetFileAttributesW || p_SetFileAttributesA)) { return false; } if (!p || !*p) { /* we should have attributes */ Dmsg2(100, "Attributes missing. of=%s ofd=%d\n", attr->ofname, ofd->fid); if (is_bopen(ofd)) { bclose(ofd); } return false; } else { Dmsg2(100, "Attribs %s = %s\n", attr->ofname, attr->attrEx); } p += from_base64(&val, p); plug(atts.dwFileAttributes, val); p++; /* skip space */ p += from_base64(&val, p); li.QuadPart = val; atts.ftCreationTime.dwLowDateTime = li.LowPart; atts.ftCreationTime.dwHighDateTime = li.HighPart; p++; /* skip space */ p += from_base64(&val, p); li.QuadPart = val; atts.ftLastAccessTime.dwLowDateTime = li.LowPart; atts.ftLastAccessTime.dwHighDateTime = li.HighPart; p++; /* skip space */ p += from_base64(&val, p); li.QuadPart = val; atts.ftLastWriteTime.dwLowDateTime = li.LowPart; atts.ftLastWriteTime.dwHighDateTime = li.HighPart; p++; p += from_base64(&val, p); plug(atts.nFileSizeHigh, val); p++; p += from_base64(&val, p); plug(atts.nFileSizeLow, val); /** Convert to Windows path format */ win32_ofile = get_pool_memory(PM_FNAME); unix_name_to_win32(&win32_ofile, attr->ofname); /** At this point, we have reconstructed the WIN32_FILE_ATTRIBUTE_DATA pkt */ if (!is_bopen(ofd)) { Dmsg1(100, "File not open: %s\n", attr->ofname); bopen(ofd, attr->ofname, O_WRONLY|O_BINARY, 0); /* attempt to open the file */ } if (is_bopen(ofd)) { Dmsg1(100, "SetFileTime %s\n", attr->ofname); if (!SetFileTime(bget_handle(ofd), &atts.ftCreationTime, &atts.ftLastAccessTime, &atts.ftLastWriteTime)) { win_error(jcr, "SetFileTime:", win32_ofile); } bclose(ofd); } Dmsg1(100, "SetFileAtts %s\n", attr->ofname); if (!(atts.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)) { if (p_SetFileAttributesW) { POOLMEM* pwszBuf = get_pool_memory(PM_FNAME); make_win32_path_UTF8_2_wchar(&pwszBuf, attr->ofname); BOOL b=p_SetFileAttributesW((LPCWSTR)pwszBuf, atts.dwFileAttributes & SET_ATTRS); free_pool_memory(pwszBuf); if (!b) win_error(jcr, "SetFileAttributesW:", win32_ofile); } else { if (!p_SetFileAttributesA(win32_ofile, atts.dwFileAttributes & SET_ATTRS)) { win_error(jcr, "SetFileAttributesA:", win32_ofile); } } } free_pool_memory(win32_ofile); return true; }
int main (int argc, char *argv[]) { int my_rank, proc_num; MPI_Status status; MPI_Init(&argc, &argv); MPI_Comm_size(MPI_COMM_WORLD, &proc_num); MPI_Comm_rank(MPI_COMM_WORLD, &my_rank); double diff; /* change in value */ int i, j, m, n; int N=DEFAULT_N; double epsilon=0.01; double mean; FILE *fp; /* Argument processing */ int edgeElems = DEFAULT_ELEM; /* edge elements */ int cfreq = DEFAULT_FREQ; /* checkpoint frequency */ char *cpath = DEFAULT_PATH; /* checkpoint path */ int nok = 0; /* arguments not OK */ int pinit=1; char *s; while (--argc > 0 && (*++argv)[0] == '-') { for(s=argv[0]+1;*s;s++) switch (*s) { case 'd': if (isdigit(s[1])) edgeElems = atoi(s+1); else nok = 1; s+=strlen(s+1); break; case 'c': if (isdigit(s[i])) cfreq = atoi(s+1); else nok = 1; s+=strlen(s+1); break; case 'p': cpath = s+1; s+=strlen(s+1); break; case 'r': pinit = 0; break; case 'n': if (isdigit(s[1])) N = atoi(s+1); else nok = 1; s+=strlen(s+1); break; case 'e': if (isdigit(s[1])) epsilon = atof(s+1); else nok = 1; s+=strlen(s+1); break; default: nok = 1; break; } } if (nok) { fprintf(stderr, "Usage: %s -e<int> -c<int> -p<str> -r -n<int> -epsilon<double>\n", argv[0]); fprintf(stderr, " -d edge elements, default: %d\n", DEFAULT_ELEM); fprintf(stderr, " -c checkpoint frequency, default: %d\n", DEFAULT_FREQ); fprintf(stderr, " -p path to checkpoint file, default: %s\n", DEFAULT_PATH); fprintf(stderr, " -r restore\n"); fprintf(stderr, " -n size of n, default:1000\n"); fprintf(stderr, " -e epsilon, default:0.01\n"); exit(EXIT_FAILURE); } #ifdef DEBUG if(my_rank==0) printf("n=%d, epsilon=%lf\n", N, epsilon); #endif if(N>1000){ printf("Too big value for N, use no more than 1000, or change DEFAULT_N\n"); return 0; } // Persistent memory initialization const char *mode = (pinit) ? "w+" : "r+"; char back_fname[128]; char my_rank_str[4]; perm(PERM_START, PERM_SIZE); strcpy(back_fname, cpath); strcat(back_fname,"hw5_mpi.back."); sprintf(my_rank_str, "%d", my_rank); strcat(back_fname,my_rank_str); // printf("mopen: %s\n", back_fname); mopen(back_fname, mode, MMAP_SIZE); strcpy(back_fname, cpath); strcat(back_fname,"hw5_mpi.mmap."); strcat(back_fname,my_rank_str); // printf("bopen: %s\n", back_fname); bopen(back_fname, mode); if (!pinit){ restore(); printf("Resotored, iter=%d, myN=%d\n", iter, myN); } else{ iter = 0; /* Set boundary values and compute mean boundary value */ mean = 0.0; for (i=0; i<N; i++) { u[i][0] = u[i][N-1] = u[0][i] = 100.0; u[N-1][i] = 0.0; mean += u[i][0] + u[i][N-1] + u[0][i] + u[N-1][i]; } mean /= (4.0 *N); /* Initialize interior values */ for (i =1; i<N-1; i++) for (j=1; j<N-1; j++) u[i][j] = mean; // distribute data myN = N / proc_num; if(N%proc_num!=0){ if(my_rank==proc_num-1) myN=N-(proc_num-1)*myN; } if(proc_num > 1) { // ghost rows if(my_rank == 0 || my_rank == proc_num - 1) myN++; else myN += 2; } // initial value for(i = 0; i < myN; i++) { for(j = 0; j < N; j++) { if(my_rank == 0) myu[i][j] = u[i][j]; else myu[i][j] = u[my_rank*(N/proc_num)-1+i][j]; myw[i][j]=myu[i][j]; } } mflush(); backup(); } struct timeval start_tv, end_tv; gettimeofday(&start_tv, NULL); double alldiff=0; int left = my_rank - 1; int right = my_rank +1; MPI_Request send_req1, recv_req1; MPI_Request send_req2, recv_req2; while(1) { iter++; diff = 0.0; for (i=1; i<myN-1; i++) { for (j=1; j<N-1; j++) { myw[i][j] = (myu[i-1][j] + myu[i+1][j] + myu[i][j-1] + myu[i][j+1])/4.0; if (fabs (myw[i][j] - myu[i][j]) > diff) diff = fabs(myw[i][j] - myu[i][j]); } } // reduce diff MPI_Allreduce(&diff, &alldiff, 1, MPI_DOUBLE, MPI_MAX, MPI_COMM_WORLD); #ifdef PRINTITER if(my_rank==0){ printf("iter=%d, diff=%lf\n", iter, alldiff); fflush(stdout); } #endif if (alldiff <= epsilon) break; if(proc_num > 1) { // send second top row if(my_rank != 0){ MPI_Isend(myw[1], N, MPI_DOUBLE, left, 0, MPI_COMM_WORLD, &send_req1); //printf("Send: %d->%d\n", my_rank, left); } // send second to bottom row if(my_rank != proc_num - 1){ MPI_Isend(myw[myN-2], N, MPI_DOUBLE, right, 1, MPI_COMM_WORLD, &send_req2); //printf("Send %d->%d\n", my_rank, right); } // recive top if(my_rank != 0){ MPI_Irecv(myw[0], N, MPI_DOUBLE, left, 1, MPI_COMM_WORLD, &recv_req1); //printf("Recv: %d->%d\n", my_rank, left); } // receive bottom if(my_rank != proc_num - 1) { MPI_Irecv(myw[myN-1], N, MPI_DOUBLE, right, 0, MPI_COMM_WORLD, &recv_req2); //printf("Recv %d->%d\n", my_rank, right); } if(my_rank != 0) MPI_Wait(&send_req1, &status); if(my_rank != proc_num - 1) MPI_Wait(&send_req2, &status); if(my_rank != 0) MPI_Wait(&recv_req1, &status); if(my_rank != proc_num - 1) MPI_Wait(&recv_req2, &status); } for (i=0; i<myN; i++) { if( (i==0&&my_rank==0) ||(i==myN-1&&my_rank==proc_num-1)) continue; for (j=1; j<N-1; j++) myu[i][j] = myw[i][j]; } // backup if(iter%cfreq == 0) backup(); } gettimeofday(&end_tv, NULL); printf("Elapsed time: %f sec\n", (double)( (double)(end_tv.tv_sec - start_tv.tv_sec) + ( (double)(end_tv.tv_usec - start_tv.tv_usec)/1000000)) ); // gather data if(my_rank==0) { for (i=0; i<myN; i++) { for(j=0; j<N; j++) { u[i][j] = myu[i][j]; } } if(proc_num > 1) { for (i=1; i<proc_num-1; i++) MPI_Recv(u[i*(N/proc_num)], (N/proc_num)*N, MPI_DOUBLE, i, 0, MPI_COMM_WORLD, &status); // special care for last one if(N%proc_num==0) MPI_Recv(u[i*(N/proc_num)], (N/proc_num)*N, MPI_DOUBLE, i, 0, MPI_COMM_WORLD, &status); else{ MPI_Recv(u[i*(N/proc_num)], (N-(N/proc_num)*(proc_num-1))*N, MPI_DOUBLE, i, 0, MPI_COMM_WORLD, &status); } } } else { if(N%proc_num==0) MPI_Send(myu[1], (N/proc_num)*N, MPI_DOUBLE, 0, 0, MPI_COMM_WORLD); else{ if(my_rank != proc_num-1) MPI_Send(myu[1], (myN-2)*N, MPI_DOUBLE, 0, 0, MPI_COMM_WORLD); else MPI_Send(myu[1], (myN-1)*N, MPI_DOUBLE, 0, 0, MPI_COMM_WORLD); } } if(my_rank == 0) { /* Print Solution */ fp = fopen("output.dat", "w"); for (i=0; i<N; i++) { for (j=0; j<N; j++) { fprintf(fp, "%6.2f ", u[i][j]); } fprintf(fp, "\n"); } fclose(fp); } mclose(); bclose(); MPI_Finalize(); return 0; }
/** * Set Extended File Attributes for Win32 * * fname is the original filename * ofile is the output filename (may be in a different directory) * * Returns: true on success * false on failure */ static bool set_win32_attributes(JCR *jcr, ATTR *attr, BFILE *ofd) { char *p = attr->attrEx; int64_t val; WIN32_FILE_ATTRIBUTE_DATA atts; ULARGE_INTEGER li; /** if we have neither Win ansi nor wchar API, get out */ if (!(p_SetFileAttributesW || p_SetFileAttributesA)) { return false; } if (!p || !*p) { /* we should have attributes */ Dmsg2(100, "Attributes missing. of=%s ofd=%d\n", attr->ofname, ofd->fid); if (is_bopen(ofd)) { bclose(ofd); } return false; } else { Dmsg2(100, "Attribs %s = %s\n", attr->ofname, attr->attrEx); } p += from_base64(&val, p); plug(atts.dwFileAttributes, val); p++; /* skip space */ p += from_base64(&val, p); li.QuadPart = val; atts.ftCreationTime.dwLowDateTime = li.LowPart; atts.ftCreationTime.dwHighDateTime = li.HighPart; p++; /* skip space */ p += from_base64(&val, p); li.QuadPart = val; atts.ftLastAccessTime.dwLowDateTime = li.LowPart; atts.ftLastAccessTime.dwHighDateTime = li.HighPart; p++; /* skip space */ p += from_base64(&val, p); li.QuadPart = val; atts.ftLastWriteTime.dwLowDateTime = li.LowPart; atts.ftLastWriteTime.dwHighDateTime = li.HighPart; p++; p += from_base64(&val, p); plug(atts.nFileSizeHigh, val); p++; p += from_base64(&val, p); plug(atts.nFileSizeLow, val); /** At this point, we have reconstructed the WIN32_FILE_ATTRIBUTE_DATA pkt */ if (!is_bopen(ofd)) { Dmsg1(100, "File not open: %s\n", attr->ofname); bopen(ofd, attr->ofname, O_WRONLY | O_BINARY, 0, 0); /* attempt to open the file */ } /* * Restore file attributes and times on the restored file. */ if (!win32_restore_file_attributes(attr->ofname, bget_handle(ofd), &atts)) { win_error(jcr, "win32_restore_file_attributes:", attr->ofname); } if (is_bopen(ofd)) { bclose(ofd); } return true; }
open_verify_vision() { int i; if ((bopen(vision_name, &vision_bf)) == 0) { cant_find(vision_name); return(0); } if (bread(&vision_bf, &vh, sizeof(vh)) < sizeof(vh)) { vitrunc(); return(0); } linebytes = VWID; switch (vh.imgdata.pixsiz) { case 16: bap = 2; break; case 24: bap = 3; break; case 32: bap = 4; break; default: continu_box(not_vision_lines); return(0); } linebytes *= bap; switch (vh.imgtype) { case 2: /* uncompressed */ is_compressed = 0; break; case 10: is_compressed = 1; break; default: continu_line(vision_103 /* "Unknown compression type" */); return(0); } if ((vh.imgdata.imgdesc & INLEAVE) != 0) { continu_line(vision_104 /* "Sorry, can't deal with Interleave" */); return(0); } if ((buf = lbegmem(linebytes + 130*bap)) == NULL) return(0); over = buf + linebytes; /* extra at end to make decompression easier */ for (i=0; i<3; i++) { if ((rgb_bufs[i] = begmem(VWID)) == NULL) return(0); } is_flipped = !((vh.imgdata.imgdesc&SCRORG) == SCRORG); if ((pic_cel = alloc_cel(VWID, vh.imgdata.height, vh.imgdata.xorg, vh.imgdata.yorg)) == NULL) return(0); vstart = pic_cel->p; vnext = pic_cel->bpr; if (is_flipped) { vstart = long_to_pt( pt_to_long(vstart) + vnext * (vh.imgdata.height-1)); vnext = -vnext; } data_offset = vh.idlength + sizeof(vh); if (vh.maptype != 0) data_offset += ((vh.cms.mapbits+7)/8)*vh.cms.maplen; return(1); }
void *balloc(B_ARGS_DEC, int size) { bType *bp; int q, memSize; /* * Call bopen with default values if the application has not yet done so */ if (bFreeBuf == NULL) { if (bopen(NULL, B_DEFAULT_MEM, 0) < 0) { return NULL; } } #ifdef B_VERIFY_CAUSES_SEVERE_OVERHEAD verifyBallocSpace(); #endif if (size < 0) { return NULL; } #ifdef BASTARD_TESTING if (rand() == 0x7fff) { return NULL; } #endif /* BASTARD_TESTING */ memSize = ballocGetSize(size, &q); if (q >= B_MAX_CLASS) { /* * Size if bigger than the maximum class. Malloc if use has been okayed */ if (bFlags & B_USE_MALLOC) { #ifdef B_STATS bstats(0, NULL); #endif #ifdef IRIX memSize = ROUNDUP4(memSize); #endif bp = (bType*) malloc(memSize); if (bp == NULL) { traceRaw(T("B: malloc failed\n")); return NULL; } #ifdef B_STATS bStatsMemMalloc += memSize; #endif #if (defined (B_FILL) || defined (B_VERIFY_CAUSES_SEVERE_OVERHEAD)) bFillBlock(bp, memSize); #endif } else { traceRaw(T("B: malloc failed\n")); return NULL; } /* * the u.size is the actual size allocated for data */ bp->u.size = memSize - sizeof(bType); bp->flags = B_MALLOCED; } else if ((bp = bQhead[q]) != NULL) { /* * Take first block off the relevant q if non-empty */ bQhead[q] = bp->u.next; #ifdef B_VERIFY_CAUSES_SEVERE_OVERHEAD verifyFreeBlock(bp, q); #endif #if (defined (B_FILL) || defined (B_VERIFY_CAUSES_SEVERE_OVERHEAD)) bFillBlock(bp, memSize); #endif bp->u.size = memSize - sizeof(bType); bp->flags = 0; } else { if (bFreeLeft > memSize) { /* * The q was empty, and the free list has spare memory so * create a new block out of the primary free block */ bp = (bType*) bFreeNext; #ifdef B_VERIFY_CAUSES_SEVERE_OVERHEAD verifyFreeBlock(bp, q); #endif bFreeNext += memSize; bFreeLeft -= memSize; #if (defined (B_FILL) || defined (B_VERIFY_CAUSES_SEVERE_OVERHEAD)) bFillBlock(bp, memSize); #endif bp->u.size = memSize - sizeof(bType); bp->flags = 0; } else if (bFlags & B_USE_MALLOC) { #ifdef B_STATS static int once = 0; if (once++ == 0) { bstats(0, NULL); } #endif /* * Nothing left on the primary free list, so malloc a new block */ #ifdef IRIX memSize = ROUNDUP4(memSize); #endif if ((bp = (bType*) malloc(memSize)) == NULL) { traceRaw(T("B: malloc failed\n")); return NULL; } #ifdef B_STATS bStatsMemMalloc += memSize; #endif #if (defined (B_FILL) || defined (B_VERIFY_CAUSES_SEVERE_OVERHEAD)) bFillBlock(bp, memSize); #endif bp->u.size = memSize - sizeof(bType); bp->flags = B_MALLOCED; } else { traceRaw(T("B: malloc failed\n")); return NULL; } } #ifdef B_STATS bStatsAlloc(B_ARGS, bp, q, memSize); #endif bp->flags |= B_INTEGRITY; /* * The following is a good place to put a breakpoint when trying to reduce * determine and reduce maximum memory use. */ #if 0 #ifdef B_STATS if (bStatsBallocInUse == bStatsBallocMax) { bstats(0, NULL); } #endif #endif return (void*) ((char*) bp + sizeof(bType)); }
int ihpapi_InitializeDevice (uint8_t sa [], uint8_t da [], size_t FW_len, uint8_t FW_pbuffer [], size_t PIB_len, uint8_t PIB_pbuffer [], unsigned options) { extern struct SeqCB scb; NVMBlockHeader *hdr; TxInfo *tcb = &scb.tcb; tcb->txok = false; #if INTELLON_SAFEMODE if (PIB_pbuffer == (uint8_t *)(0)) { errno = EFAULT; return (-1); } #endif if (_anyset (scb.flags, scbFlag_bsy)) { errno = EBUSY; return (-1); } memset (&scb, 0, sizeof (scb)); scb.flags = options; _clrbits (scb.flags, ~scbFlag_options); scb.opcode = IHPAPI_OPCODE_INITIALIZE_DEVICE; tcb->txok = true; memcpy (tcb->ODA, da, IHPAPI_ETHER_ADDR_LEN); memcpy (tcb->OSA, sa, IHPAPI_ETHER_ADDR_LEN); _setbits (scb.flags, scbFlag_PB); scb.bcb [1] = bopen (PIB_pbuffer, PIB_len, MAX_MODULE_TX_LENGTH); if (scb.bcb [1] == (buffer_t *)(0)) { return (-1); } scb.modid = PIB_MODID; if (_anybits (scb.flags, scbFlag_is6k) || _allbits (scb.flags, scbFlag_noINT6Kfwflash)) { /*! At this point: * Could be a Host Action Required) * Firmware and PIB only -> VS_WR_MOD * No trailer in the tcb required. */ if (FW_pbuffer) { scb.bcb [0] = bopen (FW_pbuffer, FW_len, MAX_MODULE_TX_LENGTH); if (scb.bcb [0] == (buffer_t *)(0)) { bclose (scb.bcb [1]); return (-1); } _setbits (scb.flags, scbFlag_FW); scb.txbcb = scb.bcb [0]; scb.modid |= MACSW_MODID; tcb->WRMDBLKR.MODULEID = MACSW_MODID; tcb->datalen = bgets (&tcb->data, 0, scb.bcb [0]); } else { scb.txbcb = scb.bcb [1]; tcb->WRMDBLKR.MODULEID = PIB_MODID; tcb->datalen = bgets (&tcb->data, 0, scb.bcb [1]); } tcb->MMTYPE = VS_WR_MOD | MMTYPE_REQ; tcb->hdrlen = sizeof (tcb->WRMDBLKR); tcb->WRMDBLKR.LENGTH = ihtons(tcb->datalen); tcb->WRMDBLKR.OFFSET = 0; tcb->WRMDBLKR.CHKSUM = ihtonl(checksum32 ((const uint32_t *)tcb->data, (tcb->datalen >> 2), 0)); } else { /*! At this point: * Host Action Required * Device Type -> Not a INT6000 * Blank Flash or No Flash * The Firmware and the PIB -> VS_WR_MEM * No trailer in the tcb required */ /*! Initialize the bcb for the firmware: * need to search to find the firmware header from the nvm file. The firmware * is the last entry on the nvm file, i.e. NEXTHEADER is equal to 0.; */ if (FW_pbuffer == (uint8_t *)(0))
int main(int argc, char** argv) { int i, demo = 0; for (i = 1; i < argc; i++) { if (strcmp(argv[i], "-demo") == 0) { demo++; } } #ifdef DEBUG printf("demo:%d\n",demo); //Modify by :LuiShiLi #endif //date :2011.09.28 //首先分配一个大的内存块(60*1024字节),以后只要是以b开头的 //对内存操作的函数都是在这个已经分好的内存块上的操作, //这些操作在Balloc.c中实现。 bopen(NULL, (60 * 1024), B_USE_MALLOC); signal(SIGPIPE, SIG_IGN); //管道破裂,写一个没有读端口的管道 signal(SIGINT, sigintHandler); //按键中断 signal(SIGTERM, sigintHandler); //终止信号 /* Initialize the web server 初始化用户管理部分,打开web服务器,注册URL处理函数。 用户管理部分在um.c中实现, Web服务器的初始化是在default.c和webs.c中实现 url处理函数在handler.c中实现 */ if (initWebs(demo) < 0) { return -1; } #ifdef WEBS_SSL_SUPPORT websSSLOpen(); /* websRequireSSL("/"); */ /* Require all files be served via https */ #endif /* * Basic event loop. SocketReady returns true when a socket is ready for * service. SocketSelect will block until an event occurs. SocketProcess * will actually do the servicing. */ //主循环 finished = 0; while (!finished) { /* 1,socketReady()函数检查是否有准备好的sock事件 2,socketSelect()函数首先把各个sock感兴趣的事件 (sp->handlerMask) 注册给三个集合(读,写,例外),然后调用select系统调用,然后更新各个sock 的 sp->currentEvents,表示各个sock的当前状态。 这两个函数在sockGen.c中实现,他们主要操作的数据是socket_t变量 socketList中 的handlerMask和currentEvents,socketList在sock.c中定义并主要由该文件中的 socketAlloc,socketFree和socketPtr三个函数维护。 */ if (socketReady(-1) || socketSelect(-1, 1000)) { /* 该函数处理具体的sock事件 1,调用socketReady(sid)对socketList[sid]进行检查,看是否有sock事件 2,如果有sock事件,则调用socketDoEvent()函数,对事件进行处理 */ socketProcess(-1); } /* 该函数在cgi.c中实现,检查cgiRec变量cgilist,首先把cgi的结果输出,如果有的话,然后看cgi进程是否已对号束,如果结束,就清理该cgi进程。 Cgilist在函数websCgiHandler和websCgiCleanup中维护。 */ websCgiCleanup(); /* 该函数在websuemf.c中实现,功能是检查sched_t变量sched,断开超时的连接,sched变量在emfSchedCallback和emfUnschedCallback中维护 */ emfSchedProcess(); } /* 退出时的清理工作,永远不会执行到这里 */ #ifdef WEBS_SSL_SUPPORT websSSLClose(); #endif #ifdef USER_MANAGEMENT_SUPPORT umClose(); #endif /* * Close the socket module, report memory leaks and close the memory allocator */ websCloseServer(); socketClose(); #ifdef B_STATS memLeaks(); #endif bclose(); return 0; }
/* * Main -- entry point from LINUX */ int main(int argc, char** argv) { int i, demo = 0; printf("OK open data!!!\n"); printf("open data OK!\n"); for (i = 0; i < argc; i++) { if (strcmp(argv[i], "-demo") == 0) { demo++; } } /* Initialize the memory allocator. Allow use of malloc and start * with a 60K heap. For each page request approx 8KB is allocated. * 60KB allows for several concurrent page requests. If more space * is required, malloc will be used for the overflow. */ bopen(NULL, (60 * 1024), B_USE_MALLOC); signal(SIGPIPE, SIG_IGN); signal(SIGINT, sigintHandler); signal(SIGTERM, sigintHandler); /* * Initialize the web server */ if (initWebs(demo) < 0) { return -1; } printf("Init Web service ok!\n"); #ifdef WEBS_SSL_SUPPORT websSSLOpen(); /* websRequireSSL("/"); */ /* Require all files be served via https */ #endif /* * Basic event loop. SocketReady returns true when a socket is ready for * service. SocketSelect will block until an event occurs. SocketProcess * will actually do the servicing. */ finished = 0; while (!finished) { if (socketReady(-1) || socketSelect(-1, 1000)) { socketProcess(-1); } websCgiCleanup(); emfSchedProcess(); } #ifdef WEBS_SSL_SUPPORT websSSLClose(); #endif #ifdef USER_MANAGEMENT_SUPPORT umClose(); #endif /* * Close the socket module, report memory leaks and close the memory allocator */ websCloseServer(); socketClose(); #ifdef B_STATS memLeaks(); #endif bclose(); return 0; }
/********************************************************************************************************* ** 函数名称: websStart ** 功能描述: 启动 GoAhead web 服务器 ** 输 入 : addr 主机地址 ** path web 路径 ** port 端口号 ** 输 出 : 0 ** 全局变量: ** 调用模块: *********************************************************************************************************/ int websStart(char *addr, char *path, int port) { /* * Initialize the memory allocator. Allow use of malloc and start * with a 60K heap. For each page request approx 8KB is allocated. * 60KB allows for several concurrent page requests. If more space * is required, malloc will be used for the overflow. */ bopen(NULL, (60 * 1024), B_USE_MALLOC); /* * Initialize the web server */ if (websInit(addr, path, port) < 0) { return -1; } #ifdef WEBS_SSL_SUPPORT websSSLOpen(); #endif /* * Basic event loop. SocketReady returns true when a socket is ready for * service. SocketSelect will block for two seconds or until an event * occurs. SocketProcess will actually do the servicing. */ running = TRUE; while (!running) { if (socketReady(-1) || socketSelect(-1, 2000)) { socketProcess(-1); } websCgiCleanup(); emfSchedProcess(); } #ifdef WEBS_SSL_SUPPORT websSSLClose(); #endif #ifdef USER_MANAGEMENT_SUPPORT umClose(); #endif /* * Close the socket module, report memory leaks and close the memory allocator */ websCloseServer(); websDefaultClose(); socketClose(); symSubClose(); #ifdef B_STATS { char *argv[2]; argv[0] = "goaheadmemleak"; argv[1] = "\0"; memLeaks(1, argv); /* print message on stdout */ } #endif bclose(); if (logFile != NULL) { fclose(logFile); logFile = NULL; } return 0; }
int _tmain(int argc, _TCHAR* argv[]) { int i, demo = 0; /* for (i = 1; i < argc; i++) { if (strcmp(argv[i], "-demo") == 0) { demo++; } } */ /* * Initialize the memory allocator. Allow use of malloc and start * with a 60K heap. For each page request approx 8KB is allocated. * 60KB allows for several concurrent page requests. If more space * is required, malloc will be used for the overflow. */ bopen(NULL, (60 * 1024), B_USE_MALLOC); /* * Store the instance handle (used in socket.c) */ /* * Initialize the web server */ if (initWebs(demo) < 0) { return FALSE; } #ifdef WEBS_SSL_SUPPORT websSSLOpen(); #endif /* * Basic event loop. SocketReady returns true when a socket is ready for * service. SocketSelect will block until an event occurs. SocketProcess * will actually do the servicing. */ wprintf(L"begin loop\n"); while (!finished) { if (socketReady(-1) || socketSelect(-1, sockServiceTime)) { wprintf(L"--->socketProcess\n"); socketProcess(-1); } emfSchedProcess(); //wprintf(L"cleanup\n"); websCgiCleanup(); } #ifdef WEBS_SSL_SUPPORT websSSLClose(); #endif /* * Close the User Management database */ #ifdef USER_MANAGEMENT_SUPPORT umClose(); #endif /* * Close the socket module, report memory leaks and close the memory allocator */ websCloseServer(); socketClose(); #ifdef B_STATS memLeaks(); #endif bclose(); return 0; }
int APIENTRY WinMain( HINSTANCE hinstance, HINSTANCE hprevinstance, char* args, int cmd_show ) { WPARAM rc; /* * Initialize the memory allocator. Allow use of malloc and start * with a 60K heap. For each page request approx 8KB is allocated. * 60KB allows for several concurrent page requests. If more space * is required, malloc will be used for the overflow. */ bopen( NULL, ( 60 * 1024 ), B_USE_MALLOC ); /* * Store the instance handle (used in socket.c) */ if ( windowsInit( hinstance ) < 0 ) { return FALSE; } /* * Initialize the web server */ if ( initWebs() < 0 ) { return FALSE; } #ifdef WEBS_SSL_SUPPORT websSSLOpen(); #endif /* * Basic event loop. SocketReady returns true when a socket is ready for * service. SocketSelect will block until an event occurs. SocketProcess * will actually do the servicing. */ while ( !finished ) { if ( socketReady( -1 ) || socketSelect( -1, sockServiceTime ) ) { socketProcess( -1 ); } emfSchedProcess(); websCgiCleanup(); if ( ( rc = checkWindowsMsgLoop() ) != 0 ) { break; } } #ifdef WEBS_SSL_SUPPORT websSSLClose(); #endif /* * Close the User Management database */ #ifdef USER_MANAGEMENT_SUPPORT umClose(); #endif /* * Close the socket module, report memory leaks and close the memory allocator */ websCloseServer(); socketClose(); /* * Free up Windows resources */ windowsClose( hinstance ); #ifdef B_STATS memLeaks(); #endif bclose(); return rc; }
/* * Called here by find() for each file included. * This is a callback. The original is find_files() above. * * Send the file and its data to the Storage daemon. * * Returns: 1 if OK * 0 if error * -1 to ignore file/directory (not used here) */ int save_file(JCR *jcr, FF_PKT *ff_pkt, bool top_level) { bool do_read = false; int stat, data_stream; int rtnstat = 0; DIGEST *digest = NULL; DIGEST *signing_digest = NULL; int digest_stream = STREAM_NONE; SIGNATURE *sig = NULL; bool has_file_data = false; // TODO landonf: Allow the user to specify the digest algorithm #ifdef HAVE_SHA2 crypto_digest_t signing_algorithm = CRYPTO_DIGEST_SHA256; #else crypto_digest_t signing_algorithm = CRYPTO_DIGEST_SHA1; #endif BSOCK *sd = jcr->store_bsock; if (job_canceled(jcr)) { return 0; } jcr->num_files_examined++; /* bump total file count */ switch (ff_pkt->type) { case FT_LNKSAVED: /* Hard linked, file already saved */ Dmsg2(130, "FT_LNKSAVED hard link: %s => %s\n", ff_pkt->fname, ff_pkt->link); break; case FT_REGE: Dmsg1(130, "FT_REGE saving: %s\n", ff_pkt->fname); has_file_data = true; break; case FT_REG: Dmsg1(130, "FT_REG saving: %s\n", ff_pkt->fname); has_file_data = true; break; case FT_LNK: Dmsg2(130, "FT_LNK saving: %s -> %s\n", ff_pkt->fname, ff_pkt->link); break; case FT_DIRBEGIN: jcr->num_files_examined--; /* correct file count */ return 1; /* not used */ case FT_NORECURSE: Jmsg(jcr, M_INFO, 1, _(" Recursion turned off. Will not descend from %s into %s\n"), ff_pkt->top_fname, ff_pkt->fname); ff_pkt->type = FT_DIREND; /* Backup only the directory entry */ break; case FT_NOFSCHG: /* Suppress message for /dev filesystems */ if (!is_in_fileset(ff_pkt)) { Jmsg(jcr, M_INFO, 1, _(" %s is a different filesystem. Will not descend from %s into %s\n"), ff_pkt->fname, ff_pkt->top_fname, ff_pkt->fname); } ff_pkt->type = FT_DIREND; /* Backup only the directory entry */ break; case FT_INVALIDFS: Jmsg(jcr, M_INFO, 1, _(" Disallowed filesystem. Will not descend from %s into %s\n"), ff_pkt->top_fname, ff_pkt->fname); ff_pkt->type = FT_DIREND; /* Backup only the directory entry */ break; case FT_INVALIDDT: Jmsg(jcr, M_INFO, 1, _(" Disallowed drive type. Will not descend into %s\n"), ff_pkt->fname); break; case FT_REPARSE: case FT_DIREND: Dmsg1(130, "FT_DIREND: %s\n", ff_pkt->link); break; case FT_SPEC: Dmsg1(130, "FT_SPEC saving: %s\n", ff_pkt->fname); if (S_ISSOCK(ff_pkt->statp.st_mode)) { Jmsg(jcr, M_SKIPPED, 1, _(" Socket file skipped: %s\n"), ff_pkt->fname); return 1; } break; case FT_RAW: Dmsg1(130, "FT_RAW saving: %s\n", ff_pkt->fname); has_file_data = true; break; case FT_FIFO: Dmsg1(130, "FT_FIFO saving: %s\n", ff_pkt->fname); break; case FT_NOACCESS: { berrno be; Jmsg(jcr, M_NOTSAVED, 0, _(" Could not access \"%s\": ERR=%s\n"), ff_pkt->fname, be.bstrerror(ff_pkt->ff_errno)); jcr->JobErrors++; return 1; } case FT_NOFOLLOW: { berrno be; Jmsg(jcr, M_NOTSAVED, 0, _(" Could not follow link \"%s\": ERR=%s\n"), ff_pkt->fname, be.bstrerror(ff_pkt->ff_errno)); jcr->JobErrors++; return 1; } case FT_NOSTAT: { berrno be; Jmsg(jcr, M_NOTSAVED, 0, _(" Could not stat \"%s\": ERR=%s\n"), ff_pkt->fname, be.bstrerror(ff_pkt->ff_errno)); jcr->JobErrors++; return 1; } case FT_DIRNOCHG: case FT_NOCHG: Jmsg(jcr, M_SKIPPED, 1, _(" Unchanged file skipped: %s\n"), ff_pkt->fname); return 1; case FT_ISARCH: Jmsg(jcr, M_NOTSAVED, 0, _(" Archive file not saved: %s\n"), ff_pkt->fname); return 1; case FT_NOOPEN: { berrno be; Jmsg(jcr, M_NOTSAVED, 0, _(" Could not open directory \"%s\": ERR=%s\n"), ff_pkt->fname, be.bstrerror(ff_pkt->ff_errno)); jcr->JobErrors++; return 1; } default: Jmsg(jcr, M_NOTSAVED, 0, _(" Unknown file type %d; not saved: %s\n"), ff_pkt->type, ff_pkt->fname); jcr->JobErrors++; return 1; } Dmsg1(130, "bfiled: sending %s to stored\n", ff_pkt->fname); /* Digests and encryption are only useful if there's file data */ if (has_file_data) { /* * Setup for digest handling. If this fails, the digest will be set to NULL * and not used. Note, the digest (file hash) can be any one of the four * algorithms below. * * The signing digest is a single algorithm depending on * whether or not we have SHA2. * ****FIXME**** the signing algoritm should really be * determined a different way!!!!!! What happens if * sha2 was available during backup but not restore? */ if (ff_pkt->flags & FO_MD5) { digest = crypto_digest_new(jcr, CRYPTO_DIGEST_MD5); digest_stream = STREAM_MD5_DIGEST; } else if (ff_pkt->flags & FO_SHA1) { digest = crypto_digest_new(jcr, CRYPTO_DIGEST_SHA1); digest_stream = STREAM_SHA1_DIGEST; } else if (ff_pkt->flags & FO_SHA256) { digest = crypto_digest_new(jcr, CRYPTO_DIGEST_SHA256); digest_stream = STREAM_SHA256_DIGEST; } else if (ff_pkt->flags & FO_SHA512) { digest = crypto_digest_new(jcr, CRYPTO_DIGEST_SHA512); digest_stream = STREAM_SHA512_DIGEST; } /* Did digest initialization fail? */ if (digest_stream != STREAM_NONE && digest == NULL) { Jmsg(jcr, M_WARNING, 0, _("%s digest initialization failed\n"), stream_to_ascii(digest_stream)); } /* * Set up signature digest handling. If this fails, the signature digest will be set to * NULL and not used. */ // TODO landonf: We should really only calculate the digest once, for both verification and signing. if (jcr->crypto.pki_sign) { signing_digest = crypto_digest_new(jcr, signing_algorithm); /* Full-stop if a failure occurred initializing the signature digest */ if (signing_digest == NULL) { Jmsg(jcr, M_NOTSAVED, 0, _("%s signature digest initialization failed\n"), stream_to_ascii(signing_algorithm)); jcr->JobErrors++; goto good_rtn; } } /* Enable encryption */ if (jcr->crypto.pki_encrypt) { ff_pkt->flags |= FO_ENCRYPT; } } /* Initialize the file descriptor we use for data and other streams. */ binit(&ff_pkt->bfd); if (ff_pkt->flags & FO_PORTABLE) { set_portable_backup(&ff_pkt->bfd); /* disable Win32 BackupRead() */ } if (ff_pkt->cmd_plugin) { if (!set_cmd_plugin(&ff_pkt->bfd, jcr)) { goto bail_out; } send_plugin_name(jcr, sd, true); /* signal start of plugin data */ } /* Send attributes -- must be done after binit() */ if (!encode_and_send_attributes(jcr, ff_pkt, data_stream)) { goto bail_out; } /* Set up the encryption context and send the session data to the SD */ if (has_file_data && jcr->crypto.pki_encrypt) { if (!crypto_session_send(jcr, sd)) { goto bail_out; } } /* * Open any file with data that we intend to save, then save it. * * Note, if is_win32_backup, we must open the Directory so that * the BackupRead will save its permissions and ownership streams. */ if (ff_pkt->type != FT_LNKSAVED && S_ISREG(ff_pkt->statp.st_mode)) { #ifdef HAVE_WIN32 do_read = !is_portable_backup(&ff_pkt->bfd) || ff_pkt->statp.st_size > 0; #else do_read = ff_pkt->statp.st_size > 0; #endif } else if (ff_pkt->type == FT_RAW || ff_pkt->type == FT_FIFO || ff_pkt->type == FT_REPARSE || (!is_portable_backup(&ff_pkt->bfd) && ff_pkt->type == FT_DIREND)) { do_read = true; } if (ff_pkt->cmd_plugin) { do_read = true; } Dmsg1(400, "do_read=%d\n", do_read); if (do_read) { btimer_t *tid; if (ff_pkt->type == FT_FIFO) { tid = start_thread_timer(jcr, pthread_self(), 60); } else { tid = NULL; } int noatime = ff_pkt->flags & FO_NOATIME ? O_NOATIME : 0; ff_pkt->bfd.reparse_point = ff_pkt->type == FT_REPARSE; if (bopen(&ff_pkt->bfd, ff_pkt->fname, O_RDONLY | O_BINARY | noatime, 0) < 0) { ff_pkt->ff_errno = errno; berrno be; Jmsg(jcr, M_NOTSAVED, 0, _(" Cannot open \"%s\": ERR=%s.\n"), ff_pkt->fname, be.bstrerror()); jcr->JobErrors++; if (tid) { stop_thread_timer(tid); tid = NULL; } goto good_rtn; } if (tid) { stop_thread_timer(tid); tid = NULL; } stat = send_data(jcr, data_stream, ff_pkt, digest, signing_digest); if (ff_pkt->flags & FO_CHKCHANGES) { has_file_changed(jcr, ff_pkt); } bclose(&ff_pkt->bfd); if (!stat) { goto bail_out; } } #ifdef HAVE_DARWIN_OS /* Regular files can have resource forks and Finder Info */ if (ff_pkt->type != FT_LNKSAVED && (S_ISREG(ff_pkt->statp.st_mode) && ff_pkt->flags & FO_HFSPLUS)) { if (ff_pkt->hfsinfo.rsrclength > 0) { int flags; int rsrc_stream; if (!bopen_rsrc(&ff_pkt->bfd, ff_pkt->fname, O_RDONLY | O_BINARY, 0) < 0) { ff_pkt->ff_errno = errno; berrno be; Jmsg(jcr, M_NOTSAVED, -1, _(" Cannot open resource fork for \"%s\": ERR=%s.\n"), ff_pkt->fname, be.bstrerror()); jcr->JobErrors++; if (is_bopen(&ff_pkt->bfd)) { bclose(&ff_pkt->bfd); } goto good_rtn; } flags = ff_pkt->flags; ff_pkt->flags &= ~(FO_GZIP|FO_SPARSE); if (flags & FO_ENCRYPT) { rsrc_stream = STREAM_ENCRYPTED_MACOS_FORK_DATA; } else { rsrc_stream = STREAM_MACOS_FORK_DATA; } stat = send_data(jcr, rsrc_stream, ff_pkt, digest, signing_digest); ff_pkt->flags = flags; bclose(&ff_pkt->bfd); if (!stat) { goto bail_out; } } Dmsg1(300, "Saving Finder Info for \"%s\"\n", ff_pkt->fname); sd->fsend("%ld %d 0", jcr->JobFiles, STREAM_HFSPLUS_ATTRIBUTES); Dmsg1(300, "bfiled>stored:header %s\n", sd->msg); pm_memcpy(sd->msg, ff_pkt->hfsinfo.fndrinfo, 32); sd->msglen = 32; if (digest) { crypto_digest_update(digest, (uint8_t *)sd->msg, sd->msglen); } if (signing_digest) { crypto_digest_update(signing_digest, (uint8_t *)sd->msg, sd->msglen); } sd->send(); sd->signal(BNET_EOD); } #endif /* * Save ACLs for anything not being a symlink and not being a plugin. */ if (!ff_pkt->cmd_plugin) { if (ff_pkt->flags & FO_ACL && ff_pkt->type != FT_LNK) { if (!build_acl_streams(jcr, ff_pkt)) goto bail_out; } } /* * Save Extended Attributes for all files not being a plugin. */ if (!ff_pkt->cmd_plugin) { if (ff_pkt->flags & FO_XATTR) { if (!build_xattr_streams(jcr, ff_pkt)) goto bail_out; } } /* Terminate the signing digest and send it to the Storage daemon */ if (signing_digest) { uint32_t size = 0; if ((sig = crypto_sign_new(jcr)) == NULL) { Jmsg(jcr, M_FATAL, 0, _("Failed to allocate memory for crypto signature.\n")); goto bail_out; } if (!crypto_sign_add_signer(sig, signing_digest, jcr->crypto.pki_keypair)) { Jmsg(jcr, M_FATAL, 0, _("An error occurred while signing the stream.\n")); goto bail_out; } /* Get signature size */ if (!crypto_sign_encode(sig, NULL, &size)) { Jmsg(jcr, M_FATAL, 0, _("An error occurred while signing the stream.\n")); goto bail_out; } /* Grow the bsock buffer to fit our message if necessary */ if (sizeof_pool_memory(sd->msg) < (int32_t)size) { sd->msg = realloc_pool_memory(sd->msg, size); } /* Send our header */ sd->fsend("%ld %ld 0", jcr->JobFiles, STREAM_SIGNED_DIGEST); Dmsg1(300, "bfiled>stored:header %s\n", sd->msg); /* Encode signature data */ if (!crypto_sign_encode(sig, (uint8_t *)sd->msg, &size)) { Jmsg(jcr, M_FATAL, 0, _("An error occurred while signing the stream.\n")); goto bail_out; } sd->msglen = size; sd->send(); sd->signal(BNET_EOD); /* end of checksum */ } /* Terminate any digest and send it to Storage daemon */ if (digest) { uint32_t size; sd->fsend("%ld %d 0", jcr->JobFiles, digest_stream); Dmsg1(300, "bfiled>stored:header %s\n", sd->msg); size = CRYPTO_DIGEST_MAX_SIZE; /* Grow the bsock buffer to fit our message if necessary */ if (sizeof_pool_memory(sd->msg) < (int32_t)size) { sd->msg = realloc_pool_memory(sd->msg, size); } if (!crypto_digest_finalize(digest, (uint8_t *)sd->msg, &size)) { Jmsg(jcr, M_FATAL, 0, _("An error occurred finalizing signing the stream.\n")); goto bail_out; } sd->msglen = size; sd->send(); sd->signal(BNET_EOD); /* end of checksum */ } if (ff_pkt->cmd_plugin) { send_plugin_name(jcr, sd, false); /* signal end of plugin data */ } good_rtn: rtnstat = 1; /* good return */ bail_out: if (digest) { crypto_digest_free(digest); } if (signing_digest) { crypto_digest_free(signing_digest); } if (sig) { crypto_sign_free(sig); } return rtnstat; }
/* * Create the file, or the directory * * fname is the original filename * ofile is the output filename (may be in a different directory) * * Returns: CF_SKIP if file should be skipped * CF_ERROR on error * CF_EXTRACT file created and data to restore * CF_CREATED file created no data to restore * * Note, we create the file here, except for special files, * we do not set the attributes because we want to first * write the file, then when the writing is done, set the * attributes. * So, we return with the file descriptor open for normal * files. * */ int create_file(JCR *jcr, ATTR *attr, BFILE *bfd, int replace) { mode_t new_mode, parent_mode; int flags; uid_t uid; gid_t gid; int pnl; bool exists = false; struct stat mstatp; bfd->reparse_point = false; if (is_win32_stream(attr->data_stream)) { set_win32_backup(bfd); } else { set_portable_backup(bfd); } new_mode = attr->statp.st_mode; Dmsg3(200, "type=%d newmode=%x file=%s\n", attr->type, new_mode, attr->ofname); parent_mode = S_IWUSR | S_IXUSR | new_mode; gid = attr->statp.st_gid; uid = attr->statp.st_uid; #ifdef HAVE_WIN32 if (!bfd->use_backup_api) { // eliminate invalid windows filename characters from foreign filenames char *ch = (char *)attr->ofname; if (ch[0] != 0 && ch[1] != 0) { ch += 2; while (*ch) { switch (*ch) { case ':': case '<': case '>': case '*': case '?': case '|': *ch = '_'; break; } ch++; } } } #endif Dmsg2(400, "Replace=%c %d\n", (char)replace, replace); if (lstat(attr->ofname, &mstatp) == 0) { exists = true; switch (replace) { case REPLACE_IFNEWER: if (attr->statp.st_mtime <= mstatp.st_mtime) { Qmsg(jcr, M_SKIPPED, 0, _("File skipped. Not newer: %s\n"), attr->ofname); return CF_SKIP; } break; case REPLACE_IFOLDER: if (attr->statp.st_mtime >= mstatp.st_mtime) { Qmsg(jcr, M_SKIPPED, 0, _("File skipped. Not older: %s\n"), attr->ofname); return CF_SKIP; } break; case REPLACE_NEVER: Qmsg(jcr, M_SKIPPED, 0, _("File skipped. Already exists: %s\n"), attr->ofname); return CF_SKIP; case REPLACE_ALWAYS: break; } } switch (attr->type) { case FT_RAW: /* raw device to be written */ case FT_FIFO: /* FIFO to be written to */ case FT_LNKSAVED: /* Hard linked, file already saved */ case FT_LNK: case FT_SPEC: /* fifo, ... to be backed up */ case FT_REGE: /* empty file */ case FT_REG: /* regular file */ /* * Note, we do not delete FT_RAW because these are device files * or FIFOs that should already exist. If we blow it away, * we may blow away a FIFO that is being used to read the * restore data, or we may blow away a partition definition. */ if (exists && attr->type != FT_RAW && attr->type != FT_FIFO) { /* Get rid of old copy */ Dmsg1(400, "unlink %s\n", attr->ofname); if (unlink(attr->ofname) == -1) { berrno be; Qmsg(jcr, M_ERROR, 0, _("File %s already exists and could not be replaced. ERR=%s.\n"), attr->ofname, be.bstrerror()); /* Continue despite error */ } } /* * Here we do some preliminary work for all the above * types to create the path to the file if it does * not already exist. Below, we will split to * do the file type specific work */ pnl = separate_path_and_file(jcr, attr->fname, attr->ofname); if (pnl < 0) { return CF_ERROR; } /* * If path length is <= 0 we are making a file in the root * directory. Assume that the directory already exists. */ if (pnl > 0) { char savechr; savechr = attr->ofname[pnl]; attr->ofname[pnl] = 0; /* terminate path */ if (!path_already_seen(jcr, attr->ofname, pnl)) { Dmsg1(400, "Make path %s\n", attr->ofname); /* * 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 (!makepath(attr, attr->ofname, parent_mode, parent_mode, uid, gid, 1)) { Dmsg1(10, "Could not make path. %s\n", attr->ofname); attr->ofname[pnl] = savechr; /* restore full name */ return CF_ERROR; } } attr->ofname[pnl] = savechr; /* restore full name */ } /* Now we do the specific work for each file type */ switch(attr->type) { case FT_REGE: case FT_REG: Dmsg1(100, "Create=%s\n", attr->ofname); flags = O_WRONLY | O_CREAT | O_TRUNC | O_BINARY; /* O_NOFOLLOW; */ if (IS_CTG(attr->statp.st_mode)) { flags |= O_CTG; /* set contiguous bit if needed */ } if (is_bopen(bfd)) { Qmsg1(jcr, M_ERROR, 0, _("bpkt already open fid=%d\n"), bfd->fid); bclose(bfd); } if ((bopen(bfd, attr->ofname, flags, S_IRUSR | S_IWUSR)) < 0) { berrno be; be.set_errno(bfd->berrno); Qmsg2(jcr, M_ERROR, 0, _("Could not create %s: ERR=%s\n"), attr->ofname, be.bstrerror()); Dmsg2(100,"Could not create %s: ERR=%s\n", attr->ofname, be.bstrerror()); return CF_ERROR; } return CF_EXTRACT; #ifndef HAVE_WIN32 // none of these exists on MS Windows case FT_RAW: /* Bacula raw device e.g. /dev/sda1 */ case FT_FIFO: /* Bacula fifo to save data */ case FT_SPEC: if (S_ISFIFO(attr->statp.st_mode)) { Dmsg1(400, "Restore fifo: %s\n", attr->ofname); if (mkfifo(attr->ofname, attr->statp.st_mode) != 0 && errno != EEXIST) { berrno be; Qmsg2(jcr, M_ERROR, 0, _("Cannot make fifo %s: ERR=%s\n"), attr->ofname, be.bstrerror()); return CF_ERROR; } } else if (S_ISSOCK(attr->statp.st_mode)) { Dmsg1(200, "Skipping restore of socket: %s\n", attr->ofname); #ifdef S_IFDOOR // Solaris high speed RPC mechanism } else if (S_ISDOOR(attr->statp.st_mode)) { Dmsg1(200, "Skipping restore of door file: %s\n", attr->ofname); #endif #ifdef S_IFPORT // Solaris event port for handling AIO } else if (S_ISPORT(attr->statp.st_mode)) { Dmsg1(200, "Skipping restore of event port file: %s\n", attr->ofname); #endif } else { Dmsg1(400, "Restore node: %s\n", attr->ofname); if (mknod(attr->ofname, attr->statp.st_mode, attr->statp.st_rdev) != 0 && errno != EEXIST) { berrno be; Qmsg2(jcr, M_ERROR, 0, _("Cannot make node %s: ERR=%s\n"), attr->ofname, be.bstrerror()); return CF_ERROR; } } /* * Here we are going to attempt to restore to a FIFO, which * means that the FIFO must already exist, AND there must * be some process already attempting to read from the * FIFO, so we open it write-only. */ if (attr->type == FT_RAW || attr->type == FT_FIFO) { btimer_t *tid; Dmsg1(400, "FT_RAW|FT_FIFO %s\n", attr->ofname); flags = O_WRONLY | O_BINARY; /* Timeout open() in 60 seconds */ if (attr->type == FT_FIFO) { Dmsg0(400, "Set FIFO timer\n"); tid = start_thread_timer(jcr, pthread_self(), 60); } else { tid = NULL; } if (is_bopen(bfd)) { Qmsg1(jcr, M_ERROR, 0, _("bpkt already open fid=%d\n"), bfd->fid); } Dmsg2(400, "open %s flags=0x%x\n", attr->ofname, flags); if ((bopen(bfd, attr->ofname, flags, 0)) < 0) { berrno be; be.set_errno(bfd->berrno); Qmsg2(jcr, M_ERROR, 0, _("Could not open %s: ERR=%s\n"), attr->ofname, be.bstrerror()); Dmsg2(400, "Could not open %s: ERR=%s\n", attr->ofname, be.bstrerror()); stop_thread_timer(tid); return CF_ERROR; } stop_thread_timer(tid); return CF_EXTRACT; } Dmsg1(400, "FT_SPEC %s\n", attr->ofname); return CF_CREATED; case FT_LNK: Dmsg2(130, "FT_LNK should restore: %s -> %s\n", attr->ofname, attr->olname); if (symlink(attr->olname, attr->ofname) != 0 && errno != EEXIST) { berrno be; Qmsg3(jcr, M_ERROR, 0, _("Could not symlink %s -> %s: ERR=%s\n"), attr->ofname, attr->olname, be.bstrerror()); return CF_ERROR; } return CF_CREATED; case FT_LNKSAVED: /* Hard linked, file already saved */ Dmsg2(130, "Hard link %s => %s\n", attr->ofname, attr->olname); if (link(attr->olname, attr->ofname) != 0) { berrno be; #ifdef HAVE_CHFLAGS struct stat s; /* * If using BSD user flags, maybe has a file flag * preventing this. So attempt to disable, retry link, * and reset flags. * Note that BSD securelevel may prevent disabling flag. */ if (stat(attr->olname, &s) == 0 && s.st_flags != 0) { if (chflags(attr->olname, 0) == 0) { if (link(attr->olname, attr->ofname) != 0) { /* restore original file flags even when linking failed */ if (chflags(attr->olname, s.st_flags) < 0) { Qmsg2(jcr, M_ERROR, 0, _("Could not restore file flags for file %s: ERR=%s\n"), attr->olname, be.bstrerror()); } #endif /* HAVE_CHFLAGS */ Qmsg3(jcr, M_ERROR, 0, _("Could not hard link %s -> %s: ERR=%s\n"), attr->ofname, attr->olname, be.bstrerror()); Dmsg3(200, "Could not hard link %s -> %s: ERR=%s\n", attr->ofname, attr->olname, be.bstrerror()); return CF_ERROR; #ifdef HAVE_CHFLAGS } /* finally restore original file flags */ if (chflags(attr->olname, s.st_flags) < 0) { Qmsg2(jcr, M_ERROR, 0, _("Could not restore file flags for file %s: ERR=%s\n"), attr->olname, be.bstrerror()); } } else { Qmsg2(jcr, M_ERROR, 0, _("Could not reset file flags for file %s: ERR=%s\n"), attr->olname, be.bstrerror()); } } else { Qmsg3(jcr, M_ERROR, 0, _("Could not hard link %s -> %s: ERR=%s\n"), attr->ofname, attr->olname, be.bstrerror()); return CF_ERROR; } #endif /* HAVE_CHFLAGS */ } return CF_CREATED; #endif } /* End inner switch */ case FT_REPARSE: bfd->reparse_point = true; /* Fall through wanted */ case FT_DIRBEGIN: case FT_DIREND: Dmsg2(200, "Make dir mode=%o dir=%s\n", new_mode, attr->ofname); if (!makepath(attr, attr->ofname, new_mode, parent_mode, uid, gid, 0)) { return CF_ERROR; } /* * If we are using the Win32 Backup API, we open the * directory so that the security info will be read * and saved. */ if (!is_portable_backup(bfd)) { if (is_bopen(bfd)) { Qmsg1(jcr, M_ERROR, 0, _("bpkt already open fid=%d\n"), bfd->fid); } if ((bopen(bfd, attr->ofname, O_WRONLY|O_BINARY, 0)) < 0) { berrno be; be.set_errno(bfd->berrno); #ifdef HAVE_WIN32 /* Check for trying to create a drive, if so, skip */ if (attr->ofname[1] == ':' && IsPathSeparator(attr->ofname[2]) && attr->ofname[3] == '\0') { return CF_SKIP; } #endif Qmsg2(jcr, M_ERROR, 0, _("Could not open %s: ERR=%s\n"), attr->ofname, be.bstrerror()); return CF_ERROR; } return CF_EXTRACT; } else { return CF_CREATED; } case FT_DELETED: Qmsg2(jcr, M_INFO, 0, _("Original file %s have been deleted: type=%d\n"), attr->fname, attr->type); break; /* The following should not occur */ case FT_NOACCESS: case FT_NOFOLLOW: case FT_NOSTAT: case FT_DIRNOCHG: case FT_NOCHG: case FT_ISARCH: case FT_NORECURSE: case FT_NOFSCHG: case FT_NOOPEN: Qmsg2(jcr, M_ERROR, 0, _("Original file %s not saved: type=%d\n"), attr->fname, attr->type); break; default: Qmsg2(jcr, M_ERROR, 0, _("Unknown file type %d; not restored: %s\n"), attr->type, attr->fname); break; } return CF_ERROR; }