/* Modify the RecyclePool of a Volume */ void update_vol_recyclepool(UAContext *ua, char *val, MEDIA_DBR *mr) { POOL_DBR pr; POOL_MEM query(PM_MESSAGE); char ed1[50], ed2[50], *poolname; if(val && *val) { /* update volume recyclepool="Scratch" */ /* If a pool name is given, look up the PoolId */ memset(&pr, 0, sizeof(pr)); bstrncpy(pr.Name, val, sizeof(pr.Name)); if (!get_pool_dbr(ua, &pr, NT_("recyclepool"))) { return; } /* pool = select_pool_resource(ua); */ mr->RecyclePoolId = pr.PoolId; /* get the PoolId */ poolname = pr.Name; } else { /* update volume recyclepool="" */ /* If no pool name is given, set the PoolId to 0 (the default) */ mr->RecyclePoolId = 0; poolname = _("*None*"); } db_lock(ua->db); Mmsg(query, "UPDATE Media SET RecyclePoolId=%s WHERE MediaId=%s", edit_int64(mr->RecyclePoolId, ed1), edit_int64(mr->MediaId, ed2)); if (!db_sql_query(ua->db, query.c_str(), NULL, NULL)) { ua->error_msg("%s", db_strerror(ua->db)); } else { ua->info_msg(_("New RecyclePool is: %s\n"), poolname); } db_unlock(ua->db); }
bool VSSClient::GetShadowPath(const char *szFilePath, char *szShadowPath, int nBuflen) { if (!m_bBackupIsInitialized) return false; /* * Check for valid pathname */ bool bIsValidName; bIsValidName = strlen(szFilePath) > 3; if (bIsValidName) bIsValidName &= isalpha (szFilePath[0]) && szFilePath[1]==':' && szFilePath[2] == '\\'; if (bIsValidName) { int nDriveIndex = toupper(szFilePath[0])-'A'; if (m_szShadowCopyName[nDriveIndex][0] != 0) { if (WideCharToMultiByte(CP_UTF8,0,m_szShadowCopyName[nDriveIndex],-1,szShadowPath,nBuflen-1,NULL,NULL)) { nBuflen -= (int)strlen(szShadowPath); bstrncat(szShadowPath, szFilePath+2, nBuflen); return true; } } } bstrncpy(szShadowPath, szFilePath, nBuflen); errno = EINVAL; return false; }
static char *get_volume_name_from_SD(UAContext *ua, int Slot, int drive) { STORE *store = ua->jcr->wstore; BSOCK *sd; char dev_name[MAX_NAME_LENGTH]; char *VolName = NULL; int rtn_slot; if (!(sd=open_sd_bsock(ua))) { ua->error_msg(_("Could not open SD socket.\n")); return NULL; } bstrncpy(dev_name, store->dev_name(), sizeof(dev_name)); bash_spaces(dev_name); /* Ask for autochanger list of volumes */ sd->fsend(NT_("readlabel %s Slot=%d drive=%d\n"), dev_name, Slot, drive); Dmsg1(100, "Sent: %s", sd->msg); /* Get Volume name in this Slot */ while (sd->recv() >= 0) { ua->send_msg("%s", sd->msg); Dmsg1(100, "Got: %s", sd->msg); if (strncmp(sd->msg, NT_("3001 Volume="), 12) == 0) { VolName = (char *)malloc(sd->msglen); if (sscanf(sd->msg, NT_("3001 Volume=%s Slot=%d"), VolName, &rtn_slot) == 2) { break; } free(VolName); VolName = NULL; } } close_sd_bsock(ua); Dmsg1(100, "get_vol_name=%s\n", NPRT(VolName)); return VolName; }
/* * We get the number of drives in the changer from the SD */ int get_num_drives_from_SD(UAContext *ua) { STORE *store = ua->jcr->wstore; char dev_name[MAX_NAME_LENGTH]; BSOCK *sd; int drives = 0; if (!(sd=open_sd_bsock(ua))) { return 0; } bstrncpy(dev_name, store->dev_name(), sizeof(dev_name)); bash_spaces(dev_name); /* Ask for autochanger number of slots */ sd->fsend(NT_("autochanger drives %s\n"), dev_name); while (sd->recv() >= 0) { if (sscanf(sd->msg, NT_("drives=%d\n"), &drives) == 1) { break; } else { ua->send_msg("%s", sd->msg); } } close_sd_bsock(ua); // bsendmsg(ua, _("Device \"%s\" has %d drives.\n"), store->dev_name(), drives); return drives; }
/* * Check if the current line contains Storage="xxx", and compare the * result to the current storage. We use UAContext to analyse the bsr * string. * * Returns true if we need to change the storage, and it set the new * Storage resource name in "storage" arg. */ static inline bool check_for_new_storage(JCR *jcr, bootstrap_info &info) { UAContext *ua = info.ua; parse_ua_args(ua); if (ua->argc != 1) { return false; } if (bstrcasecmp(ua->argk[0], "Storage")) { /* * Continue if this is a volume from the same storage. */ if (is_on_same_storage(jcr, ua->argv[0])) { return false; } /* * Note the next storage name */ bstrncpy(info.storage, ua->argv[0], MAX_NAME_LENGTH); Dmsg1(5, "Change storage to %s\n", info.storage); return true; } return false; }
dlistString *new_dlistString(const char *str, int len) { dlistString *node; node = (dlistString *)malloc(sizeof(dlink) + len +1); bstrncpy(node->c_str(), str, len + 1); return node; }
static void displayString(const char *msg, int len, void *context) { /* Get class pointer from user data */ statusDialog *statDlg = (statusDialog *)context; const char *start = msg; const char *p; char *str; for (p=start; *p; p++) { if (*p == '\n') { int len = p - start; if (len > 0) { str = (char *)alloca(len + 1); bstrncpy(str, start, len + 1); SendMessage(statDlg->m_textWin, EM_SETSEL, (WPARAM)-1, (LPARAM)-1); SendMessage(statDlg->m_textWin, EM_REPLACESEL, 0, (LPARAM)str); } if (*p == '\n') { SendMessage(statDlg->m_textWin, EM_SETSEL, (WPARAM)-1, (LPARAM)-1); SendMessage(statDlg->m_textWin, EM_REPLACESEL, 0, (LPARAM)"\r\n"); } if (*p == '\0') { break; } start = p + 1; } } }
/* * Get or create a Client record for this Job */ bool get_or_create_client_record(JCR *jcr) { CLIENT_DBR cr; memset(&cr, 0, sizeof(cr)); bstrncpy(cr.Name, jcr->client->hdr.name, sizeof(cr.Name)); cr.AutoPrune = jcr->client->AutoPrune; cr.FileRetention = jcr->client->FileRetention; cr.JobRetention = jcr->client->JobRetention; if (!jcr->client_name) { jcr->client_name = get_pool_memory(PM_NAME); } pm_strcpy(jcr->client_name, jcr->client->hdr.name); if (!db_create_client_record(jcr, jcr->db, &cr)) { Jmsg(jcr, M_FATAL, 0, _("Could not create Client record. ERR=%s\n"), db_strerror(jcr->db)); return false; } jcr->jr.ClientId = cr.ClientId; if (cr.Uname[0]) { if (!jcr->client_uname) { jcr->client_uname = get_pool_memory(PM_NAME); } pm_strcpy(jcr->client_uname, cr.Uname); } Dmsg2(100, "Created Client %s record %d\n", jcr->client->hdr.name, jcr->jr.ClientId); return true; }
/* * Update pool record -- pull info from current POOL resource */ static bool update_pool(UAContext *ua) { POOL_DBR pr; int id; POOL *pool; POOLMEM *query; char ed1[50]; pool = get_pool_resource(ua); if (!pool) { return false; } memset(&pr, 0, sizeof(pr)); bstrncpy(pr.Name, pool->name(), sizeof(pr.Name)); if (!get_pool_dbr(ua, &pr)) { return false; } set_pooldbr_from_poolres(&pr, pool, POOL_OP_UPDATE); /* update */ set_pooldbr_references(ua->jcr, ua->db, &pr, pool); id = db_update_pool_record(ua->jcr, ua->db, &pr); if (id <= 0) { ua->error_msg(_("db_update_pool_record returned %d. ERR=%s\n"), id, db_strerror(ua->db)); } query = get_pool_memory(PM_MESSAGE); Mmsg(query, list_pool, edit_int64(pr.PoolId, ed1)); db_list_sql_query(ua->jcr, ua->db, query, prtit, ua, 1, HORZ_LIST); free_pool_memory(query); ua->info_msg(_("Pool DB record updated from resource.\n")); return true; }
/* Modify the Pool in which this Volume is located */ void update_vol_pool(UAContext *ua, char *val, MEDIA_DBR *mr, POOL_DBR *opr) { POOL_DBR pr; POOL_MEM query(PM_MESSAGE); char ed1[50], ed2[50]; memset(&pr, 0, sizeof(pr)); bstrncpy(pr.Name, val, sizeof(pr.Name)); if (!get_pool_dbr(ua, &pr)) { return; } mr->PoolId = pr.PoolId; /* set new PoolId */ /* */ db_lock(ua->db); Mmsg(query, "UPDATE Media SET PoolId=%s WHERE MediaId=%s", edit_int64(mr->PoolId, ed1), edit_int64(mr->MediaId, ed2)); if (!db_sql_query(ua->db, query.c_str(), NULL, NULL)) { ua->error_msg("%s", db_strerror(ua->db)); } else { ua->info_msg(_("New Pool is: %s\n"), pr.Name); opr->NumVols--; if (!db_update_pool_record(ua->jcr, ua->db, opr)) { ua->error_msg("%s", db_strerror(ua->db)); } pr.NumVols++; if (!db_update_pool_record(ua->jcr, ua->db, &pr)) { ua->error_msg("%s", db_strerror(ua->db)); } } db_unlock(ua->db); }
/* * Set the inchanger flag to zero for each slot marked in * the given slot_list. * * The vol_list passed here needs to be from an "autochanger listall" cmd. */ void update_inchanger_for_export(UAContext *ua, STORERES *store, dlist *vol_list, char *slot_list) { vol_list_t *vl; MEDIA_DBR mr; if (!open_client_db(ua)) { return; } /* * Walk through the list updating the media records */ foreach_dlist(vl, vol_list) { /* * We are only interested in normal slots. */ switch (vl->Type) { case slot_type_normal: break; default: continue; } /* * Only update entries of slots marked in the slot_list. */ if (!bit_is_set(vl->Slot - 1, slot_list)) { continue; } /* * Set InChanger to zero for this Slot */ memset(&mr, 0, sizeof(mr)); mr.Slot = vl->Slot; mr.InChanger = 1; mr.MediaId = 0; /* Get by VolumeName */ if (vl->VolName) { bstrncpy(mr.VolumeName, vl->VolName, sizeof(mr.VolumeName)); } else { mr.VolumeName[0] = 0; } set_storageid_in_mr(store, &mr); Dmsg4(100, "Before make unique: Vol=%s slot=%d inchanger=%d sid=%d\n", mr.VolumeName, mr.Slot, mr.InChanger, mr.StorageId); db_lock(ua->db); /* * Set InChanger to zero for this Slot */ db_make_inchanger_unique(ua->jcr, ua->db, &mr); db_unlock(ua->db); Dmsg4(100, "After make unique: Vol=%s slot=%d inchanger=%d sid=%d\n", mr.VolumeName, mr.Slot, mr.InChanger, mr.StorageId); } return; }
bool fstype(const char *fname, char *fs, int fslen) { struct statfs st; if (statfs((char *)fname, &st) == 0) { switch (st.f_type) { /* Known good values */ case 0xa: bstrncpy(fs, "advfs", fslen); return true; /* Tru64 AdvFS */ case 0xe: bstrncpy(fs, "nfs", fslen); return true; /* Tru64 NFS */ default: Dmsg2(10, "Unknown file system type \"0x%x\" for \"%s\".\n", st.f_type, fname); return false; } } Dmsg1(50, "statfs() failed for \"%s\"\n", fname); return false; }
bool dir_get_volume_info(DCR *dcr, enum get_vol_info_rw writing) { Dmsg0(100, "Fake dir_get_volume_info\n"); bstrncpy(dcr->VolCatInfo.VolCatName, dcr->VolumeName, sizeof(dcr->VolCatInfo.VolCatName)); dcr->VolCatInfo.VolCatParts = find_num_dvd_parts(dcr); Dmsg2(500, "Vol=%s num_parts=%d\n", dcr->VolCatInfo.VolCatName, dcr->VolCatInfo.VolCatParts); return 1; }
/* * This is where we pick up a client name to restore to. */ static int get_restore_client_name(UAContext *ua, RESTORE_CTX &rx) { /* Start with same name as backup client */ bstrncpy(rx.RestoreClientName, rx.ClientName, sizeof(rx.RestoreClientName)); /* try command line argument */ int i = find_arg_with_value(ua, NT_("restoreclient")); if (i >= 0) { if (!is_name_valid(ua->argv[i], &ua->errmsg)) { ua->error_msg("%s argument: %s", ua->argk[i], ua->errmsg); return 0; } bstrncpy(rx.RestoreClientName, ua->argv[i], sizeof(rx.RestoreClientName)); return 1; } return 1; }
/* Return Job variables */ PyObject *job_getattr(PyObject *self, char *attrname) { JCR *jcr; bool found = false; int i; char buf[10]; char errmsg[200]; Dmsg1(100, "In job_getattr=%s\n", attrname); jcr = get_jcr_from_PyObject(self); if (!jcr) { bstrncpy(errmsg, _("Job pointer not found."), sizeof(errmsg)); goto bail_out; } for (i=0; getvars[i].name; i++) { if (strcmp(getvars[i].name, attrname) == 0) { found = true; break; } } if (!found) { /* Try our methods */ return Py_FindMethod(JobMethods, self, attrname); } switch (i) { case 0: /* Job */ return Py_BuildValue((char *)getvars[i].fmt, jcr->job_name); /* Non-unique name */ case 1: /* SD's name */ return Py_BuildValue((char *)getvars[i].fmt, my_name); case 2: /* level */ return Py_BuildValue((char *)getvars[i].fmt, job_level_to_str(jcr->get_JobLevel())); case 3: /* type */ return Py_BuildValue((char *)getvars[i].fmt, job_type_to_str(jcr->get_JobType())); case 4: /* JobId */ return Py_BuildValue((char *)getvars[i].fmt, jcr->JobId); case 5: /* Client */ return Py_BuildValue((char *)getvars[i].fmt, jcr->client_name); case 6: /* Pool */ return Py_BuildValue((char *)getvars[i].fmt, jcr->dcr->pool_name); case 7: /* MediaType */ return Py_BuildValue((char *)getvars[i].fmt, jcr->dcr->media_type); case 8: /* JobName */ return Py_BuildValue((char *)getvars[i].fmt, jcr->Job); case 9: /* JobStatus */ buf[1] = 0; buf[0] = jcr->JobStatus; return Py_BuildValue((char *)getvars[i].fmt, buf); case 10: return Py_BuildValue((char *)getvars[i].fmt, jcr->dcr->VolumeName); case 11: return Py_BuildValue((char *)getvars[i].fmt, jcr->dcr->dev_name); } bsnprintf(errmsg, sizeof(errmsg), _("Attribute %s not found."), attrname); bail_out: PyErr_SetString(PyExc_AttributeError, errmsg); return NULL; }
/* * Authenticate Director */ bool BSOCK::authenticate_with_director(JCR *jcr, const char *name, s_password &password, tls_t &tls, char *response, int response_len) { char bashed_name[MAX_NAME_LENGTH]; BSOCK *dir = this; /* for readability */ response[0] = 0; /* * Send my name to the Director then do authentication */ bstrncpy(bashed_name, name, sizeof(bashed_name)); bash_spaces(bashed_name); /* * Timeout Hello after 5 mins */ dir->start_timer(60 * 5); dir->fsend(hello, bashed_name); if (!authenticate_outbound_connection(jcr, "Director", name, password, tls)) { goto bail_out; } Dmsg1(6, ">dird: %s", dir->msg); if (dir->recv() <= 0) { dir->stop_timer(); bsnprintf(response, response_len, _("Bad response to Hello command: ERR=%s\n" "The Director at \"%s:%d\" is probably not running.\n"), dir->bstrerror(), dir->host(), dir->port()); return false; } dir->stop_timer(); Dmsg1(10, "<dird: %s", dir->msg); if (!bstrncmp(dir->msg, OKhello, sizeof(OKhello) - 1)) { bsnprintf(response, response_len, _("Director at \"%s:%d\" rejected Hello command\n"), dir->host(), dir->port()); return false; } else { bsnprintf(response, response_len, "%s", dir->msg); } return true; bail_out: dir->stop_timer(); bsnprintf(response, response_len, _("Authorization problem with Director at \"%s:%d\"\n" "Most likely the passwords do not agree.\n" "If you are using TLS, there may have been a certificate " "validation error during the TLS handshake.\n" "Please see %s for help.\n"), dir->host(), dir->port(), MANUAL_AUTH_URL); return false; }
bool DCR::is_suitable_volume_mounted() { /* Volume mounted? */ if (dev->VolHdr.VolumeName[0] == 0 || dev->swap_dev || dev->must_unload()) { return false; /* no */ } bstrncpy(VolumeName, dev->VolHdr.VolumeName, sizeof(VolumeName)); return dir_get_volume_info(this, GET_VOL_INFO_FOR_WRITE); }
bool fstype(const char *fname, char *fs, int fslen) { struct statvfs st; if (statvfs(fname, &st) == 0) { bstrncpy(fs, st.f_fstypename, fslen); return true; } Dmsg1(50, "statfs() failed for \"%s\"\n", fname); return false; }
/* * Setup a "daemon" JCR for the various standalone * tools (e.g. bls, bextract, bscan, ...) */ JCR *setup_jcr(const char *name, char *dev_name, BSR *bsr, DIRRES *director, const char *VolumeName, int mode) { DCR *dcr; JCR *jcr = new_jcr(sizeof(JCR), my_free_jcr); jcr->bsr = bsr; jcr->director = director; jcr->VolSessionId = 1; jcr->VolSessionTime = (uint32_t)time(NULL); jcr->NumReadVolumes = 0; jcr->NumWriteVolumes = 0; jcr->JobId = 0; jcr->setJobType(JT_CONSOLE); jcr->setJobLevel(L_FULL); jcr->JobStatus = JS_Terminated; jcr->where = bstrdup(""); jcr->job_name = get_pool_memory(PM_FNAME); pm_strcpy(jcr->job_name, "Dummy.Job.Name"); jcr->client_name = get_pool_memory(PM_FNAME); pm_strcpy(jcr->client_name, "Dummy.Client.Name"); bstrncpy(jcr->Job, name, sizeof(jcr->Job)); jcr->fileset_name = get_pool_memory(PM_FNAME); pm_strcpy(jcr->fileset_name, "Dummy.fileset.name"); jcr->fileset_md5 = get_pool_memory(PM_FNAME); pm_strcpy(jcr->fileset_md5, "Dummy.fileset.md5"); new_plugins(jcr); /* instantiate plugins */ init_autochangers(); create_volume_lists(); dcr = setup_to_access_device(jcr, dev_name, VolumeName, mode); if (!dcr) { return NULL; } if (!bsr && VolumeName) { bstrncpy(dcr->VolumeName, VolumeName, sizeof(dcr->VolumeName)); } bstrncpy(dcr->pool_name, "Default", sizeof(dcr->pool_name)); bstrncpy(dcr->pool_type, "Backup", sizeof(dcr->pool_type)); return jcr; }
/* * Create a Job Control Record and link it into JCR chain * Returns newly allocated JCR * Note, since each daemon has a different JCR, he passes * us the size. */ JCR *new_jcr(int size, JCR_free_HANDLER *daemon_free_jcr) { JCR *jcr; MQUEUE_ITEM *item = NULL; struct sigaction sigtimer; int status; Dmsg0(dbglvl, "Enter new_jcr\n"); status = pthread_once(&key_once, create_jcr_key); if (status != 0) { berrno be; Jmsg1(NULL, M_ABORT, 0, _("pthread_once failed. ERR=%s\n"), be.bstrerror(status)); } jcr = (JCR *)malloc(size); memset(jcr, 0, size); jcr->my_thread_id = pthread_self(); jcr->msg_queue = New(dlist(item, &item->link)); jcr->job_end_push.init(1, false); jcr->sched_time = time(NULL); jcr->daemon_free_jcr = daemon_free_jcr; /* plug daemon free routine */ jcr->init_mutex(); jcr->inc_use_count(); jcr->VolumeName = get_pool_memory(PM_FNAME); jcr->VolumeName[0] = 0; jcr->errmsg = get_pool_memory(PM_MESSAGE); jcr->errmsg[0] = 0; /* Setup some dummy values */ bstrncpy(jcr->Job, "*System*", sizeof(jcr->Job)); jcr->JobId = 0; jcr->set_JobType(JT_SYSTEM); /* internal job until defined */ jcr->set_JobLevel(L_NONE); set_jcr_job_status(jcr, JS_Created); /* ready to run */ set_jcr_in_tsd(jcr); sigtimer.sa_flags = 0; sigtimer.sa_handler = timeout_handler; sigfillset(&sigtimer.sa_mask); sigaction(TIMEOUT_SIGNAL, &sigtimer, NULL); /* * Locking jobs is a global lock that is needed * so that the Director can stop new jobs from being * added to the jcr chain while it processes a new * conf file and does the job_end_push(). */ lock_jobs(); lock_jcr_chain(); if (!jcrs) { jcrs = New(dlist(jcr, &jcr->link)); } jcrs->append(jcr); unlock_jcr_chain(); unlock_jobs(); return jcr; }
/* * create_volume_label_record * Serialize label (from dev->VolHdr structure) into device record. * Assumes that the dev->VolHdr structure is properly * initialized. */ static void create_volume_label_record(DCR *dcr, DEVICE *dev, DEV_RECORD *rec) { ser_declare; struct date_time dt; JCR *jcr = dcr->jcr; char buf[100]; /* Serialize the label into the device record. */ rec->data = check_pool_memory_size(rec->data, SER_LENGTH_Volume_Label); ser_begin(rec->data, SER_LENGTH_Volume_Label); ser_string(dev->VolHdr.Id); ser_uint32(dev->VolHdr.VerNum); if (dev->VolHdr.VerNum >= 11) { ser_btime(dev->VolHdr.label_btime); dev->VolHdr.write_btime = get_current_btime(); ser_btime(dev->VolHdr.write_btime); dev->VolHdr.write_date = 0; dev->VolHdr.write_time = 0; } else { /* OLD WAY DEPRECATED */ ser_float64(dev->VolHdr.label_date); ser_float64(dev->VolHdr.label_time); get_current_time(&dt); dev->VolHdr.write_date = dt.julian_day_number; dev->VolHdr.write_time = dt.julian_day_fraction; } ser_float64(dev->VolHdr.write_date); /* 0 if VerNum >= 11 */ ser_float64(dev->VolHdr.write_time); /* 0 if VerNum >= 11 */ ser_string(dev->VolHdr.VolumeName); ser_string(dev->VolHdr.PrevVolumeName); ser_string(dev->VolHdr.PoolName); ser_string(dev->VolHdr.PoolType); ser_string(dev->VolHdr.MediaType); ser_string(dev->VolHdr.HostName); ser_string(dev->VolHdr.LabelProg); ser_string(dev->VolHdr.ProgVersion); ser_string(dev->VolHdr.ProgDate); ser_end(rec->data, SER_LENGTH_Volume_Label); bstrncpy(dcr->VolumeName, dev->VolHdr.VolumeName, sizeof(dcr->VolumeName)); rec->data_len = ser_length(rec->data); rec->FileIndex = dev->VolHdr.LabelType; rec->VolSessionId = jcr->VolSessionId; rec->VolSessionTime = jcr->VolSessionTime; rec->Stream = jcr->NumWriteVolumes; rec->maskedStream = jcr->NumWriteVolumes; Dmsg2(150, "Created Vol label rec: FI=%s len=%d\n", FI_to_ascii(buf, rec->FileIndex), rec->data_len); }
/* * IF volume status is Append, Full, Used, or Error, mark it Purged * Purged volumes can then be recycled (if enabled). */ bool mark_media_purged(UAContext *ua, MEDIA_DBR *mr) { JCR *jcr = ua->jcr; bool status; status = bstrcmp(mr->VolStatus, "Append") || bstrcmp(mr->VolStatus, "Full") || bstrcmp(mr->VolStatus, "Used") || bstrcmp(mr->VolStatus, "Error"); if (status) { bstrncpy(mr->VolStatus, "Purged", sizeof(mr->VolStatus)); set_storageid_in_mr(NULL, mr); if (!db_update_media_record(jcr, ua->db, mr)) { return false; } pm_strcpy(jcr->VolumeName, mr->VolumeName); generate_plugin_event(jcr, bDirEventVolumePurged); /* * If the RecyclePool is defined, move the volume there */ if (mr->RecyclePoolId && mr->RecyclePoolId != mr->PoolId) { POOL_DBR oldpr, newpr; memset(&oldpr, 0, sizeof(POOL_DBR)); memset(&newpr, 0, sizeof(POOL_DBR)); newpr.PoolId = mr->RecyclePoolId; oldpr.PoolId = mr->PoolId; if ( db_get_pool_record(jcr, ua->db, &oldpr) && db_get_pool_record(jcr, ua->db, &newpr)) { /* check if destination pool size is ok */ if (newpr.MaxVols > 0 && newpr.NumVols >= newpr.MaxVols) { ua->error_msg(_("Unable move recycled Volume in full " "Pool \"%s\" MaxVols=%d\n"), newpr.Name, newpr.MaxVols); } else { /* move media */ update_vol_pool(ua, newpr.Name, mr, &oldpr); } } else { ua->error_msg("%s", db_strerror(ua->db)); } } /* Send message to Job report, if it is a *real* job */ if (jcr && jcr->JobId > 0) { Jmsg(jcr, M_INFO, 0, _("All records pruned from Volume \"%s\"; marking it \"Purged\"\n"), mr->VolumeName); } return true; } else { ua->error_msg(_("Cannot purge Volume with VolStatus=%s\n"), mr->VolStatus); } return bstrcmp(mr->VolStatus, "Purged"); }
/* * This is called during restore to create the file (if necessary) * We must return in rp->create_status: * * CF_ERROR -- error * CF_SKIP -- skip processing this file * CF_EXTRACT -- extract the file (i.e.call i/o routines) * CF_CREATED -- created, but no content to extract (typically directories) * */ static bRC createFile(bpContext *ctx, struct restore_pkt *rp) { // printf("bpipe-fd: createFile\n"); if (strlen(rp->where) > 512) { printf("Restore target dir too long. Restricting to first 512 bytes.\n"); } bstrncpy(((struct plugin_ctx *)ctx->pContext)->where, rp->where, 513); ((struct plugin_ctx *)ctx->pContext)->replace = rp->replace; rp->create_status = CF_EXTRACT; return bRC_OK; }
static bool create_simple_name(JCR *jcr, MEDIA_DBR *mr, POOL_DBR *pr) { char num[20]; db_int64_ctx ctx; POOL_MEM query(PM_MESSAGE), name(PM_NAME); char ed1[50]; /* See if volume already exists */ mr->VolumeName[0] = 0; pm_strcpy(name, pr->LabelFormat); ctx.value = 0; Mmsg(query, "SELECT MAX(MediaId) FROM Media,Pool WHERE Pool.PoolId=%s", edit_int64(pr->PoolId, ed1)); if (!db_sql_query(jcr->db, query.c_str(), db_int64_handler, (void *)&ctx)) { Jmsg(jcr, M_WARNING, 0, _("SQL failed, but ignored. ERR=%s\n"), db_strerror(jcr->db)); ctx.value = pr->NumVols+1; } for (int i=(int)ctx.value+1; i<(int)ctx.value+100; i++) { MEDIA_DBR tmr; memset(&tmr, 0, sizeof(tmr)); sprintf(num, "%04d", i); bstrncpy(tmr.VolumeName, name.c_str(), sizeof(tmr.VolumeName)); bstrncat(tmr.VolumeName, num, sizeof(tmr.VolumeName)); if (db_get_media_record(jcr, jcr->db, &tmr)) { Jmsg(jcr, M_WARNING, 0, _("Wanted to create Volume \"%s\", but it already exists. Trying again.\n"), tmr.VolumeName); continue; } bstrncpy(mr->VolumeName, name.c_str(), sizeof(mr->VolumeName)); bstrncat(mr->VolumeName, num, sizeof(mr->VolumeName)); break; /* Got good name */ } if (mr->VolumeName[0] == 0) { Jmsg(jcr, M_ERROR, 0, _("Too many failures. Giving up creating Volume name.\n")); return false; } return true; }
/* * Mark volume in error in catalog */ void DCR::mark_volume_in_error() { Jmsg(jcr, M_INFO, 0, _("Marking Volume \"%s\" in Error in Catalog.\n"), VolumeName); dev->VolCatInfo = VolCatInfo; /* structure assignment */ bstrncpy(dev->VolCatInfo.VolCatStatus, "Error", sizeof(dev->VolCatInfo.VolCatStatus)); Dmsg0(150, "dir_update_vol_info. Set Error.\n"); dir_update_volume_info(this, false, false); volume_unused(this); Dmsg0(50, "set_unload\n"); dev->set_unload(); /* must get a new volume */ }
/* * Perform full substitution on Label */ static bool perform_full_name_substitution(JCR *jcr, MEDIA_DBR *mr, POOL_DBR *pr) { bool ok = false; POOLMEM *label = get_pool_memory(PM_FNAME); jcr->NumVols = pr->NumVols; if (variable_expansion(jcr, pr->LabelFormat, &label)) { bstrncpy(mr->VolumeName, label, sizeof(mr->VolumeName)); ok = true; } free_pool_memory(label); return ok; }
static void mark_row(int row, bool mark) { char *file; int len; char new_mark[10]; gtk_clist_get_text(restore->list, row, FILE_COLUMN, &file); if (mark) { bstrncpy(new_mark, "x", sizeof(new_mark)); len = Mmsg(&restore->buf, "mark %s", file); } else { bstrncpy(new_mark, " ", sizeof(new_mark)); len = Mmsg(&restore->buf, "unmark %s", file); } gtk_clist_set_text(restore->list, row, CHECK_COLUMN, new_mark); /* strip trailing slash from directory name */ while (len > 1 && restore->buf[len-1] == '/') { restore->buf[len-1] = 0; } write_director(restore->buf); discard_to_prompt(); }
static bool ini_store_name(LEX *lc, ConfigFile *inifile, ini_items *item) { if (!lc) { Mmsg(inifile->edit, "%s", item->val.nameval); return true; } if (lex_get_token(lc, T_NAME) == T_ERROR) { return false; } bstrncpy(item->val.nameval, lc->str, sizeof(item->val.nameval)); scan_to_eol(lc); return true; }
/* * 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 */ switch (rec->maskedStream) { case STREAM_UNIX_ATTRIBUTES: case STREAM_UNIX_ATTRIBUTES_EX: if (!unpack_attributes_record(jcr, rec->Stream, rec->data, rec->data_len, attr)) { if (!forge_on) { Emsg0(M_ERROR_TERM, 0, _("Cannot continue.\n")); } else { Emsg0(M_ERROR, 0, _("Attrib unpack error!\n")); } num_files++; return true; } attr->data_stream = decode_stat(attr->attr, &attr->statp, sizeof(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++; } break; case STREAM_PLUGIN_NAME: { char data[100]; int len = MIN(rec->data_len+1, sizeof(data)); bstrncpy(data, rec->data, len); Pmsg1(000, "Plugin data: %s\n", data); break; } case STREAM_RESTORE_OBJECT: Pmsg0(000, "Restore Object record\n"); break; default: break; } return true; }
/* * Open the bootstrap file and find the first Storage= * Returns ok if able to open * * It fills the storage name (should be the first line) * and the file descriptor to the bootstrap file, * it should be used for next operations, and need to be * closed at the end. */ bool open_bootstrap_file(JCR *jcr, bootstrap_info &info) { FILE *bs; UAContext *ua; info.bs = NULL; info.ua = NULL; if (!jcr->RestoreBootstrap) { return false; } bstrncpy(info.storage, jcr->res.rstore->name(), MAX_NAME_LENGTH); bs = fopen(jcr->RestoreBootstrap, "rb"); if (!bs) { berrno be; Jmsg(jcr, M_FATAL, 0, _("Could not open bootstrap file %s: ERR=%s\n"), jcr->RestoreBootstrap, be.bstrerror()); jcr->setJobStatus(JS_ErrorTerminated); return false; } ua = new_ua_context(jcr); ua->cmd = check_pool_memory_size(ua->cmd, UA_CMD_SIZE + 1); while (!fgets(ua->cmd, UA_CMD_SIZE, bs)) { parse_ua_args(ua); if (ua->argc != 1) { continue; } if (bstrcasecmp(ua->argk[0], "Storage")) { bstrncpy(info.storage, ua->argv[0], MAX_NAME_LENGTH); break; } } info.bs = bs; info.ua = ua; fseek(bs, 0, SEEK_SET); /* return to the top of the file */ return true; }