Beispiel #1
0
/*
 * Create a standard "Unix" pid file.
 */
void create_pid_file(char *dir, const char *progname, int port)
{
#if !defined(HAVE_WIN32)
   int pidfd, len;
   int oldpid;
   char  pidbuf[20];
   POOLMEM *fname = get_pool_memory(PM_FNAME);
   struct stat statp;

   Mmsg(&fname, "%s/%s.%d.pid", dir, progname, port);
   if (stat(fname, &statp) == 0) {
      /* File exists, see what we have */
      *pidbuf = 0;
      if ((pidfd = open(fname, O_RDONLY|O_BINARY, 0)) < 0 ||
           read(pidfd, &pidbuf, sizeof(pidbuf)) < 0 ||
           sscanf(pidbuf, "%d", &oldpid) != 1) {
         berrno be;
         Emsg2(M_ERROR_TERM, 0, _("Cannot open pid file. %s ERR=%s\n"), fname,
               be.bstrerror());
      }
      /* Some OSes (IRIX) don't bother to clean out the old pid files after a crash, and
       * since they use a deterministic algorithm for assigning PIDs, we can have
       * pid conflicts with the old PID file after a reboot.
       * The intent the following code is to check if the oldpid read from the pid
       * file is the same as the currently executing process's pid,
       * and if oldpid == getpid(), skip the attempt to
       * kill(oldpid,0), since the attempt is guaranteed to succeed,
       * but the success won't actually mean that there is an
       * another BAREOS process already running.
       * For more details see bug #797.
       */
       if ((oldpid != (int)getpid()) && (kill(oldpid, 0) != -1 || errno != ESRCH)) {
         Emsg3(M_ERROR_TERM, 0, _("%s is already running. pid=%d\nCheck file %s\n"),
               progname, oldpid, fname);
      }
      /* He is not alive, so take over file ownership */
      unlink(fname);                  /* remove stale pid file */
   }
   /* Create new pid file */
   if ((pidfd = open(fname, O_CREAT|O_TRUNC|O_WRONLY|O_BINARY, 0640)) >= 0) {
      len = sprintf(pidbuf, "%d\n", (int)getpid());
      write(pidfd, pidbuf, len);
      close(pidfd);
      del_pid_file_ok = TRUE;         /* we created it so we can delete it */
   } else {
      berrno be;
      Emsg2(M_ERROR_TERM, 0, _("Could not open pid file. %s ERR=%s\n"), fname,
            be.bstrerror());
   }
   free_pool_memory(fname);
#endif
}
Beispiel #2
0
POOLMEM *sm_get_pool_memory(const char *fname, int lineno, int pool)
{
   struct abufhead *buf;

   if (pool > PM_MAX) {
      Emsg2(M_ABORT, 0, _("MemPool index %d larger than max %d\n"), pool, PM_MAX);
   }
   P(mutex);
   if (pool_ctl[pool].free_buf) {
      buf = pool_ctl[pool].free_buf;
      pool_ctl[pool].free_buf = buf->next;
      pool_ctl[pool].in_use++;
      if (pool_ctl[pool].in_use > pool_ctl[pool].max_used) {
         pool_ctl[pool].max_used = pool_ctl[pool].in_use;
      }
      V(mutex);
      Dmsg3(dbglvl, "sm_get_pool_memory reuse %p to %s:%d\n", buf, fname, lineno);
      sm_new_owner(fname, lineno, (char *)buf);
      return (POOLMEM *)((char *)buf+HEAD_SIZE);
   }

   if ((buf = (struct abufhead *)sm_malloc(fname, lineno, pool_ctl[pool].size+HEAD_SIZE)) == NULL) {
      V(mutex);
      Emsg1(M_ABORT, 0, _("Out of memory requesting %d bytes\n"), pool_ctl[pool].size);
   }
   buf->ablen = pool_ctl[pool].size;
   buf->pool = pool;
   pool_ctl[pool].in_use++;
   if (pool_ctl[pool].in_use > pool_ctl[pool].max_used) {
      pool_ctl[pool].max_used = pool_ctl[pool].in_use;
   }
   V(mutex);
   Dmsg3(dbglvl, "sm_get_pool_memory give %p to %s:%d\n", buf, fname, lineno);
   return (POOLMEM *)((char *)buf+HEAD_SIZE);
}
Beispiel #3
0
/*
 * Make a quick check to see that we have all the
 * resources needed.
 */
