int main (int argc, char** argv) { NotifyNotification* notification; gboolean success; GError* error = NULL; if (!notify_init ("sync-icon-only")) return 1; /* call this so we can savely use has_cap(CAP_SOMETHING) later */ init_caps (); /* show what's supported */ print_caps (); /* try the sync. icon-only case */ if (has_cap (CAP_LAYOUT_ICON_ONLY) && has_cap (CAP_SYNCHRONOUS)) { notification = notify_notification_new ( "Eject", /* for a11y-reasons put something meaningfull here */ NULL, "notification-device-eject"); notify_notification_set_hint_string (notification, "x-canonical-private-icon-only", "true"); notify_notification_set_hint_string (notification, "x-canonical-private-synchronous", "true"); error = NULL; success = notify_notification_show (notification, &error); if (!success) { g_print ("That did not work ... \"%s\".\n", error->message); g_error_free (error); } g_signal_connect (G_OBJECT (notification), "closed", G_CALLBACK (closed_handler), NULL); } else { g_print ("The daemon does not support the x-canonical-private-icon-only hint!\n"); g_print ("The daemon does not support the x-canonical-private-synchronous hint!\n"); } notify_uninit (); return 0; }
/* * Backward space a record * * Returns: false on failure * true on success */ bool generic_tape_device::bsr(int num) { struct mtop mt_com; int status; if (!is_open()) { dev_errno = EBADF; Mmsg0(errmsg, _("Bad call to bsr_dev. Device not open\n")); Emsg0(M_FATAL, 0, errmsg); return false; } if (!has_cap(CAP_BSR)) { Mmsg1(errmsg, _("ioctl MTBSR not permitted on %s.\n"), prt_name); return false; } Dmsg0(100, "bsr_dev\n"); block_num -= num; clear_eof(); clear_eot(); mt_com.mt_op = MTBSR; mt_com.mt_count = num; status = d_ioctl(m_fd, MTIOCTOP, (char *)&mt_com); if (status < 0) { berrno be; clrerror(mt_com.mt_op); Mmsg2(errmsg, _("ioctl MTBSR error on %s. ERR=%s.\n"), prt_name, be.bstrerror()); } return status == 0; }
/* Returns the number of capabilities printed. */ static int print_caps(FILE *f, enum cap_type which) { int i, n = 0, max = real_cap_last_cap(); for (i = 0; i <= max; i++) { int ret = has_cap(which, i); if (i == 0 && ret < 0) return -1; if (ret == 1) { const char *name = capng_capability_to_name(i); if (n) fputc(',', f); if (name) fputs(name, f); else /* cap-ng has very poor handling of * CAP_LAST_CAP changes. This is the * best we can do. */ printf("cap_%d", i); n++; } } return n; }
_public_ int sd_bus_creds_has_bounding_cap(sd_bus_creds *c, int capability) { assert_return(c, -EINVAL); assert_return(capability >= 0, -EINVAL); if (!(c->mask & SD_BUS_CREDS_BOUNDING_CAPS)) return -ENODATA; return has_cap(c, CAP_OFFSET_BOUNDING, capability); }
_public_ int sd_bus_creds_has_inheritable_cap(sd_bus_creds *c, int capability) { assert_return(c, -EINVAL); assert_return(capability >= 0, -EINVAL); if (!(c->mask & SD_BUS_CREDS_INHERITABLE_CAPS)) return -ENODATA; return has_cap(c, CAP_OFFSET_INHERITABLE, capability); }
_public_ int sd_bus_creds_has_permitted_cap(sd_bus_creds *c, int capability) { assert_return(c, -EINVAL); assert_return(capability >= 0, -EINVAL); if (!(c->mask & SD_BUS_CREDS_PERMITTED_CAPS)) return -ENODATA; return has_cap(c, CAP_OFFSET_PERMITTED, capability); }
_public_ int sd_bus_creds_has_effective_cap(sd_bus_creds *c, int capability) { assert_return(c, -EINVAL); assert_return(capability >= 0, -EINVAL); if (!(c->mask & SD_BUS_CREDS_EFFECTIVE_CAPS)) return -ENODATA; return has_cap(c, CAP_OFFSET_EFFECTIVE, capability); }
int main (int argc, char** argv) { if (!notify_init ("append-hint-example")) return 1; /* call this so we can savely use has_cap(CAP_SOMETHING) later */ init_caps (); /* show what's supported */ print_caps (); /* try the append-hint */ if (has_cap (CAP_APPEND)) { push_notification ("Cole Raby", "Hey Bro Coly!", "notification-message-im"); push_notification ("Cole Raby", "What's up dude?", "notification-message-im"); push_notification ("Cole Raby", "Did you watch the air-race in Oshkosh last week?", "notification-message-im"); push_notification ("Cole Raby", "Phil owned the place like no one before him!", "notification-message-im"); push_notification ("Cole Raby", "Did really everything in the race work according to regulations?", "notification-message-im"); push_notification ("Cole Raby", "Somehow I think to remember Burt Williams did cut corners and was not punished for this.", "notification-message-im"); push_notification ("Cole Raby", "Hopefully the referees will watch the videos of the race.", "notification-message-im"); push_notification ("Cole Raby", "Burt could get fined with US$ 50000 for that rule-violation :)", "notification-message-im"); } else { g_print ("The daemon does not support the x-canonical-append hint!"); } notify_uninit (); return 0; }
/* Returns file position on tape or -1 */ int32_t DEVICE::get_os_tape_file() { struct mtget mt_stat; if (has_cap(CAP_MTIOCGET) && d_ioctl(m_fd, MTIOCGET, (char *)&mt_stat) == 0) { return mt_stat.mt_fileno; } return -1; }
/* * Foward space num records * * Returns: false on failure * true on success */ bool generic_tape_device::fsr(int num) { struct mtop mt_com; int status; if (!is_open()) { dev_errno = EBADF; Mmsg0(errmsg, _("Bad call to fsr. Device not open\n")); Emsg0(M_FATAL, 0, errmsg); return false; } if (!has_cap(CAP_FSR)) { Mmsg1(errmsg, _("ioctl MTFSR not permitted on %s.\n"), prt_name); return false; } Dmsg1(100, "fsr %d\n", num); mt_com.mt_op = MTFSR; mt_com.mt_count = num; status = d_ioctl(m_fd, MTIOCTOP, (char *)&mt_com); if (status == 0) { clear_eof(); block_num += num; } else { berrno be; struct mtget mt_stat; clrerror(mt_com.mt_op); Dmsg1(100, "FSF fail: ERR=%s\n", be.bstrerror()); if (dev_get_os_pos(this, &mt_stat)) { Dmsg4(100, "Adjust from %d:%d to %d:%d\n", file, block_num, mt_stat.mt_fileno, mt_stat.mt_blkno); file = mt_stat.mt_fileno; block_num = mt_stat.mt_blkno; } else { if (at_eof()) { set_eot(); } else { set_ateof(); } } Mmsg3(errmsg, _("ioctl MTFSR %d error on %s. ERR=%s.\n"), num, prt_name, be.bstrerror()); } return status == 0; }
/* * Reposition the device to file, block * * Returns: false on failure * true on success */ bool generic_tape_device::reposition(DCR *dcr, uint32_t rfile, uint32_t rblock) { Dmsg4(100, "reposition from %u:%u to %u:%u\n", file, block_num, rfile, rblock); if (rfile < file) { Dmsg0(100, "Rewind\n"); if (!rewind(NULL)) { return false; } } if (rfile > file) { Dmsg1(100, "fsf %d\n", rfile-file); if (!fsf(rfile-file)) { Dmsg1(100, "fsf failed! ERR=%s\n", bstrerror()); return false; } Dmsg2(100, "wanted_file=%d at_file=%d\n", rfile, file); } if (rblock < block_num) { Dmsg2(100, "wanted_blk=%d at_blk=%d\n", rblock, block_num); Dmsg0(100, "bsf 1\n"); bsf(1); Dmsg0(100, "fsf 1\n"); fsf(1); Dmsg2(100, "wanted_blk=%d at_blk=%d\n", rblock, block_num); } if (has_cap(CAP_POSITIONBLOCKS) && rblock > block_num) { /* * Ignore errors as Bareos can read to the correct block. */ Dmsg1(100, "fsr %d\n", rblock-block_num); return fsr(rblock-block_num); } else { while (rblock > block_num) { if (!dcr->read_block_from_dev(NO_BLOCK_NUMBER_CHECK)) { berrno be; dev_errno = errno; Dmsg2(30, "Failed to find requested block on %s: ERR=%s", prt_name, be.bstrerror()); return false; } Dmsg2(300, "moving forward wanted_blk=%d at_blk=%d\n", rblock, block_num); } } return true; }
bool DEVICE::offline_or_rewind() { if (m_fd < 0) { return false; } if (has_cap(CAP_OFFLINEUNMOUNT)) { return offline(); } else { /* * Note, this rewind probably should not be here (it wasn't * in prior versions of Bareos), but on FreeBSD, this is * needed in the case the tape was "frozen" due to an error * such as backspacing after writing and EOF. If it is not * done, all future references to the drive get and I/O error. */ clrerror(MTREW); return rewind(NULL); } }
/* * Foward space a file * * Returns: true on success * false on failure */ bool generic_tape_device::fsf(int num) { int32_t os_file = 0; struct mtop mt_com; int status = 0; if (!is_open()) { dev_errno = EBADF; Mmsg0(errmsg, _("Bad call to fsf. Device not open\n")); Emsg0(M_FATAL, 0, errmsg); return false; } if (at_eot()) { dev_errno = 0; Mmsg1(errmsg, _("Device %s at End of Tape.\n"), prt_name); return false; } if (at_eof()) { Dmsg0(200, "ST_EOF set on entry to FSF\n"); } Dmsg0(100, "fsf\n"); block_num = 0; /* * If Fast forward space file is set, then we * use MTFSF to forward space and MTIOCGET * to get the file position. We assume that * the SCSI driver will ensure that we do not * forward space past the end of the medium. */ if (has_cap(CAP_FSF) && has_cap(CAP_MTIOCGET) && has_cap(CAP_FASTFSF)) { int my_errno = 0; mt_com.mt_op = MTFSF; mt_com.mt_count = num; status = d_ioctl(m_fd, MTIOCTOP, (char *)&mt_com); if (status < 0) { my_errno = errno; /* save errno */ } else if ((os_file=get_os_tape_file()) < 0) { my_errno = errno; /* save errno */ } if (my_errno != 0) { berrno be; set_eot(); Dmsg0(200, "Set ST_EOT\n"); clrerror(mt_com.mt_op); Mmsg2(errmsg, _("ioctl MTFSF error on %s. ERR=%s.\n"), prt_name, be.bstrerror(my_errno)); Dmsg1(200, "%s", errmsg); return false; } Dmsg1(200, "fsf file=%d\n", os_file); set_ateof(); file = os_file; return true; /* * Here if CAP_FSF is set, and virtually all drives * these days support it, we read a record, then forward * space one file. Using this procedure, which is slow, * is the only way we can be sure that we don't read * two consecutive EOF marks, which means End of Data. */ } else if (has_cap(CAP_FSF)) { POOLMEM *rbuf; int rbuf_len; Dmsg0(200, "FSF has cap_fsf\n"); if (max_block_size == 0) { rbuf_len = DEFAULT_BLOCK_SIZE; } else { rbuf_len = max_block_size; } rbuf = get_memory(rbuf_len); mt_com.mt_op = MTFSF; mt_com.mt_count = 1; while (num-- && !at_eot()) { Dmsg0(100, "Doing read before fsf\n"); if ((status = this->read((char *)rbuf, rbuf_len)) < 0) { if (errno == ENOMEM) { /* tape record exceeds buf len */ status = rbuf_len; /* This is OK */ /* * On IBM drives, they return ENOSPC at EOM instead of EOF status */ } else if (at_eof() && errno == ENOSPC) { status = 0; } else if (has_cap(CAP_IOERRATEOM) && at_eof() && errno == EIO) { if (has_cap(CAP_IBMLINTAPE)) { Dmsg0(100, "Got EIO on read, checking lin_tape sense data\n"); if (check_scsi_at_eod(m_fd)) { Dmsg0(100, "Sense data confirms it's EOD\n"); status = 0; } else { Dmsg0(100, "Not at EOD, might be a real error. Check sense trace from lin_taped logs.\n"); set_eot(); clrerror(-1); Mmsg1(errmsg, _("read error on %s. ERR=Input/Output error.\n"), prt_name); break; } } else { Dmsg0(100, "Got EIO on read, assuming that's due to EOD\n"); status = 0; } } else { berrno be; set_eot(); clrerror(-1); Dmsg2(100, "Set ST_EOT read errno=%d. ERR=%s\n", dev_errno, be.bstrerror()); Mmsg2(errmsg, _("read error on %s. ERR=%s.\n"), prt_name, be.bstrerror()); Dmsg1(100, "%s", errmsg); break; } } if (status == 0) { /* EOF */ Dmsg1(100, "End of File mark from read. File=%d\n", file+1); /* * Two reads of zero means end of tape */ if (at_eof()) { set_eot(); Dmsg0(100, "Set ST_EOT\n"); break; } else { set_ateof(); continue; } } else { /* Got data */ clear_eot(); clear_eof(); } Dmsg0(100, "Doing MTFSF\n"); status = d_ioctl(m_fd, MTIOCTOP, (char *)&mt_com); if (status < 0) { /* error => EOT */ berrno be; set_eot(); Dmsg0(100, "Set ST_EOT\n"); clrerror(mt_com.mt_op); Mmsg2(errmsg, _("ioctl MTFSF error on %s. ERR=%s.\n"), prt_name, be.bstrerror()); Dmsg0(100, "Got < 0 for MTFSF\n"); Dmsg1(100, "%s", errmsg); } else { set_ateof(); } } free_memory(rbuf); /* * No FSF, so use FSR to simulate it */ } else { Dmsg0(200, "Doing FSR for FSF\n"); while (num-- && !at_eot()) { fsr(INT32_MAX); /* returns -1 on EOF or EOT */ } if (at_eot()) { dev_errno = 0; Mmsg1(errmsg, _("Device %s at End of Tape.\n"), prt_name); status = -1; } else { status = 0; } } Dmsg1(200, "Return %d from FSF\n", status); if (at_eof()) { Dmsg0(200, "ST_EOF set on exit FSF\n"); } if (at_eot()) { Dmsg0(200, "ST_EOT set on exit FSF\n"); } Dmsg1(200, "Return from FSF file=%d\n", file); return status == 0; }
/* * Position device to end of medium (end of data) * * Returns: true on succes * false on error */ bool generic_tape_device::eod(DCR *dcr) { struct mtop mt_com; bool ok = true; int32_t os_file; if (m_fd < 0) { dev_errno = EBADF; Mmsg1(errmsg, _("Bad call to eod. Device %s not open\n"), prt_name); return false; } #if defined (__digital__) && defined (__unix__) return fsf(VolCatInfo.VolCatFiles); #endif Dmsg0(100, "Enter eod\n"); if (at_eot()) { return true; } clear_eof(); /* remove EOF flag */ block_num = file = 0; file_size = 0; file_addr = 0; #ifdef MTEOM if (has_cap(CAP_FASTFSF) && !has_cap(CAP_EOM)) { Dmsg0(100,"Using FAST FSF for EOM\n"); /* * If unknown position, rewind */ if (get_os_tape_file() < 0) { if (!rewind(NULL)) { Dmsg0(100, "Rewind error\n"); return false; } } mt_com.mt_op = MTFSF; /* * ***FIXME*** fix code to handle case that INT16_MAX is not large enough. */ mt_com.mt_count = INT16_MAX; /* use big positive number */ if (mt_com.mt_count < 0) { mt_com.mt_count = INT16_MAX; /* brain damaged system */ } } if (has_cap(CAP_MTIOCGET) && (has_cap(CAP_FASTFSF) || has_cap(CAP_EOM))) { if (has_cap(CAP_EOM)) { Dmsg0(100,"Using EOM for EOM\n"); mt_com.mt_op = MTEOM; mt_com.mt_count = 1; } if (d_ioctl(m_fd, MTIOCTOP, (char *)&mt_com) < 0) { berrno be; clrerror(mt_com.mt_op); Dmsg1(50, "ioctl error: %s\n", be.bstrerror()); update_pos(dcr); Mmsg2(errmsg, _("ioctl MTEOM error on %s. ERR=%s.\n"), prt_name, be.bstrerror()); Dmsg0(100, errmsg); return false; } os_file = get_os_tape_file(); if (os_file < 0) { berrno be; clrerror(-1); Mmsg2(errmsg, _("ioctl MTIOCGET error on %s. ERR=%s.\n"), prt_name, be.bstrerror()); Dmsg0(100, errmsg); return false; } Dmsg1(100, "EOD file=%d\n", os_file); set_ateof(); file = os_file; } else { #endif /* * Rewind then use FSF until EOT reached */ if (!rewind(NULL)) { Dmsg0(100, "Rewind error.\n"); return false; } /* * Move file by file to the end of the tape */ int file_num; for (file_num=file; !at_eot(); file_num++) { Dmsg0(200, "eod: doing fsf 1\n"); if (!fsf(1)) { Dmsg0(100, "fsf error.\n"); return false; } /* * Avoid infinite loop by ensuring we advance. */ if (!at_eot() && file_num == (int)file) { Dmsg1(100, "fsf did not advance from file %d\n", file_num); set_ateof(); os_file = get_os_tape_file(); if (os_file >= 0) { Dmsg2(100, "Adjust file from %d to %d\n", file_num, os_file); file = os_file; } break; } } #ifdef MTEOM } #endif /* * Some drivers leave us after second EOF when doing MTEOM, so we must backup * so that appending overwrites the second EOF. */ if (has_cap(CAP_BSFATEOM)) { /* * Backup over EOF */ ok = bsf(1); /* * If BSF worked and fileno is known (not -1), set file */ os_file = get_os_tape_file(); if (os_file >= 0) { Dmsg2(100, "BSFATEOF adjust file from %d to %d\n", file , os_file); file = os_file; } else { file++; /* wing it -- not correct on all OSes */ } } else { update_pos(dcr); /* update position */ } Dmsg1(200, "EOD dev->file=%d\n", file); return ok; }
uint32_t generic_tape_device::status_dev() { struct mtget mt_stat; uint32_t status = 0; if (state & (ST_EOT | ST_WEOT)) { status |= BMT_EOD; Pmsg0(-20, " EOD"); } if (state & ST_EOF) { status |= BMT_EOF; Pmsg0(-20, " EOF"); } status |= BMT_TAPE; Pmsg0(-20,_(" Bareos status:")); Pmsg2(-20,_(" file=%d block=%d\n"), file, block_num); if (d_ioctl(m_fd, MTIOCGET, (char *)&mt_stat) < 0) { berrno be; dev_errno = errno; Mmsg2(errmsg, _("ioctl MTIOCGET error on %s. ERR=%s.\n"), print_name(), be.bstrerror()); return 0; } Pmsg0(-20, _(" Device status:")); #if defined(HAVE_LINUX_OS) if (GMT_EOF(mt_stat.mt_gstat)) { status |= BMT_EOF; Pmsg0(-20, " EOF"); } if (GMT_BOT(mt_stat.mt_gstat)) { status |= BMT_BOT; Pmsg0(-20, " BOT"); } if (GMT_EOT(mt_stat.mt_gstat)) { status |= BMT_EOT; Pmsg0(-20, " EOT"); } if (GMT_SM(mt_stat.mt_gstat)) { status |= BMT_SM; Pmsg0(-20, " SM"); } if (GMT_EOD(mt_stat.mt_gstat)) { status |= BMT_EOD; Pmsg0(-20, " EOD"); } if (GMT_WR_PROT(mt_stat.mt_gstat)) { status |= BMT_WR_PROT; Pmsg0(-20, " WR_PROT"); } if (GMT_ONLINE(mt_stat.mt_gstat)) { status |= BMT_ONLINE; Pmsg0(-20, " ONLINE"); } if (GMT_DR_OPEN(mt_stat.mt_gstat)) { status |= BMT_DR_OPEN; Pmsg0(-20, " DR_OPEN"); } if (GMT_IM_REP_EN(mt_stat.mt_gstat)) { status |= BMT_IM_REP_EN; Pmsg0(-20, " IM_REP_EN"); } #elif defined(HAVE_WIN32) if (GMT_EOF(mt_stat.mt_gstat)) { status |= BMT_EOF; Pmsg0(-20, " EOF"); } if (GMT_BOT(mt_stat.mt_gstat)) { status |= BMT_BOT; Pmsg0(-20, " BOT"); } if (GMT_EOT(mt_stat.mt_gstat)) { status |= BMT_EOT; Pmsg0(-20, " EOT"); } if (GMT_EOD(mt_stat.mt_gstat)) { status |= BMT_EOD; Pmsg0(-20, " EOD"); } if (GMT_WR_PROT(mt_stat.mt_gstat)) { status |= BMT_WR_PROT; Pmsg0(-20, " WR_PROT"); } if (GMT_ONLINE(mt_stat.mt_gstat)) { status |= BMT_ONLINE; Pmsg0(-20, " ONLINE"); } if (GMT_DR_OPEN(mt_stat.mt_gstat)) { status |= BMT_DR_OPEN; Pmsg0(-20, " DR_OPEN"); } if (GMT_IM_REP_EN(mt_stat.mt_gstat)) { status |= BMT_IM_REP_EN; Pmsg0(-20, " IM_REP_EN"); } #endif /* HAVE_LINUX_OS || HAVE_WIN32 */ if (has_cap(CAP_MTIOCGET)) { Pmsg2(-20, _(" file=%d block=%d\n"), mt_stat.mt_fileno, mt_stat.mt_blkno); } else { Pmsg2(-20, _(" file=%d block=%d\n"), -1, -1); } return status; }