Example #1
0
File: bsys.c Project: pstray/bareos
/*
 * 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
}
Example #2
0
void b_UnlockRes(const char *file, int line)
{
   int errstat;
   if ((errstat=rwl_writeunlock(&res_lock)) != 0) {
      Emsg3(M_ABORT, 0, _("rwl_writeunlock failure at %s:%d:. ERR=%s\n"),
           file, line, strerror(errstat));
   }
   res_locked--;
#ifdef TRACE_RES
   Pmsg4(000, "UnLockRes locked=%d wactive=%d at %s:%d\n",
         res_locked, res_lock.w_active, file, line);
#endif
}
Example #3
0
void b_LockRes(const char *file, int line)
{
   int errstat;
#ifdef TRACE_RES
   Pmsg4(000, "LockRes  locked=%d w_active=%d at %s:%d\n",
         res_locked, res_lock.w_active, file, line);
    if (res_locked) {
       Pmsg2(000, "LockRes writerid=%d myid=%d\n", res_lock.writer_id,
          pthread_self());
     }
#endif
   if ((errstat=rwl_writelock(&res_lock)) != 0) {
      Emsg3(M_ABORT, 0, _("rwl_writelock failure at %s:%d:  ERR=%s\n"),
           file, line, strerror(errstat));
   }
   res_locked++;
}
Example #4
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
   }
Example #5
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;
}
Example #6
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;
}
Example #7
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;
}
Example #8
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;
}
Example #9
0
/*
 * Drop to privilege new userid and new gid if non-NULL
 */
void drop(char *uname, char *gname)
{
#if   defined(HAVE_PWD_H) && defined(HAVE_GRP_H)
   struct passwd *passw = NULL;
   struct group *group = NULL;
   gid_t gid;
   uid_t uid;
   char username[1000];         

   Dmsg2(900, "uname=%s gname=%s\n", uname?uname:"NONE", gname?gname:"NONE");
   if (!uname && !gname) {
      return;                            /* Nothing to do */
   }

   if (uname) {
      if ((passw = getpwnam(uname)) == NULL) {
         berrno be;
         Emsg2(M_ERROR_TERM, 0, _("Could not find userid=%s: ERR=%s\n"), uname,
            be.bstrerror());
      }
   } else {
      if ((passw = getpwuid(getuid())) == NULL) {
         berrno be;
         Emsg1(M_ERROR_TERM, 0, _("Could not find password entry. ERR=%s\n"),
            be.bstrerror());
      } else {
         uname = passw->pw_name;
      }
   }
   /* Any OS uname pointer may get overwritten, so save name, uid, and gid */
   bstrncpy(username, uname, sizeof(username));
   uid = passw->pw_uid;
   gid = passw->pw_gid;
   if (gname) {
      if ((group = getgrnam(gname)) == NULL) {
         berrno be;
         Emsg2(M_ERROR_TERM, 0, _("Could not find group=%s: ERR=%s\n"), gname,
            be.bstrerror());
      }
      gid = group->gr_gid;
   }
   if (initgroups(username, gid)) {
      berrno be;
      if (gname) {
         Emsg3(M_ERROR_TERM, 0, _("Could not initgroups for group=%s, userid=%s: ERR=%s\n"),         
            gname, username, be.bstrerror());
      } else {
         Emsg2(M_ERROR_TERM, 0, _("Could not initgroups for userid=%s: ERR=%s\n"),         
            username, be.bstrerror());
      }
   }
   if (gname) {
      if (setgid(gid)) {
         berrno be;
         Emsg2(M_ERROR_TERM, 0, _("Could not set group=%s: ERR=%s\n"), gname,
            be.bstrerror());
      }
   }
   if (setuid(uid)) {
      berrno be;
      Emsg1(M_ERROR_TERM, 0, _("Could not set specified userid: %s\n"), username);
   }
#endif
}