static int check_resources()
{
   bool ok = true;
   DIRRES *director;
   int numdir;
   bool tls_needed;

   LockRes();

   numdir = 0;
   foreach_res(director, R_DIRECTOR) {
      numdir++;
      /* tls_require implies tls_enable */
      if (director->tls_require) {
         if (have_tls) {
            director->tls_enable = true;
         } else {
            Jmsg(NULL, M_FATAL, 0, _("TLS required but not configured in Bacula.\n"));
            ok = false;
            continue;
         }
      }
      tls_needed = director->tls_enable || director->tls_authenticate;

      if ((!director->tls_ca_certfile && !director->tls_ca_certdir) && tls_needed) {
         Emsg2(M_FATAL, 0, _("Neither \"TLS CA Certificate\""
                             " or \"TLS CA Certificate Dir\" are defined for Director \"%s\" in %s."
                             " At least one CA certificate store is required.\n"),
                             director->hdr.name, configfile);
         ok = false;
      }
   }
Beispiel #4
0
QStringList MonitorItemThread::createRes(const cl_opts& cl)
{
   QStringList tabRefs;

   LockRes(my_config);

   int monitorItems = 0;
   MONITORRES *monitorRes;
   foreach_res(my_config, monitorRes, R_MONITOR) {
      monitorItems++;
   }

   if (monitorItems != 1) {
      Emsg2(M_ERROR_TERM, 0,
         _("Error: %d Monitor resources defined in %s. "
           "You must define one and only one Monitor resource.\n"),
            monitorItems, cl.configfile);
   }

   monitor = reinterpret_cast<MONITORRES*>(my_config->GetNextRes(R_MONITOR, (RES *)NULL));

   int nitems = 0;

   DIRRES* dird;
   foreach_res(my_config, dird, R_DIRECTOR) {
      MonitorItem* item = new MonitorItem;
      item->setType(R_DIRECTOR);
      item->setResource(dird);
      item->setConnectTimeout(monitor->DIRConnectTimeout);
      item->connectToMainWindow(MainWindow::instance());
      tabRefs.append(item->get_name());
      items.append(item);
      nitems++;
   }
Beispiel #5
0
static BSR *store_fileregex(LEX *lc, BSR *bsr)
{
   int token;
   int rc;

   token = lex_get_token(lc, T_STRING);
   if (token == T_ERROR) {
      return NULL;
   }

   if (bsr->fileregex) free(bsr->fileregex);
   bsr->fileregex = bstrdup(lc->str);

   if (bsr->fileregex_re == NULL)
      bsr->fileregex_re = (regex_t *)bmalloc(sizeof(regex_t));

   rc = regcomp(bsr->fileregex_re, bsr->fileregex, REG_EXTENDED|REG_NOSUB);
   if (rc != 0) {
      char prbuf[500];
      regerror(rc, bsr->fileregex_re, prbuf, sizeof(prbuf));
      Emsg2(M_ERROR, 0, _("REGEX '%s' compile error. ERR=%s\n"),
            bsr->fileregex, prbuf);
      return NULL;
   }
   return bsr;
}
Beispiel #6
0
/*********************************************************************
 *
 *      Parse Bootstrap file
 *
 */
BSR *parse_bsr(JCR *jcr, char *fname)
{
   LEX *lc = NULL;
   int token, i;
   BSR *root_bsr = new_bsr();
   BSR *bsr = root_bsr;

   Dmsg1(300, "Enter parse_bsf %s\n", fname);
   if ((lc = lex_open_file(lc, fname, s_err)) == NULL) {
      berrno be;
      Emsg2(M_ERROR_TERM, 0, _("Cannot open bootstrap file %s: %s\n"),
            fname, be.bstrerror());
   }
   lc->caller_ctx = (void *)jcr;
   while ((token=lex_get_token(lc, T_ALL)) != T_EOF) {
      Dmsg1(300, "parse got token=%s\n", lex_tok_to_str(token));
      if (token == T_EOL) {
         continue;
      }
      for (i=0; items[i].name; i++) {
         if (strcasecmp(items[i].name, lc->str) == 0) {
            token = lex_get_token(lc, T_ALL);
            Dmsg1 (300, "in T_IDENT got token=%s\n", lex_tok_to_str(token));
            if (token != T_EQUALS) {
               scan_err1(lc, "expected an equals, got: %s", lc->str);
               bsr = NULL;
               break;
            }
            Dmsg1(300, "calling handler for %s\n", items[i].name);
            /* Call item handler */
            bsr = items[i].handler(lc, bsr);
            i = -1;
            break;
         }
      }
      if (i >= 0) {
         Dmsg1(300, "Keyword = %s\n", lc->str);
         scan_err1(lc, "Keyword %s not found", lc->str);
         bsr = NULL;
         break;
      }
      if (!bsr) {
         break;
      }
   }
   lc = lex_close_file(lc);
   Dmsg0(300, "Leave parse_bsf()\n");
   if (!bsr) {
      free_bsr(root_bsr);
      root_bsr = NULL;
   }
   if (root_bsr) {
      root_bsr->use_fast_rejection = is_fast_rejection_ok(root_bsr);
      root_bsr->use_positioning = is_positioning_ok(root_bsr);
   }
   for (bsr=root_bsr; bsr; bsr=bsr->next) {
      bsr->root = root_bsr;
   }
   return root_bsr;
}
Beispiel #7
0
/* Parse a config file used by Plugin/Director */
bool ConfigFile::parse(const char *fname)
{
   int token, i;
   bool ret=false;

   if (!items) {
      return false;
   }

   if ((lc = lex_open_file(lc, fname, s_err, s_warn)) == NULL) {
      berrno be;
      Emsg2(M_ERROR, 0, _("Cannot open config file %s: %s\n"),
            fname, be.bstrerror());
      return false;
   }
   lc->options |= LOPT_NO_EXTERN;
   lc->caller_ctx = (void *)this;

   while ((token=lex_get_token(lc, T_ALL)) != T_EOF) {
      Dmsg1(dbglevel, "parse got token=%s\n", lex_tok_to_str(token));
      if (token == T_EOL) {
         continue;
      }
      for (i = 0; items[i].name; i++) {
         if (strcasecmp(items[i].name, lc->str) == 0) {
            if ((token = lex_get_token(lc, T_EQUALS)) == T_ERROR) {
               Dmsg1(dbglevel, "in T_IDENT got token=%s\n",
                     lex_tok_to_str(token));
               break;
            }

            Dmsg1(dbglevel, "calling handler for %s\n", items[i].name);
            /* Call item handler */
            ret = items[i].found = items[i].handler(lc, this, &items[i]);
            i = -1;
            break;
         }
      }
      if (i >= 0) {
         Dmsg1(dbglevel, "Keyword = %s\n", lc->str);
         scan_err1(lc, "Keyword %s not found", lc->str);
         /* We can raise an error here */
         break;
      }
      if (!ret) {
         break;
      }
   }

   for (i = 0; items[i].name; i++) {
      if (items[i].required && !items[i].found) {
         scan_err1(lc, "%s required but not found", items[i].name);
         ret = false;
      }
   }

   lc = lex_close_file(lc);

   return ret;
}
Beispiel #8
0
/*  SM_CHECK --  Check the buffers and dump if any damage exists. */
void sm_check(const char *fname, int lineno, bool bufdump)
{
   if (!sm_check_rtn(fname, lineno, bufdump)) {
      Emsg2(M_ABORT, 0, _("Damaged buffer found. Called from %s:%d\n"),
            get_basename(fname), (uint32_t)lineno);
   }
}
Beispiel #9
0
void _unlock_volumes()
{
   int errstat;
   vol_list_lock_count--;
   if ((errstat=rwl_writeunlock(&vol_list_lock)) != 0) {
      berrno be;
      Emsg2(M_ABORT, 0, "rwl_writeunlock failure. stat=%d: ERR=%s\n",
           errstat, be.bstrerror(errstat));
   }
}
Beispiel #10
0
static bool store_data(BFILE *bfd, char *data, const int32_t length)
{
   if (is_win32_stream(attr->data_stream) && !have_win32_api()) {
      set_portable_backup(bfd);
      if (!processWin32BackupAPIBlock(bfd, data, length)) {
         berrno be;
         Emsg2(M_ERROR_TERM, 0, _("Write error on %s: %s\n"),
               attr->ofname, be.bstrerror());
         return false;
      }
   } else if (bwrite(bfd, data, length) != (ssize_t)length) {
      berrno be;
      Emsg2(M_ERROR_TERM, 0, _("Write error on %s: %s\n"),
            attr->ofname, be.bstrerror());
      return false;
   }

   return true;
}
Beispiel #11
0
/*
 * This allows a given thread to recursively call to lock_volumes()
 */
void _lock_volumes(const char *file, int line)
{
   int errstat;
   vol_list_lock_count++;
   if ((errstat=rwl_writelock_p(&vol_list_lock, file, line)) != 0) {
      berrno be;
      Emsg2(M_ABORT, 0, "rwl_writelock failure. stat=%d: ERR=%s\n",
           errstat, be.bstrerror(errstat));
   }
}
Beispiel #12
0
static void do_extract(char *devname)
{
   struct stat statp;

   enable_backup_privileges(NULL, 1);

   jcr = setup_jcr("bextract", devname, bsr, director, VolumeName, 1); /* acquire for read */
   if (!jcr) {
      exit(1);
   }
   dev = jcr->read_dcr->dev;
   if (!dev) {
      exit(1);
   }
   dcr = jcr->read_dcr;

   /* Make sure where directory exists and that it is a directory */
   if (stat(where, &statp) < 0) {
      berrno be;
      Emsg2(M_ERROR_TERM, 0, _("Cannot stat %s. It must exist. ERR=%s\n"),
         where, be.bstrerror());
   }
   if (!S_ISDIR(statp.st_mode)) {
      Emsg1(M_ERROR_TERM, 0, _("%s must be a directory.\n"), where);
   }

   free(jcr->where);
   jcr->where = bstrdup(where);
   attr = new_attr(jcr);

   compress_buf = get_memory(compress_buf_size);

   acl_data.last_fname = get_pool_memory(PM_FNAME);
   xattr_data.last_fname = get_pool_memory(PM_FNAME);

   read_records(dcr, record_cb, mount_next_read_volume);
   /* If output file is still open, it was the last one in the
    * archive since we just hit an end of file, so close the file.
    */
   if (is_bopen(&bfd)) {
      set_attributes(jcr, attr, &bfd);
   }
   free_attr(attr);

   free_pool_memory(acl_data.last_fname);
   free_pool_memory(xattr_data.last_fname);

   clean_device(jcr->dcr);
   dev->term();
   free_dcr(dcr);
   free_jcr(jcr);

   printf(_("%u files restored.\n"), num_files);
   return;
}
void OUTPUT_FORMATTER::json_key_value_add(const char *key, const char *value)
{
   json_t *json_obj = NULL;

   json_obj = (json_t *)result_stack_json->last();
   if (json_obj != NULL) {
      json_object_set(json_obj, key, json_string(value));
   } else {
      Emsg2(M_ERROR, 0, "no json object defined to add %s: %s", key, value);
   }
}
Beispiel #14
0
/*
 * Write the content of the crypto cache to the filesystem.
 */
void write_crypto_cache(const char *cache_file)
{
   int fd;
   bool ok = false;
   crypto_cache_entry_t *cce;

   if (!cached_crypto_keys) {
      return;
   }

   /*
    * Lock the cache.
    */
   P(crypto_cache_lock);

   unlink(cache_file);
   if ((fd = open(cache_file, O_CREAT | O_WRONLY | O_BINARY, 0640)) < 0) {
      berrno be;

      Dmsg2(000, "Could not create crypto cache file. %s ERR=%s\n", cache_file, be.bstrerror());
      Emsg2(M_ERROR, 0, _("Could not create crypto cache file. %s ERR=%s\n"), cache_file, be.bstrerror());
      goto bail_out;
   }

   crypto_cache_hdr.nr_entries = cached_crypto_keys->size();
   if (write(fd, &crypto_cache_hdr, sizeof(crypto_cache_hdr)) != sizeof(crypto_cache_hdr)) {
      berrno be;

      Dmsg1(000, "Write hdr error: ERR=%s\n", be.bstrerror());
      goto bail_out;
   }

   foreach_dlist(cce, cached_crypto_keys) {
      if (write(fd, cce, sizeof(crypto_cache_entry_t)) != sizeof(crypto_cache_entry_t)) {
         berrno be;

         Dmsg1(000, "Write record error: ERR=%s\n", be.bstrerror());
         goto bail_out;
      }
   }

   ok = true;

bail_out:
   if (fd >= 0) {
      close(fd);
   }

   if (!ok) {
      unlink(cache_file);
   }

   V(crypto_cache_lock);
}
Beispiel #15
0
void write_state_file(char *dir, const char *progname, int port)
{
   int sfd;
   bool ok = false;
   POOLMEM *fname = get_pool_memory(PM_FNAME);

   P(state_mutex);                    /* Only one job at a time can call here */
   Mmsg(&fname, "%s/%s.%d.state", dir, progname, port);
   /* Create new state file */
   unlink(fname);
   if ((sfd = open(fname, O_CREAT|O_WRONLY|O_BINARY, 0640)) < 0) {
      berrno be;
      Dmsg2(000, "Could not create state file. %s ERR=%s\n", fname, be.bstrerror());
      Emsg2(M_ERROR, 0, _("Could not create state file. %s ERR=%s\n"), fname, be.bstrerror());
      goto bail_out;
   }
   if (write(sfd, &state_hdr, sizeof(state_hdr)) != sizeof(state_hdr)) {
      berrno be;
      Dmsg1(000, "Write hdr error: ERR=%s\n", be.bstrerror());
      goto bail_out;
   }
// Dmsg1(010, "Wrote header of %d bytes\n", sizeof(state_hdr));
   state_hdr.last_jobs_addr = sizeof(state_hdr);
   state_hdr.reserved[0] = write_last_jobs_list(sfd, state_hdr.last_jobs_addr);
// Dmsg1(010, "write last job end = %d\n", (int)state_hdr.reserved[0]);
   if (lseek(sfd, 0, SEEK_SET) < 0) {
      berrno be;
      Dmsg1(000, "lseek error: ERR=%s\n", be.bstrerror());
      goto bail_out;
   }
   if (write(sfd, &state_hdr, sizeof(state_hdr)) != sizeof(state_hdr)) {
      berrno be;
      Pmsg1(000, _("Write final hdr error: ERR=%s\n"), be.bstrerror());
      goto bail_out;
   }
   ok = true;
// Dmsg1(010, "rewrote header = %d\n", sizeof(state_hdr));
bail_out:
   if (sfd >= 0) {
      close(sfd);
   }
   if (!ok) {
      unlink(fname);
   }
   V(state_mutex);
   free_pool_memory(fname);
}
Beispiel #16
0
/*
 * Connection request. We accept connections either from the
 * Director, Storage Daemon or a Client (File daemon).
 *
 * Note, we are running as a seperate thread of the Storage daemon.
 *
 * Basic tasks done here:
 *  - If it was a connection from the FD, call handle_filed_connection()
 *  - If it was a connection from another SD, call handle_stored_connection()
 *  - Otherwise it was a connection from the DIR, call handle_director_connection()
 */
static void *handle_connection_request(void *arg)
{
   BSOCK *bs = (BSOCK *)arg;
   char name[MAX_NAME_LENGTH];
   char tbuf[MAX_TIME_LENGTH];

   if (bs->recv() <= 0) {
      Emsg1(M_ERROR, 0, _("Connection request from %s failed.\n"), bs->who());
      bmicrosleep(5, 0);   /* make user wait 5 seconds */
      bs->close();
      return NULL;
   }

   /*
    * Do a sanity check on the message received
    */
   if (bs->msglen < MIN_MSG_LEN || bs->msglen > MAX_MSG_LEN) {
      Dmsg1(000, "<filed: %s", bs->msg);
      Emsg2(M_ERROR, 0, _("Invalid connection from %s. Len=%d\n"), bs->who(), bs->msglen);
      bmicrosleep(5, 0);   /* make user wait 5 seconds */
      bs->close();
      return NULL;
   }

   Dmsg1(110, "Conn: %s", bs->msg);

   /*
    * See if this is a File daemon connection. If so call FD handler.
    */
   if (sscanf(bs->msg, "Hello Start Job %127s", name) == 1) {
      Dmsg1(110, "Got a FD connection at %s\n", bstrftimes(tbuf, sizeof(tbuf), (utime_t)time(NULL)));
      return handle_filed_connection(bs, name);
   }

   /*
    * See if this is a Storage daemon connection. If so call SD handler.
    */
   if (sscanf(bs->msg, "Hello Start Storage Job %127s", name) == 1) {
      Dmsg1(110, "Got a SD connection at %s\n", bstrftimes(tbuf, sizeof(tbuf), (utime_t)time(NULL)));
      return handle_stored_connection(bs, name);
   }

   Dmsg1(110, "Got a DIR connection at %s\n", bstrftimes(tbuf, sizeof(tbuf), (utime_t)time(NULL)));

   return handle_director_connection(bs);
}
Beispiel #17
0
/*
 * Called here for each record from read_records()
 */
static bool record_cb(DCR *dcr, DEV_RECORD *rec)
{
    if (rec->FileIndex < 0) {
        get_session_record(dev, rec, &sessrec);
        return true;
    }
    /* File Attributes stream */
    if (rec->Stream == STREAM_UNIX_ATTRIBUTES ||
            rec->Stream == STREAM_UNIX_ATTRIBUTES_EX) {

        if (!unpack_attributes_record(jcr, rec->Stream, rec->data, attr)) {
            if (!forge_on) {
                Emsg0(M_ERROR_TERM, 0, _("Cannot continue.\n"));
            }
            num_files++;
            return true;
        }

        if (attr->file_index != rec->FileIndex) {
            Emsg2(forge_on?M_WARNING:M_ERROR_TERM, 0, _("Record header file index %ld not equal record index %ld\n"),
                  rec->FileIndex, attr->file_index);
        }

        attr->data_stream = decode_stat(attr->attr, &attr->statp, &attr->LinkFI);
        build_attr_output_fnames(jcr, attr);

        if (file_is_included(ff, attr->fname) && !file_is_excluded(ff, attr->fname)) {
            if (verbose) {
                Pmsg5(-1, _("FileIndex=%d VolSessionId=%d VolSessionTime=%d Stream=%d DataLen=%d\n"),
                      rec->FileIndex, rec->VolSessionId, rec->VolSessionTime, rec->Stream, rec->data_len);
            }
            print_ls_output(jcr, attr);
            num_files++;
        }
    } else if (rec->Stream == STREAM_PLUGIN_NAME) {
        if (strncmp("0 0", rec->data, 3) != 0) {
            Pmsg1(000, "Plugin data: %s\n", rec->data);
        }
    }

    return true;
}
Beispiel #18
0
/*
 * Become Threaded Network Server
 *
 * This function is able to handle multiple server ips in
 * ipv4 and ipv6 style. The Addresse are give in a comma
 * seperated string in bind_addr
 *
 * At the moment it is impossible to bind to different ports.
 */
void bnet_thread_server(dlist *addr_list, int max_clients, alist *sockfds,
                        workq_t *client_wq, void *handle_client_request(void *bsock))
{
   int newsockfd, status;
   socklen_t clilen;
   struct sockaddr cli_addr;       /* client's address */
   int tlog, tmax;
   int turnon = 1;
#ifdef HAVE_LIBWRAP
   struct request_info request;
#endif
   IPADDR *ipaddr, *next;
   s_sockfd *fd_ptr = NULL;
   char buf[128];
#ifdef HAVE_POLL
   nfds_t nfds;
   struct pollfd *pfds;
#endif

   char allbuf[256 * 10];

   /*
    * Remove any duplicate addresses.
    */
   for (ipaddr = (IPADDR *)addr_list->first(); ipaddr;
        ipaddr = (IPADDR *)addr_list->next(ipaddr)) {
      for (next = (IPADDR *)addr_list->next(ipaddr); next;
           next = (IPADDR *)addr_list->next(next)) {
         if (ipaddr->get_sockaddr_len() == next->get_sockaddr_len() &&
             memcmp(ipaddr->get_sockaddr(), next->get_sockaddr(),
                    ipaddr->get_sockaddr_len()) == 0) {
            addr_list->remove(next);
         }
      }
   }

   Dmsg1(100, "Addresses %s\n", build_addresses_str(addr_list, allbuf, sizeof(allbuf)));

#ifdef HAVE_POLL
   nfds = 0;
#endif
   foreach_dlist(ipaddr, addr_list) {
      /*
       * Allocate on stack from -- no need to free
       */
      fd_ptr = (s_sockfd *)alloca(sizeof(s_sockfd));
      fd_ptr->port = ipaddr->get_port_net_order();

      /*
       * Open a TCP socket
       */
      for (tlog= 60; (fd_ptr->fd=socket(ipaddr->get_family(), SOCK_STREAM, 0)) < 0; tlog -= 10) {
         if (tlog <= 0) {
            berrno be;
            char curbuf[256];
            Emsg3(M_ABORT, 0, _("Cannot open stream socket. ERR=%s. Current %s All %s\n"),
                       be.bstrerror(),
                       ipaddr->build_address_str(curbuf, sizeof(curbuf)),
                       build_addresses_str(addr_list, allbuf, sizeof(allbuf)));
         }
         bmicrosleep(10, 0);
      }

      /*
       * Reuse old sockets
       */
      if (setsockopt(fd_ptr->fd, SOL_SOCKET, SO_REUSEADDR, (sockopt_val_t)&turnon,
           sizeof(turnon)) < 0) {
         berrno be;
         Emsg1(M_WARNING, 0, _("Cannot set SO_REUSEADDR on socket: %s\n"),
               be.bstrerror());
      }

      tmax = 30 * (60 / 5);        /* wait 30 minutes max */
      for (tlog = 0; bind(fd_ptr->fd, ipaddr->get_sockaddr(), ipaddr->get_sockaddr_len()) < 0; tlog -= 5) {
         berrno be;
         if (tlog <= 0) {
            tlog = 2 * 60;         /* Complain every 2 minutes */
            Emsg2(M_WARNING, 0, _("Cannot bind port %d: ERR=%s: Retrying ...\n"),
                  ntohs(fd_ptr->port), be.bstrerror());
         }
         bmicrosleep(5, 0);
         if (--tmax <= 0) {
            Emsg2(M_ABORT, 0, _("Cannot bind port %d: ERR=%s.\n"), ntohs(fd_ptr->port),
                  be.bstrerror());
         }
      }

      listen(fd_ptr->fd, 50);      /* tell system we are ready */
      sockfds->append(fd_ptr);

#ifdef HAVE_POLL
      nfds++;
#endif
   }
Beispiel #19
0
int main (int argc, char *argv[])
{
   int ch;
   bool no_signals = false;
   bool test_config = false;
   pthread_t thid;
   char *uid = NULL;
   char *gid = NULL;

   start_heap = sbrk(0);
   setlocale(LC_ALL, "");
   bindtextdomain("bareos", LOCALEDIR);
   textdomain("bareos");

   init_stack_dump();
   my_name_is(argc, argv, "bareos-sd");
   init_msg(NULL, NULL);
   daemon_start_time = time(NULL);

   /* Sanity checks */
   if (TAPE_BSIZE % B_DEV_BSIZE != 0 || TAPE_BSIZE / B_DEV_BSIZE == 0) {
      Emsg2(M_ABORT, 0, _("Tape block size (%d) not multiple of system size (%d)\n"),
         TAPE_BSIZE, B_DEV_BSIZE);
   }
   if (TAPE_BSIZE != (1 << (ffs(TAPE_BSIZE)-1))) {
      Emsg1(M_ABORT, 0, _("Tape block size (%d) is not a power of 2\n"), TAPE_BSIZE);
   }

   while ((ch = getopt(argc, argv, "c:d:fg:mpstu:v?")) != -1) {
      switch (ch) {
      case 'c':                    /* configuration file */
         if (configfile != NULL) {
            free(configfile);
         }
         configfile = bstrdup(optarg);
         break;

      case 'd':                    /* debug level */
         if (*optarg == 't') {
            dbg_timestamp = true;
         } else {
            debug_level = atoi(optarg);
            if (debug_level <= 0) {
               debug_level = 1;
            }
         }
         break;

      case 'f':                    /* run in foreground */
         foreground = true;
         break;

      case 'g':                    /* set group id */
         gid = optarg;
         break;

      case 'm':                    /* print kaboom output */
         prt_kaboom = true;
         break;

      case 'p':                    /* proceed in spite of I/O errors */
         forge_on = true;
         break;

      case 's':                    /* no signals */
         no_signals = true;
         break;

      case 't':
         test_config = true;
         break;

      case 'u':                    /* set uid */
         uid = optarg;
         break;

      case 'v':                    /* verbose */
         verbose++;
         break;

      case '?':
      default:
         usage();
         break;
      }
   }
   argc -= optind;
   argv += optind;

   if (argc) {
      if (configfile != NULL) {
         free(configfile);
      }
      configfile = bstrdup(*argv);
      argc--;
      argv++;
   }
   if (argc)
      usage();

   /*
    * See if we want to drop privs.
    */
   if (geteuid() == 0) {
      drop(uid, gid, false);
   }

   if (!no_signals) {
      init_signals(terminate_stored);
   }

   if (configfile == NULL) {
      configfile = bstrdup(CONFIG_FILE);
   }

   my_config = new_config_parser();
   parse_sd_config(my_config, configfile, M_ERROR_TERM);

   if (init_crypto() != 0) {
      Jmsg((JCR *)NULL, M_ERROR_TERM, 0, _("Cryptography library initialization failed.\n"));
   }

   if (!check_resources()) {
      Jmsg((JCR *)NULL, M_ERROR_TERM, 0, _("Please correct configuration file: %s\n"), configfile);
   }

   init_reservations_lock();

   if (test_config) {
      terminate_stored(0);
   }

   my_name_is(0, (char **)NULL, me->hdr.name);     /* Set our real name */

   if (!foreground) {
      daemon_start();                 /* become daemon */
      init_stack_dump();              /* pick up new pid */
   }

   create_pid_file(me->pid_directory, "bareos-sd",
                   get_first_port_host_order(me->SDaddrs));
   read_state_file(me->working_directory, "bareos-sd",
                   get_first_port_host_order(me->SDaddrs));
   read_crypto_cache(me->working_directory, "bareos-sd",
                     get_first_port_host_order(me->SDaddrs));

   set_jcr_in_tsd(INVALID_JCR);

   /*
    * Make sure on Solaris we can run concurrent, watch dog + servers + misc
    */
   set_thread_concurrency(me->max_concurrent_jobs * 2 + 4);
   lmgr_init_thread(); /* initialize the lockmanager stack */

   load_sd_plugins(me->plugin_directory, me->plugin_names);

   cleanup_old_files();

   /* Ensure that Volume Session Time and Id are both
    * set and are both non-zero.
    */
   VolSessionTime = (uint32_t)daemon_start_time;
   if (VolSessionTime == 0) { /* paranoid */
      Jmsg0(NULL, M_ABORT, 0, _("Volume Session Time is ZERO!\n"));
   }

   /*
    * Start the device allocation thread
    */
   create_volume_lists();             /* do before device_init */
   if (pthread_create(&thid, NULL, device_initialization, NULL) != 0) {
      berrno be;
      Emsg1(M_ABORT, 0, _("Unable to create thread. ERR=%s\n"), be.bstrerror());
   }

   start_watchdog();                  /* start watchdog thread */
   if (me->jcr_watchdog_time) {
      init_jcr_subsystem(me->jcr_watchdog_time); /* start JCR watchdogs etc. */
   }

#if HAVE_NDMP
   /* Seperate thread that handles NDMP connections */
   if (me->ndmp_enable) {
      start_ndmp_thread_server(me->NDMPaddrs,
                               me->max_concurrent_jobs * 2 + 1,
                               &ndmp_workq);
   }
#endif

   /* Single server used for Director/Storage and File daemon */
   sock_fds = New(alist(10, not_owned_by_alist));
   bnet_thread_server_tcp(me->SDaddrs,
                      me->max_concurrent_jobs * 2 + 1,
                      sock_fds,
                      &dird_workq,
                      me->nokeepalive,
                      handle_connection_request);
   exit(1);                           /* to keep compiler quiet */
}
Beispiel #20
0
/*
 * Save the new resource by chaining it into the head list for
 * the resource. If this is pass 2, we update any resource
 * pointers (currently only in the Job resource).
 */
void save_resource(int type, RES_ITEM *items, int pass)
{
   URES *res;
   int rindex = type - r_first;
   int i, size = 0;
   int error = 0;

   /*
    * Ensure that all required items are present
    */
   for (i=0; items[i].name; i++) {
      if (items[i].flags & ITEM_REQUIRED) {
            if (!bit_is_set(i, res_all.dir_res.hdr.item_present)) {
               Emsg2(M_ABORT, 0, _("%s item is required in %s resource, but not found.\n"),
                 items[i].name, resources[rindex]);
             }
      }
   }

   /*
    * During pass 2, we looked up pointers to all the resources
    * referrenced in the current resource, , now we
    * must copy their address from the static record to the allocated
    * record.
    */
   if (pass == 2) {
      switch (type) {
      /*
       * Resources not containing a resource
       */
      case R_DIRECTOR:
         break;

      case R_CONSOLE:
      case R_CONSOLE_FONT:
         break;

      default:
         Emsg1(M_ERROR, 0, _("Unknown resource type %d\n"), type);
         error = 1;
         break;
      }
      /*
       * Note, the resoure name was already saved during pass 1,
       * so here, we can just release it.
       */
      if (res_all.dir_res.hdr.name) {
         free(res_all.dir_res.hdr.name);
         res_all.dir_res.hdr.name = NULL;
      }
      if (res_all.dir_res.hdr.desc) {
         free(res_all.dir_res.hdr.desc);
         res_all.dir_res.hdr.desc = NULL;
      }
      return;
   }

   /*
    * The following code is only executed during pass 1
    */
   switch (type) {
   case R_DIRECTOR:
      size = sizeof(DIRRES);
      break;
   case R_CONSOLE_FONT:
      size = sizeof(CONFONTRES);
      break;
   case R_CONSOLE:
      size = sizeof(CONRES);
      break;
   default:
      printf(_("Unknown resource type %d\n"), type);
      error = 1;
      break;
   }
   /*
    * Common
    */
   if (!error) {
      res = (URES *)malloc(size);
      memcpy(res, &res_all, size);
      if (!res_head[rindex]) {
         res_head[rindex] = (RES *)res; /* store first entry */
      } else {
         RES *next, *last;
         /*
          * Add new res to end of chain
          */
         for (last=next=res_head[rindex]; next; next=next->next) {
            last = next;
            if (strcmp(next->name, res->dir_res.hdr.name) == 0) {
               Emsg2(M_ERROR_TERM, 0,
                  _("Attempt to define second %s resource named \"%s\" is not permitted.\n"),
                  resources[rindex].name, res->dir_res.hdr.name);
            }
         }
         last->next = (RES *)res;
         Dmsg2(90, "Inserting %s res: %s\n", res_to_str(type),
               res->dir_res.hdr.name);
      }
   }
}
Beispiel #21
0
Datei: bls.c Projekt: AlD/bareos
int main (int argc, char *argv[])
{
   int i, ch;
   FILE *fd;
   char line[1000];
   char *VolumeName = NULL;
   char *bsrName = NULL;
   char *DirectorName = NULL;
   bool ignore_label_errors = false;
   DIRRES *director = NULL;

   setlocale(LC_ALL, "");
   bindtextdomain("bareos", LOCALEDIR);
   textdomain("bareos");
   init_stack_dump();
   lmgr_init_thread();

   working_directory = "/tmp";
   my_name_is(argc, argv, "bls");
   init_msg(NULL, NULL);              /* initialize message handler */

   OSDependentInit();

   ff = init_find_files();

   while ((ch = getopt(argc, argv, "b:c:D:d:e:i:jkLpvV:?")) != -1) {
      switch (ch) {
      case 'b':
         bsrName = optarg;
         break;

      case 'c':                    /* specify config file */
         if (configfile != NULL) {
            free(configfile);
         }
         configfile = bstrdup(optarg);
         break;

      case 'D':                    /* specify director name */
         if (DirectorName != NULL) {
            free(DirectorName);
         }
         DirectorName = bstrdup(optarg);
         break;

      case 'd':                    /* debug level */
         if (*optarg == 't') {
            dbg_timestamp = true;
         } else {
            debug_level = atoi(optarg);
            if (debug_level <= 0) {
               debug_level = 1;
            }
         }
         break;

      case 'e':                    /* exclude list */
         if ((fd = fopen(optarg, "rb")) == NULL) {
            berrno be;
            Pmsg2(0, _("Could not open exclude file: %s, ERR=%s\n"),
               optarg, be.bstrerror());
            exit(1);
         }
         while (fgets(line, sizeof(line), fd) != NULL) {
            strip_trailing_junk(line);
            Dmsg1(100, "add_exclude %s\n", line);
            add_fname_to_exclude_list(ff, line);
         }
         fclose(fd);
         break;

      case 'i':                    /* include list */
         if ((fd = fopen(optarg, "rb")) == NULL) {
            berrno be;
            Pmsg2(0, _("Could not open include file: %s, ERR=%s\n"),
               optarg, be.bstrerror());
            exit(1);
         }
         while (fgets(line, sizeof(line), fd) != NULL) {
            strip_trailing_junk(line);
            Dmsg1(100, "add_include %s\n", line);
            add_fname_to_include_list(ff, 0, line);
         }
         fclose(fd);
         break;

      case 'j':
         list_jobs = true;
         break;

      case 'k':
         list_blocks = true;
         break;

      case 'L':
         dump_label = true;
         break;

      case 'p':
         ignore_label_errors = true;
         forge_on = true;
         break;

      case 'v':
         verbose++;
         break;

      case 'V':                    /* Volume name */
         VolumeName = optarg;
         break;

      case '?':
      default:
         usage();

      } /* end switch */
   } /* end while */
   argc -= optind;
   argv += optind;

   if (!argc) {
      Pmsg0(0, _("No archive name specified\n"));
      usage();
   }

   if (configfile == NULL) {
      configfile = bstrdup(CONFIG_FILE);
   }

   my_config = new_config_parser();
   parse_sd_config(my_config, configfile, M_ERROR_TERM);

   LockRes();
   me = (STORES *)GetNextRes(R_STORAGE, NULL);
   if (!me) {
      UnlockRes();
      Emsg1(M_ERROR_TERM, 0, _("No Storage resource defined in %s. Cannot continue.\n"),
            configfile);
   }
   UnlockRes();

  if (DirectorName) {
      foreach_res(director, R_DIRECTOR) {
         if (bstrcmp(director->hdr.name, DirectorName)) {
            break;
         }
      }
      if (!director) {
         Emsg2(M_ERROR_TERM, 0, _("No Director resource named %s defined in %s. Cannot continue.\n"),
               DirectorName, configfile);
      }
   }

   load_sd_plugins(me->plugin_directory, me->plugin_names);

   read_crypto_cache(me->working_directory, "bareos-sd",
                     get_first_port_host_order(me->SDaddrs));

   if (ff->included_files_list == NULL) {
      add_fname_to_include_list(ff, 0, "/");
   }

   for (i=0; i < argc; i++) {
      if (bsrName) {
         bsr = parse_bsr(NULL, bsrName);
      }
      jcr = setup_jcr("bls", argv[i], bsr, director, VolumeName, 1); /* acquire for read */
      if (!jcr) {
         exit(1);
      }
      jcr->ignore_label_errors = ignore_label_errors;
      dev = jcr->dcr->dev;
      if (!dev) {
         exit(1);
      }
      dcr = jcr->dcr;
      rec = new_record();
      attr = new_attr(jcr);
      /*
       * Assume that we have already read the volume label.
       * If on second or subsequent volume, adjust buffer pointer
       */
      if (dev->VolHdr.PrevVolumeName[0] != 0) { /* second volume */
         Pmsg1(0, _("\n"
                    "Warning, this Volume is a continuation of Volume %s\n"),
                dev->VolHdr.PrevVolumeName);
      }

      if (list_blocks) {
         do_blocks(argv[i]);
      } else if (list_jobs) {
         do_jobs(argv[i]);
      } else {
         do_ls(argv[i]);
      }
      do_close(jcr);
   }
   if (bsr) {
      free_bsr(bsr);
   }
   term_include_exclude_files(ff);
   term_find_files(ff);
   return 0;
}
Beispiel #22
0
/*
 * Save the new resource by chaining it into the head list for
 * the resource. If this is pass 2, we update any resource
 * pointers because they may not have been defined until
 * later in pass 1.
 */
void save_resource(int type, RES_ITEM *items, int pass)
{
   URES *res;
   int rindex = type - R_FIRST;
   int i;
   int error = 0;

   /*
    * Ensure that all required items are present
    */
   for (i = 0; items[i].name; i++) {
      if (items[i].flags & CFG_ITEM_REQUIRED) {
         if (!bit_is_set(i, res_all.res_monitor.hdr.item_present)) {
               Emsg2(M_ERROR_TERM, 0, _("%s item is required in %s resource, but not found.\n"),
                  items[i].name, resources[rindex]);
         }
      }
      /* If this triggers, take a look at lib/parse_conf.h */
      if (i >= MAX_RES_ITEMS) {
         Emsg1(M_ERROR_TERM, 0, _("Too many items in %s resource\n"), resources[rindex]);
      }
   }

   /*
    * During pass 2 in each "store" routine, we looked up pointers
    * to all the resources referrenced in the current resource, now we
    * must copy their addresses from the static record to the allocated
    * record.
    */
   if (pass == 2) {
      switch (type) {
      /*
       * Resources not containing a resource
       */
      case R_MONITOR:
      case R_CLIENT:
      case R_STORAGE:
      case R_DIRECTOR:
      case R_CONSOLE_FONT:
         break;
      default:
         Emsg1(M_ERROR, 0, _("Unknown resource type %d in save_resource.\n"), type);
         error = 1;
         break;
      }
      /*
       * Note, the resource name was already saved during pass 1,
       * so here, we can just release it.
       */
      if (res_all.res_monitor.hdr.name) {
         free(res_all.res_monitor.hdr.name);
         res_all.res_monitor.hdr.name = NULL;
      }
      if (res_all.res_monitor.hdr.desc) {
         free(res_all.res_monitor.hdr.desc);
         res_all.res_monitor.hdr.desc = NULL;
      }
      return;
   }

   /*
    * Common
    */
   if (!error) {
      res = (URES *)malloc(resources[rindex].size);
      memcpy(res, &res_all, resources[rindex].size);
      if (!res_head[rindex]) {
        res_head[rindex] = (RES *)res; /* store first entry */
         Dmsg3(900, "Inserting first %s res: %s index=%d\n", res_to_str(type),
         res->res_monitor.hdr.name, rindex);
      } else {
         RES *next, *last;
         /*
          * Add new res to end of chain
          */
         for (last = next = res_head[rindex]; next; next=next->next) {
            last = next;
            if (strcmp(next->name, res->res_monitor.hdr.name) == 0) {
               Emsg2(M_ERROR_TERM, 0,
                     _("Attempt to define second %s resource named \"%s\" is not permitted.\n"),
               resources[rindex].name, res->res_monitor.hdr.name);
            }
         }
         last->next = (RES *)res;
         Dmsg4(900, "Inserting %s res: %s index=%d pass=%d\n", res_to_str(type),
         res->res_monitor.hdr.name, rindex, pass);
      }
   }
}
Beispiel #23
0
/*
 * Called here for each record from read_records()
 */
static bool record_cb(DCR *dcr, DEV_RECORD *rec)
{
   int status;
   JCR *jcr = dcr->jcr;

   if (rec->FileIndex < 0) {
      return true;                    /* we don't want labels */
   }

   /* File Attributes stream */

   switch (rec->maskedStream) {
   case STREAM_UNIX_ATTRIBUTES:
   case STREAM_UNIX_ATTRIBUTES_EX:

      /* If extracting, it was from previous stream, so
       * close the output file.
       */
      if (extract) {
         if (!is_bopen(&bfd)) {
            Emsg0(M_ERROR, 0, _("Logic error output file should be open but is not.\n"));
         }
         set_attributes(jcr, attr, &bfd);
         extract = false;
      }

      if (!unpack_attributes_record(jcr, rec->Stream, rec->data, rec->data_len, attr)) {
         Emsg0(M_ERROR_TERM, 0, _("Cannot continue.\n"));
      }

      if (file_is_included(ff, attr->fname) && !file_is_excluded(ff, attr->fname)) {
         attr->data_stream = decode_stat(attr->attr, &attr->statp, sizeof(attr->statp), &attr->LinkFI);
         if (!is_restore_stream_supported(attr->data_stream)) {
            if (!non_support_data++) {
               Jmsg(jcr, M_ERROR, 0, _("%s stream not supported on this Client.\n"),
                  stream_to_ascii(attr->data_stream));
            }
            extract = false;
            return true;
         }

         build_attr_output_fnames(jcr, attr);

         if (attr->type == FT_DELETED) { /* TODO: choose the right fname/ofname */
            Jmsg(jcr, M_INFO, 0, _("%s was deleted.\n"), attr->fname);
            extract = false;
            return true;
         }

         extract = false;
         status = create_file(jcr, attr, &bfd, REPLACE_ALWAYS);
         switch (status) {
         case CF_ERROR:
         case CF_SKIP:
            break;
         case CF_EXTRACT:
            extract = true;
            print_ls_output(jcr, attr);
            num_files++;
            fileAddr = 0;
            break;
         case CF_CREATED:
            set_attributes(jcr, attr, &bfd);
            print_ls_output(jcr, attr);
            num_files++;
            fileAddr = 0;
            break;
         }
      }
      break;

   case STREAM_RESTORE_OBJECT:
      /* nothing to do */
      break;

   /* Data stream and extracting */
   case STREAM_FILE_DATA:
   case STREAM_SPARSE_DATA:
   case STREAM_WIN32_DATA:

      if (extract) {
         if (rec->maskedStream == STREAM_SPARSE_DATA) {
            ser_declare;
            uint64_t faddr;
            wbuf = rec->data + OFFSET_FADDR_SIZE;
            wsize = rec->data_len - OFFSET_FADDR_SIZE;
            ser_begin(rec->data, OFFSET_FADDR_SIZE);
            unser_uint64(faddr);
            if (fileAddr != faddr) {
               fileAddr = faddr;
               if (blseek(&bfd, (boffset_t)fileAddr, SEEK_SET) < 0) {
                  berrno be;
                  Emsg2(M_ERROR_TERM, 0, _("Seek error on %s: %s\n"),
                     attr->ofname, be.bstrerror());
               }
            }
         } else {
            wbuf = rec->data;
            wsize = rec->data_len;
         }
         total += wsize;
         Dmsg2(8, "Write %u bytes, total=%u\n", wsize, total);
         store_data(&bfd, wbuf, wsize);
         fileAddr += wsize;
      }
      break;

   /* GZIP data stream */
   case STREAM_GZIP_DATA:
   case STREAM_SPARSE_GZIP_DATA:
   case STREAM_WIN32_GZIP_DATA:
#ifdef HAVE_LIBZ
      if (extract) {
         uLong compress_len = compress_buf_size;
         int status = Z_BUF_ERROR;

         if (rec->maskedStream == STREAM_SPARSE_GZIP_DATA) {
            ser_declare;
            uint64_t faddr;
            char ec1[50];
            wbuf = rec->data + OFFSET_FADDR_SIZE;
            wsize = rec->data_len - OFFSET_FADDR_SIZE;
            ser_begin(rec->data, OFFSET_FADDR_SIZE);
            unser_uint64(faddr);
            if (fileAddr != faddr) {
               fileAddr = faddr;
               if (blseek(&bfd, (boffset_t)fileAddr, SEEK_SET) < 0) {
                  berrno be;
                  Emsg3(M_ERROR, 0, _("Seek to %s error on %s: ERR=%s\n"),
                     edit_uint64(fileAddr, ec1), attr->ofname, be.bstrerror());
                  extract = false;
                  return true;
               }
            }
         } else {
            wbuf = rec->data;
            wsize = rec->data_len;
         }

         while (compress_len < 10000000 && (status = uncompress((Byte *)compress_buf, &compress_len,
                                 (const Byte *)wbuf, (uLong)wsize)) == Z_BUF_ERROR) {
            /* The buffer size is too small, try with a bigger one */
            compress_len = 2 * compress_len;
            compress_buf = check_pool_memory_size(compress_buf,
                                                  compress_len);
         }
         if (status != Z_OK) {
            Emsg1(M_ERROR, 0, _("Uncompression error. ERR=%d\n"), status);
            extract = false;
            return true;
         }

         Dmsg2(100, "Write uncompressed %d bytes, total before write=%d\n", compress_len, total);
         store_data(&bfd, compress_buf, compress_len);
         total += compress_len;
         fileAddr += compress_len;
         Dmsg2(100, "Compress len=%d uncompressed=%d\n", rec->data_len,
            compress_len);
      }
#else
      if (extract) {
         Emsg0(M_ERROR, 0, _("GZIP data stream found, but GZIP not configured!\n"));
         extract = false;
         return true;
      }
#endif
      break;

   /* Compressed data stream */
   case STREAM_COMPRESSED_DATA:
   case STREAM_SPARSE_COMPRESSED_DATA:
   case STREAM_WIN32_COMPRESSED_DATA:
      if (extract) {
         uint32_t comp_magic, comp_len;
         uint16_t comp_level, comp_version;
#ifdef HAVE_LZO
         lzo_uint compress_len;
         const unsigned char *cbuf;
         int r, real_compress_len;
#endif

         if (rec->maskedStream == STREAM_SPARSE_COMPRESSED_DATA) {
            ser_declare;
            uint64_t faddr;
            char ec1[50];
            wbuf = rec->data + OFFSET_FADDR_SIZE;
            wsize = rec->data_len - OFFSET_FADDR_SIZE;
            ser_begin(rec->data, OFFSET_FADDR_SIZE);
            unser_uint64(faddr);
            if (fileAddr != faddr) {
               fileAddr = faddr;
               if (blseek(&bfd, (boffset_t)fileAddr, SEEK_SET) < 0) {
                  berrno be;
                  Emsg3(M_ERROR, 0, _("Seek to %s error on %s: ERR=%s\n"),
                     edit_uint64(fileAddr, ec1), attr->ofname, be.bstrerror());
                  extract = false;
                  return true;
               }
            }
         } else {
            wbuf = rec->data;
            wsize = rec->data_len;
         }

         /* read compress header */
         unser_declare;
         unser_begin(wbuf, sizeof(comp_stream_header));
         unser_uint32(comp_magic);
         unser_uint32(comp_len);
         unser_uint16(comp_level);
         unser_uint16(comp_version);
         Dmsg4(200, "Compressed data stream found: magic=0x%x, len=%d, level=%d, ver=0x%x\n", comp_magic, comp_len,
                                 comp_level, comp_version);

         /* version check */
         if (comp_version != COMP_HEAD_VERSION) {
            Emsg1(M_ERROR, 0, _("Compressed header version error. version=0x%x\n"), comp_version);
            return false;
         }
         /* size check */
         if (comp_len + sizeof(comp_stream_header) != wsize) {
            Emsg2(M_ERROR, 0, _("Compressed header size error. comp_len=%d, msglen=%d\n"),
                 comp_len, wsize);
            return false;
         }

          switch(comp_magic) {
#ifdef HAVE_LZO
            case COMPRESS_LZO1X:
               compress_len = compress_buf_size;
               cbuf = (const unsigned char*) wbuf + sizeof(comp_stream_header);
               real_compress_len = wsize - sizeof(comp_stream_header);
               Dmsg2(200, "Comp_len=%d msglen=%d\n", compress_len, wsize);
               while ((r=lzo1x_decompress_safe(cbuf, real_compress_len,
                                               (unsigned char *)compress_buf, &compress_len, NULL)) == LZO_E_OUTPUT_OVERRUN)
               {

                  /* The buffer size is too small, try with a bigger one */
                  compress_len = 2 * compress_len;
                  compress_buf = check_pool_memory_size(compress_buf,
                                                  compress_len);
               }
               if (r != LZO_E_OK) {
                  Emsg1(M_ERROR, 0, _("LZO uncompression error. ERR=%d\n"), r);
                  extract = false;
                  return true;
               }
               Dmsg2(100, "Write uncompressed %d bytes, total before write=%d\n", compress_len, total);
               store_data(&bfd, compress_buf, compress_len);
               total += compress_len;
               fileAddr += compress_len;
               Dmsg2(100, "Compress len=%d uncompressed=%d\n", rec->data_len, compress_len);
               break;
#endif
            default:
               Emsg1(M_ERROR, 0, _("Compression algorithm 0x%x found, but not supported!\n"), comp_magic);
               extract = false;
               return true;
         }

      }
      break;

   case STREAM_MD5_DIGEST:
   case STREAM_SHA1_DIGEST:
   case STREAM_SHA256_DIGEST:
   case STREAM_SHA512_DIGEST:
      break;

   case STREAM_SIGNED_DIGEST:
   case STREAM_ENCRYPTED_SESSION_DATA:
      // TODO landonf: Investigate crypto support in the storage daemon
      break;

   case STREAM_PROGRAM_NAMES:
   case STREAM_PROGRAM_DATA:
      if (!prog_name_msg) {
         Pmsg0(000, _("Got Program Name or Data Stream. Ignored.\n"));
         prog_name_msg++;
      }
      break;

   case STREAM_UNIX_ACCESS_ACL:          /* Deprecated Standard ACL attributes on UNIX */
   case STREAM_UNIX_DEFAULT_ACL:         /* Deprecated Default ACL attributes on UNIX */
   case STREAM_ACL_AIX_TEXT:
   case STREAM_ACL_DARWIN_ACCESS_ACL:
   case STREAM_ACL_FREEBSD_DEFAULT_ACL:
   case STREAM_ACL_FREEBSD_ACCESS_ACL:
   case STREAM_ACL_HPUX_ACL_ENTRY:
   case STREAM_ACL_IRIX_DEFAULT_ACL:
   case STREAM_ACL_IRIX_ACCESS_ACL:
   case STREAM_ACL_LINUX_DEFAULT_ACL:
   case STREAM_ACL_LINUX_ACCESS_ACL:
   case STREAM_ACL_TRU64_DEFAULT_ACL:
   case STREAM_ACL_TRU64_DEFAULT_DIR_ACL:
   case STREAM_ACL_TRU64_ACCESS_ACL:
   case STREAM_ACL_SOLARIS_ACLENT:
   case STREAM_ACL_SOLARIS_ACE:
   case STREAM_ACL_AFS_TEXT:
   case STREAM_ACL_AIX_AIXC:
   case STREAM_ACL_AIX_NFS4:
   case STREAM_ACL_FREEBSD_NFS4_ACL:
   case STREAM_ACL_HURD_DEFAULT_ACL:
   case STREAM_ACL_HURD_ACCESS_ACL:
      if (extract) {
         wbuf = rec->data;
         wsize = rec->data_len;
         pm_strcpy(acl_data.last_fname, attr->fname);

         parse_acl_streams(jcr, &acl_data, rec->maskedStream, wbuf, wsize);
      }
      break;

   case STREAM_XATTR_HURD:
   case STREAM_XATTR_IRIX:
   case STREAM_XATTR_TRU64:
   case STREAM_XATTR_AIX:
   case STREAM_XATTR_OPENBSD:
   case STREAM_XATTR_SOLARIS_SYS:
   case STREAM_XATTR_SOLARIS:
   case STREAM_XATTR_DARWIN:
   case STREAM_XATTR_FREEBSD:
   case STREAM_XATTR_LINUX:
   case STREAM_XATTR_NETBSD:
      if (extract) {
         wbuf = rec->data;
         wsize = rec->data_len;
         pm_strcpy(xattr_data.last_fname, attr->fname);

         parse_xattr_streams(jcr, &xattr_data, rec->maskedStream, wbuf, wsize);
      }
      break;

   case STREAM_NDMP_SEPERATOR:
      break;

   default:
      /* If extracting, weird stream (not 1 or 2), close output file anyway */
      if (extract) {
         if (!is_bopen(&bfd)) {
            Emsg0(M_ERROR, 0, _("Logic error output file should be open but is not.\n"));
         }
         set_attributes(jcr, attr, &bfd);
         extract = false;
      }
      Jmsg(jcr, M_ERROR, 0, _("Unknown stream=%d ignored. This shouldn't happen!\n"),
         rec->Stream);
      break;

   } /* end switch */
   return true;
}
Beispiel #24
0
/*********************************************************************
 *
 *         Main Bacula Tray Monitor -- User Interface Program
 *
 */
int main(int argc, char *argv[])
{   
   int ch, i, dir_index=-1;
   bool test_config = false;
   DIRRES* dird;
   CLIENT* filed;
   STORE* stored;

   setlocale(LC_ALL, "");
   bindtextdomain("bacula", LOCALEDIR);
   textdomain("bacula");

   init_stack_dump();
   my_name_is(argc, argv, "tray-monitor");
   lmgr_init_thread();
   init_msg(NULL, NULL, NULL);
   working_directory = "/tmp";

#ifndef HAVE_WIN32
   struct sigaction sigignore;
   sigignore.sa_flags = 0;
   sigignore.sa_handler = SIG_IGN;
   sigfillset(&sigignore.sa_mask);
   sigaction(SIGPIPE, &sigignore, NULL);
#endif

   while ((ch = getopt(argc, argv, "bc:d:th?f:s:")) != -1) {
      switch (ch) {
      case 'c':                    /* configuration file */
         if (configfile != NULL) {
            free(configfile);
         }
         configfile = bstrdup(optarg);
         break;

      case 'd':
         if (*optarg == 't') {
            dbg_timestamp = true;
         } else {
            debug_level = atoi(optarg);
            if (debug_level <= 0) {
               debug_level = 1;
            }
         }
         break;

      case 't':
         test_config = true;
         break;

      case 'h':
      case '?':
      default:
         usage();
         exit(1);
      }
   }
   argc -= optind;
   //argv += optind;

   if (argc) {
      usage();
      exit(1);
   }

   if (configfile == NULL) {
      configfile = bstrdup(CONFIG_FILE);
   }

   config = new_config_parser();
   parse_tmon_config(config, configfile, M_ERROR_TERM);

   LockRes();
   nitems = 0;
   foreach_res(monitor, R_MONITOR) {
      nitems++;
   }

   if (nitems != 1) {
      Emsg2(M_ERROR_TERM, 0,
         _("Error: %d Monitor resources defined in %s. You must define one and only one Monitor resource.\n"), nitems, configfile);
   }

   nitems = 0;
   foreach_res(dird, R_DIRECTOR) {
      dir_index=nitems;
      items[nitems].type = R_DIRECTOR;
      items[nitems].resource = dird;
      items[nitems].D_sock = NULL;
      items[nitems].state = warn;
      items[nitems].oldstate = warn;
      nitems++;
   }
Beispiel #25
0
int main (int argc, char *argv[])
{
   int ch;
   FILE *fd;
   char line[1000];
   bool got_inc = false;

   setlocale(LC_ALL, "");
   bindtextdomain("bareos", LOCALEDIR);
   textdomain("bareos");
   init_stack_dump();
   lmgr_init_thread();

   working_directory = "/tmp";
   my_name_is(argc, argv, "bextract");
   init_msg(NULL, NULL);              /* setup message handler */

   OSDependentInit();

   ff = init_find_files();
   binit(&bfd);

   while ((ch = getopt(argc, argv, "b:c:D:d:e:i:pvV:?")) != -1) {
      switch (ch) {
      case 'b':                    /* bootstrap file */
         bsr = parse_bsr(NULL, optarg);
//       dump_bsr(bsr, true);
         break;

      case 'c':                    /* specify config file */
         if (configfile != NULL) {
            free(configfile);
         }
         configfile = bstrdup(optarg);
         break;

      case 'D':                    /* specify director name */
         if (DirectorName != NULL) {
            free(DirectorName);
         }
         DirectorName = bstrdup(optarg);
         break;

      case 'd':                    /* debug level */
         if (*optarg == 't') {
            dbg_timestamp = true;
         } else {
            debug_level = atoi(optarg);
            if (debug_level <= 0) {
               debug_level = 1;
            }
         }
         break;

      case 'e':                    /* exclude list */
         if ((fd = fopen(optarg, "rb")) == NULL) {
            berrno be;
            Pmsg2(0, _("Could not open exclude file: %s, ERR=%s\n"),
               optarg, be.bstrerror());
            exit(1);
         }
         while (fgets(line, sizeof(line), fd) != NULL) {
            strip_trailing_junk(line);
            Dmsg1(900, "add_exclude %s\n", line);
            add_fname_to_exclude_list(ff, line);
         }
         fclose(fd);
         break;

      case 'i':                    /* include list */
         if ((fd = fopen(optarg, "rb")) == NULL) {
            berrno be;
            Pmsg2(0, _("Could not open include file: %s, ERR=%s\n"),
               optarg, be.bstrerror());
            exit(1);
         }
         while (fgets(line, sizeof(line), fd) != NULL) {
            strip_trailing_junk(line);
            Dmsg1(900, "add_include %s\n", line);
            add_fname_to_include_list(ff, 0, line);
         }
         fclose(fd);
         got_inc = true;
         break;

      case 'p':
         forge_on = true;
         break;

      case 'v':
         verbose++;
         break;

      case 'V':                    /* Volume name */
         VolumeName = optarg;
         break;

      case '?':
      default:
         usage();

      } /* end switch */
   } /* end while */
   argc -= optind;
   argv += optind;

   if (argc != 2) {
      Pmsg0(0, _("Wrong number of arguments: \n"));
      usage();
   }

   if (configfile == NULL) {
      configfile = bstrdup(CONFIG_FILE);
   }

   config = new_config_parser();
   parse_sd_config(config, configfile, M_ERROR_TERM);

   LockRes();
   me = (STORES *)GetNextRes(R_STORAGE, NULL);
   if (!me) {
      UnlockRes();
      Emsg1(M_ERROR_TERM, 0, _("No Storage resource defined in %s. Cannot continue.\n"),
         configfile);
   }
   UnlockRes();

  if (DirectorName) {
      foreach_res(director, R_DIRECTOR) {
         if (bstrcmp(director->hdr.name, DirectorName)) {
            break;
         }
      }
      if (!director) {
         Emsg2(M_ERROR_TERM, 0, _("No Director resource named %s defined in %s. Cannot continue.\n"),
               DirectorName, configfile);
      }
   }

   load_sd_plugins(me->plugin_directory);

   read_crypto_cache(me->working_directory, "bareos-sd",
                     get_first_port_host_order(me->sdaddrs));

   if (!got_inc) {                            /* If no include file, */
      add_fname_to_include_list(ff, 0, "/");  /*   include everything */
   }

   where = argv[1];
   do_extract(argv[0]);

   if (bsr) {
      free_bsr(bsr);
   }
   if (prog_name_msg) {
      Pmsg1(000, _("%d Program Name and/or Program Data Stream records ignored.\n"),
         prog_name_msg);
   }
   if (win32_data_msg) {
      Pmsg1(000, _("%d Win32 data or Win32 gzip data stream records. Ignored.\n"),
         win32_data_msg);
   }
   term_include_exclude_files(ff);
   term_find_files(ff);
   return 0;
}
Beispiel #26
0
/*
 * Save the new resource by chaining it into the head list for
 * the resource. If this is pass 2, we update any resource
 * pointers (currently only in the Job resource).
 */
bool save_resource(int type, RES_ITEM *items, int pass)
{
   URES *res;
   int rindex = type - R_FIRST;
   int i;
   int error = 0;

   /*
    * Ensure that all required items are present
    */
   for (i = 0; items[i].name; i++) {
      if (items[i].flags & CFG_ITEM_REQUIRED) {
            if (!bit_is_set(i, res_all.res_dir.hdr.item_present)) {
               Emsg2(M_ABORT, 0, _("%s item is required in %s resource, but not found.\n"),
                 items[i].name, resources[rindex]);
             }
      }
   }

   /*
    * During pass 2, we looked up pointers to all the resources
    * referrenced in the current resource, , now we
    * must copy their address from the static record to the allocated
    * record.
    */
   if (pass == 2) {
      switch (type) {
         case R_CONSOLE:
            if ((res = (URES *)GetResWithName(R_CONSOLE, res_all.res_cons.name())) == NULL) {
               Emsg1(M_ABORT, 0, _("Cannot find Console resource %s\n"), res_all.res_cons.name());
            } else {
               res->res_cons.tls.allowed_cns = res_all.res_cons.tls.allowed_cns;
            }
            break;
         case R_DIRECTOR:
            if ((res = (URES *)GetResWithName(R_DIRECTOR, res_all.res_dir.name())) == NULL) {
               Emsg1(M_ABORT, 0, _("Cannot find Director resource %s\n"), res_all.res_dir.name());
            } else {
               res->res_dir.tls.allowed_cns = res_all.res_dir.tls.allowed_cns;
            }
            break;
         default:
            Emsg1(M_ERROR, 0, _("Unknown resource type %d\n"), type);
            error = 1;
            break;
      }

      /*
       * Note, the resoure name was already saved during pass 1,
       * so here, we can just release it.
       */
      if (res_all.res_dir.hdr.name) {
         free(res_all.res_dir.hdr.name);
         res_all.res_dir.hdr.name = NULL;
      }
      if (res_all.res_dir.hdr.desc) {
         free(res_all.res_dir.hdr.desc);
         res_all.res_dir.hdr.desc = NULL;
      }
      return (error == 0);
   }

   /*
    * Common
    */
   if (!error) {
      res = (URES *)malloc(resources[rindex].size);
      memcpy(res, &res_all, resources[rindex].size);
      if (!res_head[rindex]) {
         res_head[rindex] = (RES *)res; /* store first entry */
      } else {
         RES *next, *last;
         for (last=next=res_head[rindex]; next; next=next->next) {
            last = next;
            if (bstrcmp(next->name, res->res_dir.name())) {
               Emsg2(M_ERROR_TERM, 0,
                     _("Attempt to define second %s resource named \"%s\" is not permitted.\n"),
                     resources[rindex].name, res->res_dir.name());
            }
         }
         last->next = (RES *)res;
         Dmsg2(90, "Inserting %s res: %s\n", res_to_str(type), res->res_dir.name());
      }
   }
   return (error == 0);
}
Beispiel #27
0
/*
 * Core interface function to lowlevel SCSI interface.
 */
static inline bool do_scsi_cmd_page(int fd, const char *device_name,
                                    void *cdb, unsigned int cdb_len,
                                    void *cmd_page, unsigned int cmd_page_len,
                                    int flags)
{
   int rc;
   struct uscsi_cmd my_cmd;
   SCSI_PAGE_SENSE sense;
   bool opened_device = false;
   bool retval = false;

   /*
    * See if we need to open the device_name or if we got an open filedescriptor.
    */
   if (fd == -1) {
      fd = open(device_name, O_RDWR | O_NONBLOCK | O_BINARY);
      if (fd < 0) {
         berrno be;

         Emsg2(M_ERROR, 0, _("Failed to open %s: ERR=%s\n"),
               device_name, be.bstrerror());
         Dmsg2(010, "Failed to open %s: ERR=%s\n",
               device_name, be.bstrerror());
         return false;
      }
      opened_device = true;
   }

   memset(&sense, 0, sizeof(sense));

   my_cmd.uscsi_flags = flags;
   my_cmd.uscsi_timeout = 15;   /* Allow 15 seconds for completion */
   my_cmd.uscsi_cdb = (char *)cdb;
   my_cmd.uscsi_cdblen = cdb_len;
   my_cmd.uscsi_bufaddr = (char *)cmd_page;
   my_cmd.uscsi_buflen = cmd_page_len;
   my_cmd.uscsi_rqlen = sizeof(sense);
   my_cmd.uscsi_rqbuf = (char *)&sense;

   rc = ioctl(fd, USCSICMD, &my_cmd);
   if (rc != 0) {
      berrno be;

      Emsg2(M_ERROR, 0, _("Unable to perform USCSICMD ioctl on fd %d: ERR=%s\n"),
            fd, be.bstrerror());
      Emsg3(M_ERROR, 0, _("Sense Key: %0.2X ASC: %0.2X ASCQ: %0.2X\n"),
            LOBYTE(sense.senseKey), sense.addSenseCode, sense.addSenseCodeQual);
      Dmsg2(010, "Unable to perform USCSICMD ioctl on fd %d: ERR=%s\n",
            fd, be.bstrerror());
      Dmsg3(010, "Sense Key: %0.2X ASC: %0.2X ASCQ: %0.2X\n",
            LOBYTE(sense.senseKey), sense.addSenseCode, sense.addSenseCodeQual);
      goto bail_out;
   }

   retval = true;

bail_out:
   /*
    * See if we opened the device in this function, if so close it.
    */
   if (opened_device) {
      close(fd);
   }
   return retval;
}
Beispiel #28
0
/*
 * Core interface function to lowlevel SCSI interface.
 */
static inline bool do_scsi_cmd_page(int fd, const char *device_name,
                                    void *cdb, unsigned int cdb_len,
                                    void *cmd_page, unsigned int cmd_page_len,
                                    int direction)
{
   int unitnum, len;
   union ccb *ccb;
   char errbuf[128];
   char cam_devicename[64];
   struct cam_device *cam_dev;
   SCSI_PAGE_SENSE sense;
   bool retval = false;

   /*
    * See what CAM device to use.
    */
   if (cam_get_device(device_name, cam_devicename, sizeof(cam_devicename), &unitnum) == -1) {
      berrno be;

      Emsg2(M_ERROR, 0, _("Failed to find CAM device for %s: ERR=%s\n"),
            device_name, be.bstrerror());
      Dmsg2(010, "Failed to find CAM device for %s: ERR=%s\n",
            device_name, be.bstrerror());
      return false;
   }

   cam_dev = cam_open_spec_device(cam_devicename, unitnum, O_RDWR, NULL);
   if (!cam_dev) {
      berrno be;

      Emsg2(M_ERROR, 0, _("Failed to open CAM device for %s: ERR=%s\n"),
            device_name, be.bstrerror());
      Dmsg2(010, "Failed to open CAM device for %s: ERR=%s\n",
            device_name, be.bstrerror());
      return false;
   }

   ccb = cam_getccv(cam_dev);
   if (!ccb) {
      Emsg1(M_ERROR, 0, _("Failed to allocate new ccb for %s\n"),
            device_name);
      Dmsg1(0, "Failed to allocate new ccb for %s\n",
            device_name);
      goto bail_out;
   }

   /*
    * Clear out structure, except for header that was filled for us.
    */
   memset(&ccb->ccb_h)[1], 0, sizeof(struct ccb_scsiio) - sizeof(struct ccb_hdr));

   cam_fill_csio(&ccb->csio,
                 1, /* retries */
                 NULL, /* cbfcnp */
                 direction, /* flags */
                 MSG_SIMPLE_Q_TAG,, /* tagaction */
                 cmd_page, /* dataptr */
                 cmd_page_len, /* datalen */
                 sizeof(sense), /* senselength */
                 cdb_len, /* cdblength  */
                 15000 /* timeout (millisecs) */);
   memcpy(ccb->csio.cdb_io.cdb_bytes, cdb, SPP_SP_CMD_LEN);

   if (cam_send_ccb(cam_dev, ccb) < 0) {
      Emsg2(M_ERROR, 0, _("Failed to send ccb to device %s: %s\n"),
            device_name, cam_error_string(cam_dev, ccb, errbuf, sizeof(errbuf),
                                          CAM_ESF_ALL, CAM_EPF_ALL));
      Dmsg2(010, "Failed to send ccb to device %s: %s\n",
            device_name, cam_error_string(cam_dev, ccb, errbuf, sizeof(errbuf),
                                          CAM_ESF_ALL, CAM_EPF_ALL));
      cam_freeccb(ccb);
      goto bail_out;
   }

   /*
    * Retrieve the SCSI sense data.
    */
   if (((ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP) ||
       ((ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_SCSI_STATUS_ERROR)) {
      if ((SAM_STAT_CHECK_CONDITION == ccb->csio.scsi_status) ||
          (SAM_STAT_COMMAND_TERMINATED == ccb->csio.scsi_status)) {
         len = sizeof(sense) - ccb->csio.sense_resid;
         if (len) {
            memcpy(&sense, &(ccb->csio.sense_data), len);
         }
      }
   }

   retval = true;

bail_out:
   /*
    * Close the CAM device.
    */
   cam_close_device(cam_dev);
   return retval;
}
Beispiel #29
0
/*
 * Core interface function to lowlevel SCSI interface.
 */
static inline bool do_scsi_cmd_page(int fd, const char *device_name,
                                    void *cdb, unsigned int cdb_len,
                                    void *cmd_page, unsigned int cmd_page_len,
                                    int flags)
{
   int rc;
   scsireq_t req;
   SCSI_PAGE_SENSE *sense;
   bool opened_device = false;
   bool retval = false;

   /*
    * See if we need to open the device_name or if we got an open filedescriptor.
    */
   if (fd == -1) {
      fd = open(device_name, O_RDWR | O_NONBLOCK| O_BINARY);
      if (fd < 0) {
         berrno be;

         Emsg2(M_ERROR, 0, _("Failed to open %s: ERR=%s\n"),
               device_name, be.bstrerror());
         Dmsg2(010, "Failed to open %s: ERR=%s\n",
               device_name, be.bstrerror());
         return false;
      }
      opened_device = true;
   }

   memset(&req, 0, sizeof(req));

   memcpy(req.cmd, cdb, cdb_len);
   req.cmdlen = cdb_len;
   req.databuf = cmd_page;
   req.datalen = cmd_page_len;
   req.timeout = 15000 /* timeout (millisecs) */;
   req.flags = flags;
   req.senselen = sizeof(SCSI_PAGE_SENSE);

   rc = ioctl(fd, SCIOCCOMMAND, &req);
   if (rc <  0) {
      berrno be;

      Emsg2(M_ERROR, 0, _("Unable to perform SCIOCCOMMAND ioctl on fd %d: ERR=%s\n"),
            fd, be.bstrerror());
      Dmsg2(010, "Unable to perform SCIOCCOMMAND ioctl on fd %d: ERR=%s\n",
            fd, be.bstrerror());
      goto bail_out;
   }

   switch (req.retsts) {
   case SCCMD_OK:
      retval = true;
      break;
   case SCCMD_SENSE:
      sense = req.sense;
      Emsg3(M_ERROR, 0, _("Sense Key: %0.2X ASC: %0.2X ASCQ: %0.2X\n"),
            LOBYTE(sense.senseKey), sense.addSenseCode, sense.addSenseCodeQual);
      Dmsg3(010, "Sense Key: %0.2X ASC: %0.2X ASCQ: %0.2X\n",
            LOBYTE(sense.senseKey), sense.addSenseCode, sense.addSenseCodeQual);
      break;
   case SCCMD_TIMEOUT:
      Emsg1(M_ERROR, 0, _("SCIOCCOMMAND ioctl on %s returned SCSI command timed out\n"),
            devicename);
      Dmsg1(010, "SCIOCCOMMAND ioctl on %s returned SCSI command timed out\n",
            devicename);
      break;
   case SCCMD_BUSY:
      Emsg1(M_ERROR, 0, _("SCIOCCOMMAND ioctl on %s returned device is busy\n"),
            devicename);
      Dmsg1(010, "SCIOCCOMMAND ioctl on %s returned device is busy\n",
            devicename);
      break;
   case SCCMD_SENSE:
      break;
   default:
      Emsg2(M_ERROR, 0, _("SCIOCCOMMAND ioctl on %s returned unknown status %d\n"),
            device_name, req.retsts);
      Dmsg2(010, "SCIOCCOMMAND ioctl on %s returned unknown status %d\n",
            device_name, req.retsts);
      break;
   }

bail_out:
   /*
    * See if we opened the device in this function, if so close it.
    */
   if (opened_device) {
      close(fd);
   }
   return retval;
}
Beispiel #30
0
/*
 * Core interface function to lowlevel SCSI interface.
 */
static inline bool do_scsi_cmd_page(int fd, const char *device_name,
                                    void *cdb, unsigned int cdb_len,
                                    void *cmd_page, unsigned int cmd_page_len,
                                    int direction)
{
   int rc;
   sg_io_hdr_t io_hdr;
   SCSI_PAGE_SENSE sense;
   bool opened_device = false;
   bool retval = false;

   /*
    * See if we need to open the device_name or if we got an open filedescriptor.
    */
   if (fd == -1) {
      fd = open(device_name, O_RDWR | O_NONBLOCK | O_BINARY);
      if (fd < 0) {
         berrno be;

         Emsg2(M_ERROR, 0, _("Failed to open %s: ERR=%s\n"),
               device_name, be.bstrerror());
         Dmsg2(010, "Failed to open %s: ERR=%s\n",
               device_name, be.bstrerror());
         return false;
      }
      opened_device = true;
   }

   memset(&sense, 0, sizeof(sense));
   memset(&io_hdr, 0, sizeof(io_hdr));
   io_hdr.interface_id = 'S';
   io_hdr.cmd_len = cdb_len;
   io_hdr.mx_sb_len = sizeof(sense);
   io_hdr.dxfer_direction = direction;
   io_hdr.dxfer_len = cmd_page_len;
   io_hdr.dxferp = (char *)cmd_page;
   io_hdr.cmdp = (unsigned char *)cdb;
   io_hdr.sbp = (unsigned char *)&sense;

   rc = ioctl(fd, SG_IO, &io_hdr);
   if (rc <  0) {
      berrno be;

      Emsg2(M_ERROR, 0, _("Unable to perform SG_IO ioctl on fd %d: ERR=%s\n"),
            fd, be.bstrerror());
      Dmsg2(010, "Unable to perform SG_IO ioctl on fd %d: ERR=%s\n",
            fd, be.bstrerror());
      goto bail_out;
   }

   if ((io_hdr.info & SG_INFO_OK_MASK) != SG_INFO_OK) {
      Emsg3(M_ERROR, 0, _("Failed with info 0x%02x mask status 0x%02x msg status 0x%02x\n"),
            io_hdr.info, io_hdr.masked_status, io_hdr.msg_status);
      Emsg2(M_ERROR, 0, _("     host status 0x%02x driver status 0x%02x\n"),
            io_hdr.host_status, io_hdr.driver_status );
      Dmsg3(010, "Failed with info 0x%02x mask status 0x%02x msg status 0x%02x\n",
            io_hdr.info, io_hdr.masked_status, io_hdr.msg_status);
      Dmsg2(010, "     host status 0x%02x driver status 0x%02x\n",
            io_hdr.host_status, io_hdr.driver_status );
      goto bail_out;
   }

   retval = true;

bail_out:
   /*
    * See if we opened the device in this function, if so close it.
    */
   if (opened_device) {
      close(fd);
   }

   return retval;
}