void MyFrame::UpdateControls() { bLoadingItems = true; auto allAttrs = m_engine->GetAllDictionaryAttrs(); for (auto it = allAttrs->begin(); it != allAttrs->end(); it++) { if (it->second->GetValueChanged()) SetControlUI(it->second); } bLoadingItems = false; UpdateCatalog(); #ifdef USEDEBUGGER if (m_debugger) m_debugger->Update(); #endif }
// Create new PDF file and append changed or new annotations bool AnnotWriter::WriteTo(const char* name) { if (!CopyFile(name)) return false; if (!mAnnots.HasChanged()) return true; AssignShortFontNames(); mFile = fopen(name, "a+b"); bool ok = mFile != NULL; int numPages = mDoc->getNumPages(); for (int i = 0; ok && i < numPages; i ++) { mPageRef = *mDoc->getCatalog()->getPageRef(i+1); Annotations* a = mAnnots.Get(i); if (a && a->HasChanged()) { Ref annotArray; ok = ok && UpdatePage(i, a, annotArray); ok = ok && UpdateAnnotArray(i, a, annotArray); for (int j = 0; ok && j < a->Length(); j ++) { Annotation* an = a->At(j); if (!an->IsDeleted()) { if (CanWrite(an)) { ok = UpdateAnnot(an); } } else { if (!is_empty_ref(an->GetRef())) { mXRefTable.DeleteRef(an->GetRef()); } } } } } if (ok) { UpdateInfoDict(); UpdateBePDFAcroForm(); UpdateCatalog(); ok = WriteXRefTable(); ok = ok && WriteFileTrailer(); } if (mFile) { fclose(mFile); mFile = NULL; } if (!ok) { // delete file on error unlink(name); } UnassignShortFontNames(); return ok; }
/* * clean_3570 - attempt to load cleaning tape into 3570. */ void clean_3570( drive_state_t *drive, robo_event_t *event, struct CatalogEntry *ce) { int retry; char *dev_name; char *d_mess = drive->un->dis_mes[DIS_MES_NORM]; dev_ent_t *un = drive->un; library_t *library = drive->library; move_flags_t move_flags; mutex_lock(&drive->mutex); move_flags.bits = 0; /* * The 3570 does not return from the move until the cleaning cycle * has completed. */ memccpy(d_mess, catgets(catfd, SET, 9030, "wait for cleaning cycle"), '\0', DIS_MES_LEN); if (generic_get_media(library, drive, event, ce)) { memccpy(drive->un->dis_mes[DIS_MES_CRIT], catgets(catfd, SET, 9029, "unable to load cleaning cartridge, move failed"), '\0', DIS_MES_LEN); DevLog(DL_ERR(5145), ce->CeSlot); down_drive(drive, SAM_STATE_CHANGE); drive->status.b.cln_inprog = FALSE; mutex_unlock(&drive->mutex); disp_of_event(library, event, EIO); return; } mutex_unlock(&drive->mutex); sleep(4); dev_name = samst_devname(un); mutex_lock(&un->mutex); drive->open_fd = open_unit(un, dev_name, 10); mutex_unlock(&un->mutex); free(dev_name); un->i.ViEq = un->fseq; un->i.ViSlot = un->slot; un->i.ViPart = 0; un->i.ViFlags = VI_cart; UpdateCatalog(drive->un, 0, CatalogVolumeLoaded); /* Wait for cleaning to finish */ retry = 60; while (retry--) { sam_extended_sense_t *sense = (sam_extended_sense_t *) SHM_REF_ADDR(un->sense); mutex_lock(&un->io_mutex); memset(sense, 0, sizeof (sam_extended_sense_t)); if (scsi_cmd(drive->open_fd, un, SCMD_TEST_UNIT_READY, 20) || sense->es_key != 0) { /* If cleaning in progress */ if (sense->es_key == 0x02 && sense->es_add_code == 0x30 && sense->es_qual_code == 0x03) { mutex_unlock(&un->io_mutex); sleep(30); continue; } if (sense->es_key == 0x06 && sense->es_add_code == 0x82 && sense->es_qual_code == 0x83) break; mutex_unlock(&un->io_mutex); sprintf(d_mess, "sense %x, %x, %x", sense->es_key, sense->es_add_code, sense->es_qual_code); sleep(10); } } if (retry <= 0) DevLog(DL_ERR(5216)); memccpy(d_mess, catgets(catfd, SET, 9034, "drive has been cleaned"), '\0', DIS_MES_LEN); mutex_unlock(&un->io_mutex); mutex_lock(&un->mutex); close_unit(un, &drive->open_fd); mutex_unlock(&un->mutex); mutex_lock(&drive->mutex); move_flags.bits = 0; memccpy(d_mess, catgets(catfd, SET, 9009, "waiting for media changer"), '\0', DIS_MES_LEN); if (move_media(library, 0, drive->element, 0xff, 1, move_flags)) { memccpy(drive->un->dis_mes[DIS_MES_CRIT], catgets(catfd, SET, 9032, "unable to unload cleaning cartridge"), '\0', DIS_MES_LEN); DevLog(DL_ERR(5147)); drive->status.b.cln_inprog = FALSE; down_drive(drive, SAM_STATE_CHANGE); mutex_unlock(&drive->mutex); disp_of_event(library, event, EIO); return; } if (CatalogVolumeUnloaded(&un->i, "") == -1) { DevLog(DL_SYSERR(5336), ce->CeSlot); } drive->status.b.cln_inprog = FALSE; mutex_lock(&drive->un->mutex); drive->un->status.bits &= ~(DVST_CLEANING | DVST_REQUESTED); un->label_time = 0; mutex_unlock(&drive->un->mutex); mutex_unlock(&drive->mutex); disp_of_event(library, event, 0); }
/* * audit - start auditing * * */ void audit( drive_state_t *drive, /* drive state pointer */ const uint_t slot, /* slot to audit */ const int audit_eod) { /* flag to find eod during audit */ int part, err; uint_t myslot = 0; dev_ent_t *un; sam_defaults_t *defaults; struct CatalogEntry ced; struct CatalogEntry *ce = &ced; int skip_audit_eod = 0; defaults = GetDefaults(); SANITY_CHECK(drive != (drive_state_t *)0); SANITY_CHECK(drive->library != (library_t *)0); SANITY_CHECK(drive->library->un != (dev_ent_t *)0); SANITY_CHECK(drive->library->un != drive->un); un = drive->un; if ((slot == ROBOT_NO_SLOT) && IS_GENERIC_API(drive->library->un->type)) { DevLog(DL_ERR(6004)); return; } mutex_lock(&drive->mutex); if (drive->status.b.full) { mutex_lock(&un->mutex); un->status.b.requested = TRUE; mutex_unlock(&un->mutex); if (clear_drive(drive)) { mutex_lock(&un->mutex); un->status.b.requested = TRUE; mutex_unlock(&un->mutex); mutex_unlock(&drive->mutex); return; } if (drive->open_fd >= 0) { mutex_lock(&un->mutex); close_unit(un, &drive->open_fd); DEC_OPEN(un); mutex_unlock(&un->mutex); } } mutex_unlock(&drive->mutex); mutex_lock(&un->mutex); un->status.b.requested = TRUE; un->status.b.labeled = FALSE; un->status.b.ready = FALSE; mutex_unlock(&un->mutex); if (slot == ROBOT_NO_SLOT) { mutex_lock(&drive->library->mutex); drive->library->countdown--; drive->library->drives_auditing++; mutex_unlock(&drive->library->mutex); /* * ok not to lock here wait for all drives to clear */ while (drive->library->countdown > 0) sleep(4); } for (;;) { mutex_lock(&drive->mutex); if (slot == ROBOT_NO_SLOT) { /* get the next slot number (s) */ mutex_lock(&drive->library->mutex); myslot = drive->library->audit_index; if (myslot <= drive->library->range.storage_count) { drive->library->audit_index++; mutex_unlock(&drive->library->mutex); } else { /* No more slots to audit */ mutex_unlock(&drive->library->mutex); mutex_lock(&drive->library->un->mutex); drive->library->un->status.b.mounted = TRUE; drive->library->un->status.b.audit = FALSE; drive->library->un->status.b.ready = TRUE; mutex_unlock(&drive->library->un->mutex); if (drive->status.b.full) { clear_drive(drive); if (drive->open_fd >= 0) mutex_lock(&un->mutex); close_unit(un, &drive->open_fd); mutex_unlock(&un->mutex); } mutex_lock(&un->mutex); un->status.b.requested = FALSE; mutex_unlock(&un->mutex); mutex_unlock(&drive->mutex); return; } } else { /* get specific slot */ myslot = slot; } /* * Should we audit this media? (is occupied, not cleaning and * is a sam tape) */ if (drive->library->status.b.two_sided) { part = 1; } else { part = 0; } ce = CatalogGetCeByLoc(drive->library->un->eq, myslot, part, &ced); if (ce == NULL || (!(ce->CeStatus & CES_occupied)) || (ce->CeStatus & CES_cleaning) || (ce->CeStatus & CES_non_sam)) { mutex_unlock(&drive->mutex); if (slot != ROBOT_NO_SLOT) { /* only one slot */ mutex_lock(&un->mutex); un->status.b.requested = FALSE; mutex_unlock(&un->mutex); return; } continue; } /* * The following lines of code get a tape mounted, or if * two-sided media, mounts the "A" side. */ err = get_media(drive->library, drive, NULL, ce); if (err) { mutex_lock(&un->mutex); un->status.b.requested = FALSE; DEC_ACTIVE(un); mutex_unlock(&un->mutex); mutex_unlock(&drive->mutex); return; } mutex_lock(&un->mutex); un->status.b.scanning = TRUE; mutex_unlock(&un->mutex); if (spin_drive(drive, SPINUP, NOEJECT)) { mutex_lock(&drive->un->mutex); drive->un->status.b.scanning &= ~DVST_SCANNING; drive->un->status.bits &= ~DVST_REQUESTED; mutex_unlock(&drive->un->mutex); if (un->state > DEV_ON) { clear_drive(drive); mutex_lock(&un->mutex); clear_driver_idle(drive, drive->open_fd); DEC_ACTIVE(un); close_unit(un, &drive->open_fd); mutex_unlock(&un->mutex); mutex_unlock(&drive->mutex); } else { mutex_lock(&un->mutex); clear_driver_idle(drive, drive->open_fd); DEC_ACTIVE(un); close_unit(un, &drive->open_fd); mutex_unlock(&un->mutex); mutex_unlock(&drive->mutex); } SendCustMsg(HERE, 9348); DevLog(DL_ERR(5218)); return; } un->status.bits |= DVST_AUDIT; un->mid = ce->CeMid; un->status.b.labeled = FALSE; un->i.ViPart = ce->CePart; scan_a_device(un, drive->open_fd); if (drive->status.b.bar_code) { (void) CatalogSetStringByLoc(drive->library->un->eq, ce->CeSlot, ce->CePart, CEF_BarCode, (char *)drive->bar_code); } /* * If the cleaning light came on while scanning, leave the * audit bit set and unload the drive. */ if (un->status.bits & DVST_CLEANING) { mutex_lock(&un->mutex); un->mtime = 0; DEC_ACTIVE(un); close_unit(un, &drive->open_fd); un->status.b.requested = FALSE; mutex_unlock(&un->mutex); clear_drive(drive); mutex_unlock(&drive->mutex); return; } else { un->status.bits &= ~DVST_AUDIT; } mutex_lock(&un->mutex); /* * This next check keeps us from auditing media that is not * really labeled (label lie). I'm not sure why the un->mutex * is held for this. */ if (!un->status.b.labeled && (ce->CeStatus & CES_bar_code) && (defaults->flags & DF_LABEL_BARCODE)) { int tmp; if (IS_TAPE(un)) { tmp = LEN_TAPE_VSN; } else { tmp = LEN_OPTIC_VSN; } vsn_from_barcode(un->vsn, ce->CeBarCode, defaults, tmp); un->status.b.labeled = TRUE; un->space = un->capacity; skip_audit_eod = 1; } if (IS_TAPE(un)) { if (un->status.b.labeled && audit_eod && !skip_audit_eod) { DevLog(DL_DETAIL(5074), un->vsn); mutex_unlock(&un->mutex); mutex_lock(&un->io_mutex); tape_append(drive->open_fd, un, NULL); mutex_unlock(&un->io_mutex); mutex_lock(&un->mutex); } else { if (!un->status.b.labeled) { un->space = un->capacity; } else { un->space = ce->CeSpace; } } } UpdateCatalog(un, 0, CatalogVolumeLoaded); /* * Now do the "B" side if this is optical media. * flip_and_scan calls CatalogVolumeLoaded so it is not done * here. */ if (drive->library->status.b.two_sided && (ce->CePart == 1)) { mutex_unlock(&un->mutex); if (flip_and_scan(ce->CePart, drive)) { clear_drive(drive); mutex_lock(&un->mutex); un->status.b.requested = FALSE; clear_driver_idle(drive, drive->open_fd); close_unit(un, &drive->open_fd); DEC_ACTIVE(un); mutex_unlock(&un->mutex); mutex_unlock(&drive->mutex); return; } mutex_unlock(&drive->mutex); } else { mutex_unlock(&un->mutex); mutex_unlock(&drive->mutex); } mutex_lock(&un->mutex); close_unit(un, &drive->open_fd); DEC_ACTIVE(un); un->status.b.requested = TRUE; mutex_unlock(&un->mutex); if (slot != ROBOT_NO_SLOT) { /* only one slot */ mutex_lock(&un->mutex); un->status.b.requested = FALSE; mutex_unlock(&un->mutex); mutex_lock(&drive->library->un->mutex); drive->library->un->status.b.mounted = TRUE; mutex_unlock(&drive->library->un->mutex); return; } } }