int pm_strcpy(POOLMEM *&pm, POOL_MEM &str) { int len = strlen(str.c_str()) + 1; pm = check_pool_memory_size(pm, len); memcpy(pm, str.c_str(), len); return len - 1; }
int pm_strcat(POOLMEM *&pm, POOL_MEM &str) { int pmlen = strlen(pm); int len = strlen(str.c_str()) + 1; pm = check_pool_memory_size(pm, pmlen + len); memcpy(pm+pmlen, str.c_str(), len); return pmlen + len - 1; }
/* * Edit codes into (Un)MountCommand, Write(First)PartCommand * %% = % * %a = archive device name * %e = erase (set if cannot mount and first part) * %n = part number * %m = mount point * %v = last part name * * omsg = edited output message * imsg = input string containing edit codes (%x) * */ void DEVICE::edit_mount_codes(POOL_MEM &omsg, const char *imsg) { const char *p; const char *str; char add[20]; POOL_MEM archive_name(PM_FNAME); omsg.c_str()[0] = 0; Dmsg1(800, "edit_mount_codes: %s\n", imsg); for (p=imsg; *p; p++) { if (*p == '%') { switch (*++p) { case '%': str = "%"; break; case 'a': str = dev_name; break; case 'e': if (num_dvd_parts == 0) { if (truncating || blank_dvd) { str = "2"; } else { str = "1"; } } else { str = "0"; } break; case 'n': bsnprintf(add, sizeof(add), "%d", part); str = add; break; case 'm': str = device->mount_point; break; default: add[0] = '%'; add[1] = *p; add[2] = 0; str = add; break; } } else { add[0] = *p; add[1] = 0; str = add; } Dmsg1(1900, "add_str %s\n", str); pm_strcat(omsg, (char *)str); Dmsg1(1800, "omsg=%s\n", omsg.c_str()); } }
int pm_strcat(POOL_MEM &pm, const char *str) { int pmlen = strlen(pm.c_str()); int len; if (!str) str = ""; len = strlen(str) + 1; pm.check_size(pmlen + len); memcpy(pm.c_str()+pmlen, str, len); return pmlen + len - 1; }
bool CONFIG::get_path_of_new_resource(POOL_MEM &path, POOL_MEM &extramsg, const char *component, const char *resourcetype, const char *name, bool error_if_exists, bool create_directories) { POOL_MEM rel_path(PM_FNAME); POOL_MEM directory(PM_FNAME); POOL_MEM resourcetype_lowercase(resourcetype); resourcetype_lowercase.toLower(); if (!get_path_of_resource(path, component, resourcetype, name, false)) { return false; } path_get_directory(directory, path); if (create_directories) { path_create(directory); } if (!path_exists(directory)) { extramsg.bsprintf("Resource config directory \"%s\" does not exist.\n", directory.c_str()); return false; } /* * Store name for temporary file in extramsg. * Can be used, if result is true. * Otherwise it contains an error message. */ extramsg.bsprintf("%s.tmp", path.c_str()); if (!error_if_exists) { return true; } /* * File should not exists, as it is going to be created. */ if (path_exists(path)) { extramsg.bsprintf("Resource config file \"%s\" already exists.\n", path.c_str()); return false; } if (path_exists(extramsg)) { extramsg.bsprintf("Temporary resource config file \"%s.tmp\" already exists.\n", path.c_str()); return false; } return true; }
/* * Dump contents of resource */ void dump_resource(int type, RES *reshdr, void sendit(void *sock, const char *fmt, ...), void *sock, bool hide_sensitive_data) { POOL_MEM buf; URES *res = (URES *)reshdr; BRSRES *resclass; bool recurse = true; if (res == NULL) { sendit(sock, _("Warning: no \"%s\" resource (%d) defined.\n"), res_to_str(type), type); return; } if (type < 0) { /* no recursion */ type = - type; recurse = false; } switch (type) { default: resclass = (BRSRES *)reshdr; resclass->print_config(buf); break; } sendit(sock, "%s", buf.c_str()); if (recurse && res->res_dir.hdr.next) { dump_resource(type, res->res_dir.hdr.next, sendit, sock, hide_sensitive_data); } }
void OUTPUT_FORMATTER::json_finalize_result(bool result) { POOL_MEM string; json_t *msg_obj = json_object(); json_t *error_obj; /* * We mimic json-rpc result and error messages, * To make it easier to implement real json-rpc later on. */ json_object_set(msg_obj, "jsonrpc", json_string("2.0")); json_object_set(msg_obj, "id", json_null()); if (result) { json_object_set(msg_obj, "result", result_array_json); } else { error_obj = json_object(); json_object_set_new(error_obj, "code", json_integer(1)); json_object_set_new(error_obj, "message", json_string("failed")); json_object_set(error_obj, "data", result_array_json); json_object_set_new(msg_obj, "error", error_obj); } string.bsprintf("%s\n", json_dumps(msg_obj, UA_JSON_FLAGS)); send_func(send_ctx, string.c_str()); json_array_clear(result_array_json); json_object_clear(msg_obj); }
static void add_file_and_part_name(DEVICE *dev, POOL_MEM &archive_name) { char partnumber[20]; if (!IsPathSeparator(archive_name.c_str()[strlen(archive_name.c_str())-1])) { pm_strcat(archive_name, "/"); } pm_strcat(archive_name, dev->getVolCatName()); /* if part > 1, append .# to the filename (where # is the part number) */ if (dev->part > 1) { pm_strcat(archive_name, "."); bsnprintf(partnumber, sizeof(partnumber), "%d", dev->part); pm_strcat(archive_name, partnumber); } Dmsg2(400, "Exit add_file_part_name: arch=%s, part=%d\n", archive_name.c_str(), dev->part); }
static void configure_lex_error_handler(const char *file, int line, LEX *lc, POOL_MEM &msg) { UAContext *ua; lc->error_counter++; if (lc->caller_ctx) { ua = (UAContext *)(lc->caller_ctx); ua->error_msg("configure error: %s\n", msg.c_str()); }; }
/* Convert spaces to non-space character. * This makes scanf of fields containing spaces easier. */ void bash_spaces(POOL_MEM &pm) { char *str = pm.c_str(); while (*str) { if (*str == ' ') *str = 0x1; str++; } }
/* Convert non-space characters (0x1) back into spaces */ void unbash_spaces(POOL_MEM &pm) { char *str = pm.c_str(); while (*str) { if (*str == 0x1) *str = ' '; str++; } }
int pm_strcpy(POOL_MEM &pm, const char *str) { int len; if (!str) str = ""; len = strlen(str) + 1; pm.check_size(len); memcpy(pm.c_str(), str, len); return len - 1; }
/* * Edit codes into (Un)MountCommand * %% = % * %a = archive device name * %m = mount point * * omsg = edited output message * imsg = input string containing edit codes (%x) * */ void DEVICE::edit_mount_codes(POOL_MEM &omsg, const char *imsg) { const char *p; const char *str; char add[20]; POOL_MEM archive_name(PM_FNAME); omsg.c_str()[0] = 0; Dmsg1(800, "edit_mount_codes: %s\n", imsg); for (p=imsg; *p; p++) { if (*p == '%') { switch (*++p) { case '%': str = "%"; break; case 'a': str = dev_name; break; case 'm': str = device->mount_point; break; default: add[0] = '%'; add[1] = *p; add[2] = 0; str = add; break; } } else { add[0] = *p; add[1] = 0; str = add; } Dmsg1(1900, "add_str %s\n", str); pm_strcat(omsg, (char *)str); Dmsg1(1800, "omsg=%s\n", omsg.c_str()); } }
static inline bool configure_create_resource_string(UAContext *ua, int first_parameter, RES_TABLE *res_table, POOL_MEM &resourcename, POOL_MEM &resource) { resource.strcat(res_table->name); resource.strcat(" {\n"); /* * Is the name of the resource already given as value of the resource type? * E.g. configure add client=newclient address=127.0.0.1 ... * instead of configure add client name=newclient address=127.0.0.1 ... */ if (ua->argv[first_parameter - 1]) { resourcename.strcat(ua->argv[first_parameter - 1]); if (!config_add_directive(ua, res_table, "name", resourcename.c_str(), resource)) { return false; } } for (int i = first_parameter; i < ua->argc; i++) { if (!ua->argv[i]) { ua->error_msg("Missing value for directive \"%s\"\n", ua->argk[i]); return false; } if (bstrcasecmp(ua->argk[i], "name")) { resourcename.strcat(ua->argv[i]); } if (!config_add_directive(ua, res_table, ua->argk[i], ua->argv[i], resource)) { return false; } } resource.strcat("}\n"); if (strlen(resourcename.c_str()) <= 0) { ua->error_msg("Resource \"%s\": missing name parameter.\n", res_table->name); return false; } return true; }
/* * Fill the rx->BaseJobIds and display the list */ static void get_and_display_basejobs(UAContext *ua, RESTORE_CTX *rx) { db_list_ctx jobids; if (!db_get_used_base_jobids(ua->jcr, ua->db, rx->JobIds, &jobids)) { ua->warning_msg("%s", db_strerror(ua->db)); } if (jobids.count) { POOL_MEM q; Mmsg(q, uar_print_jobs, jobids.list); ua->send_msg(_("The restore will use the following job(s) as Base\n")); db_list_sql_query(ua->jcr, ua->db, q.c_str(), prtit, ua, 1, HORZ_LIST); } pm_strcpy(rx->BaseJobIds, jobids.list); }
static void make_unique_restore_filename(UAContext *ua, POOL_MEM &fname) { JCR *jcr = ua->jcr; int i = find_arg_with_value(ua, "bootstrap"); if (i >= 0) { Mmsg(fname, "%s", ua->argv[i]); jcr->unlink_bsr = false; } else { P(mutex); uniq++; V(mutex); Mmsg(fname, "%s/%s.restore.%u.bsr", working_directory, my_name, uniq); jcr->unlink_bsr = true; } if (jcr->RestoreBootstrap) { free(jcr->RestoreBootstrap); } jcr->RestoreBootstrap = bstrdup(fname.c_str()); }
/* * Send current file list to FD * DIR -> FD : accurate files=xxxx * DIR -> FD : /path/to/file\0Lstat * DIR -> FD : /path/to/dir/\0Lstat * ... * DIR -> FD : EOD */ bool send_accurate_current_files(JCR *jcr) { POOL_MEM buf; if (!jcr->accurate || job_canceled(jcr) || jcr->get_JobLevel()==L_FULL) { return true; } POOLMEM *jobids = get_pool_memory(PM_FNAME); db_accurate_get_jobids(jcr, jcr->db, &jcr->jr, jobids); if (*jobids == 0) { free_pool_memory(jobids); Jmsg(jcr, M_FATAL, 0, _("Cannot find previous jobids.\n")); return false; } Jmsg(jcr, M_INFO, 0, _("Sending Accurate information.\n")); /* to be able to allocate the right size for htable */ POOLMEM *nb = get_pool_memory(PM_FNAME); *nb = 0; /* clear buffer */ Mmsg(buf, "SELECT sum(JobFiles) FROM Job WHERE JobId IN (%s)",jobids); db_sql_query(jcr->db, buf.c_str(), db_get_int_handler, nb); Dmsg2(200, "jobids=%s nb=%s\n", jobids, nb); jcr->file_bsock->fsend("accurate files=%s\n", nb); if (!db_open_batch_connexion(jcr, jcr->db)) { Jmsg0(jcr, M_FATAL, 0, "Can't get dedicate sql connexion"); return false; } db_get_file_list(jcr, jcr->db_batch, jobids, accurate_list_handler, (void *)jcr); /* TODO: close the batch connexion ? (can be used very soon) */ free_pool_memory(jobids); free_pool_memory(nb); jcr->file_bsock->signal(BNET_EOD); return true; }
/* * If full_list is set, we list vertically, otherwise, we * list on one line horizontally. * Return number of rows */ int list_result(JCR *jcr, B_DB *mdb, OUTPUT_FORMATTER *send, e_list_type type) { SQL_FIELD *field; SQL_ROW row; int i, col_len, max_len = 0; int num_fields; char ewc[30]; POOL_MEM key; POOL_MEM value; Dmsg0(800, "list_result starts\n"); if (sql_num_rows(mdb) == 0) { send->decoration(_("No results to list.\n")); send->object_end("table"); return sql_num_rows(mdb); } num_fields = sql_num_fields(mdb); switch (type) { case NF_LIST: case RAW_LIST: /* * No need to calculate things like column widths for * unformated or raw output. */ break; case HORZ_LIST: case VERT_LIST: Dmsg1(800, "list_result starts looking at %d fields\n", num_fields); /* * Determine column display widths */ sql_field_seek(mdb, 0); for (i = 0; i < num_fields; i++) { Dmsg1(800, "list_result processing field %d\n", i); field = sql_fetch_field(mdb); if (!field) { break; } col_len = cstrlen(field->name); if (type == VERT_LIST) { if (col_len > max_len) { max_len = col_len; } } else { if (sql_field_is_numeric(mdb, field->type) && (int)field->max_length > 0) { /* fixup for commas */ field->max_length += (field->max_length - 1) / 3; } if (col_len < (int)field->max_length) { col_len = field->max_length; } if (col_len < 4 && !sql_field_is_not_null(mdb, field->flags)) { col_len = 4; /* 4 = length of the word "NULL" */ } field->max_length = col_len; /* reset column info */ } } break; } Dmsg0(800, "list_result finished first loop\n"); switch (type) { case NF_LIST: case RAW_LIST: Dmsg1(800, "list_result starts second loop looking at %d fields\n", num_fields); while ((row = sql_fetch_row(mdb)) != NULL) { send->object_start(row[0]); sql_field_seek(mdb, 0); for (i = 0; i < num_fields; i++) { field = sql_fetch_field(mdb); if (!field) { break; } if (row[i] == NULL) { value.bsprintf(" %s", "NULL"); } else { value.bsprintf(" %s", row[i]); } send->object_key_value(field->name, value.c_str(), "%s"); } if (type != RAW_LIST) { send->decoration("\n"); } send->object_end(row[0]); } break; case HORZ_LIST: Dmsg1(800, "list_result starts second loop looking at %d fields\n", num_fields); list_dashes(mdb, send); send->decoration("|"); sql_field_seek(mdb, 0); for (i = 0; i < num_fields; i++) { Dmsg1(800, "list_result looking at field %d\n", i); field = sql_fetch_field(mdb); if (!field) { break; } max_len = max_length(field->max_length); send->decoration(" %-*s |", max_len, field->name); } send->decoration("\n"); list_dashes(mdb, send); Dmsg1(800, "list_result starts third loop looking at %d fields\n", num_fields); while ((row = sql_fetch_row(mdb)) != NULL) { send->object_start(row[0]); sql_field_seek(mdb, 0); send->decoration("|"); for (i = 0; i < num_fields; i++) { field = sql_fetch_field(mdb); if (!field) { break; } max_len = max_length(field->max_length); if (row[i] == NULL) { value.bsprintf(" %-*s |", max_len, "NULL"); } else if (sql_field_is_numeric(mdb, field->type) && !jcr->gui && is_an_integer(row[i])) { value.bsprintf(" %*s |", max_len, add_commas(row[i], ewc)); } else { value.bsprintf(" %-*s |", max_len, row[i]); } if (i == num_fields-1) { value.strcat("\n"); } /* use value format string to send preformated value */ send->object_key_value(field->name, row[i], value.c_str()); } send->object_end(row[0]); } list_dashes(mdb, send); break; case VERT_LIST: Dmsg1(800, "list_result starts vertical list at %d fields\n", num_fields); while ((row = sql_fetch_row(mdb)) != NULL) { send->object_start(row[0]); sql_field_seek(mdb, 0); for (i = 0; i < num_fields; i++) { field = sql_fetch_field(mdb); if (!field) { break; } if (row[i] == NULL) { key.bsprintf(" %*s: ", max_len, field->name); value.bsprintf("%s\n", "NULL"); } else if (sql_field_is_numeric(mdb, field->type) && !jcr->gui && is_an_integer(row[i])) { key.bsprintf(" %*s: ", max_len, field->name); value.bsprintf("%s\n", add_commas(row[i], ewc)); } else { key.bsprintf(" %*s: ", max_len, field->name); value.bsprintf("%s\n", row[i]); } /* use value format string to send preformated value */ send->object_key_value(field->name, key.c_str(), row[i], value.c_str()); } send->decoration("\n"); send->object_end(row[0]); } break; } return sql_num_rows(mdb); }
int list_result(void *vctx, int nb_col, char **row) { SQL_FIELD *field; int i, col_len, max_len = 0; int num_fields; char ewc[30]; POOL_MEM key; POOL_MEM value; LIST_CTX *pctx = (LIST_CTX *)vctx; OUTPUT_FORMATTER *send = pctx->send; e_list_type type = pctx->type; B_DB *mdb = pctx->mdb; JCR *jcr = pctx->jcr; send->object_start("row"); num_fields = sql_num_fields(mdb); switch (type) { case NF_LIST: case RAW_LIST: /* * No need to calculate things like maximum field lenght for * unformated or raw output. */ break; case HORZ_LIST: case VERT_LIST: if (!pctx->once) { pctx->once = true; Dmsg1(800, "list_result starts looking at %d fields\n", num_fields); /* * Determine column display widths */ sql_field_seek(mdb, 0); for (i = 0; i < num_fields; i++) { Dmsg1(800, "list_result processing field %d\n", i); field = sql_fetch_field(mdb); if (!field) { break; } col_len = cstrlen(field->name); if (type == VERT_LIST) { if (col_len > max_len) { max_len = col_len; } } else { if (sql_field_is_numeric(mdb, field->type) && (int)field->max_length > 0) { /* fixup for commas */ field->max_length += (field->max_length - 1) / 3; } if (col_len < (int)field->max_length) { col_len = field->max_length; } if (col_len < 4 && !sql_field_is_not_null(mdb, field->flags)) { col_len = 4; /* 4 = length of the word "NULL" */ } field->max_length = col_len; /* reset column info */ } } pctx->num_rows++; Dmsg0(800, "list_result finished first loop\n"); if (type == VERT_LIST) { break; } Dmsg1(800, "list_result starts second loop looking at %d fields\n", num_fields); /* * Keep the result to display the same line at the end of the table */ list_dashes(mdb, send); send->decoration("|"); sql_field_seek(mdb, 0); for (i = 0; i < num_fields; i++) { Dmsg1(800, "list_result looking at field %d\n", i); field = sql_fetch_field(mdb); if (!field) { break; } max_len = max_length(field->max_length); send->decoration(" %-*s |", max_len, field->name); } send->decoration("\n"); list_dashes(mdb, send); } break; default: break; } switch (type) { case NF_LIST: case RAW_LIST: Dmsg1(800, "list_result starts third loop looking at %d fields\n", num_fields); sql_field_seek(mdb, 0); for (i = 0; i < num_fields; i++) { field = sql_fetch_field(mdb); if (!field) { break; } if (row[i] == NULL) { value.bsprintf(" %s", "NULL"); } else { value.bsprintf(" %s", row[i]); } send->object_key_value(field->name, value.c_str(), "%s"); } if (type != RAW_LIST) { send->decoration("\n"); } break; case HORZ_LIST: Dmsg1(800, "list_result starts third loop looking at %d fields\n", num_fields); sql_field_seek(mdb, 0); send->decoration("|"); for (i = 0; i < num_fields; i++) { field = sql_fetch_field(mdb); if (!field) { break; } max_len = max_length(field->max_length); if (row[i] == NULL) { value.bsprintf(" %-*s |", max_len, "NULL"); } else if (sql_field_is_numeric(mdb, field->type) && !jcr->gui && is_an_integer(row[i])) { value.bsprintf(" %*s |", max_len, add_commas(row[i], ewc)); } else { value.bsprintf(" %-*s |", max_len, row[i]); } /* * Use value format string to send preformated value. */ send->object_key_value(field->name, row[i], value.c_str()); } send->decoration("\n"); break; case VERT_LIST: Dmsg1(800, "list_result starts vertical list at %d fields\n", num_fields); sql_field_seek(mdb, 0); for (i = 0; i < num_fields; i++) { field = sql_fetch_field(mdb); if (!field) { break; } if (row[i] == NULL) { key.bsprintf(" %*s: ", max_len, field->name); value.bsprintf("%s\n", "NULL"); } else if (sql_field_is_numeric(mdb, field->type) && !jcr->gui && is_an_integer(row[i])) { key.bsprintf(" %*s: ", max_len, field->name); value.bsprintf("%s\n", add_commas(row[i], ewc)); } else { key.bsprintf(" %*s: ", max_len, field->name); value.bsprintf("%s\n", row[i]); } /* * Use value format string to send preformated value. */ send->object_key_value(field->name, key.c_str(), row[i], value.c_str()); } send->decoration("\n"); break; default: break; } send->object_end("row"); return 0; }
/** * After writing a Volume, send the updated statistics * back to the director. The information comes from the * dev record. */ bool dir_update_volume_info(DCR *dcr, bool label, bool update_LastWritten) { JCR *jcr = dcr->jcr; BSOCK *dir = jcr->dir_bsock; DEVICE *dev = dcr->dev; VOLUME_CAT_INFO *vol = &dev->VolCatInfo; char ed1[50], ed2[50], ed3[50], ed4[50], ed5[50], ed6[50]; int InChanger; bool ok = false; POOL_MEM VolumeName; /* If system job, do not update catalog */ if (jcr->is_JobType(JT_SYSTEM)) { return true; } if (vol->VolCatName[0] == 0) { Jmsg0(jcr, M_FATAL, 0, _("NULL Volume name. This shouldn't happen!!!\n")); Pmsg0(000, _("NULL Volume name. This shouldn't happen!!!\n")); return false; } /* Lock during Volume update */ P(vol_info_mutex); Dmsg1(dbglvl, "Update cat VolBytes=%lld\n", vol->VolCatBytes); /* Just labeled or relabeled the tape */ if (label) { bstrncpy(vol->VolCatStatus, "Append", sizeof(vol->VolCatStatus)); } // if (update_LastWritten) { vol->VolLastWritten = time(NULL); // } pm_strcpy(VolumeName, vol->VolCatName); bash_spaces(VolumeName); InChanger = vol->InChanger; dir->fsend(Update_media, jcr->Job, VolumeName.c_str(), vol->VolCatJobs, vol->VolCatFiles, vol->VolCatBlocks, edit_uint64(vol->VolCatBytes, ed1), vol->VolCatMounts, vol->VolCatErrors, vol->VolCatWrites, edit_uint64(vol->VolCatMaxBytes, ed2), edit_uint64(vol->VolLastWritten, ed6), vol->VolCatStatus, vol->Slot, label, InChanger, /* bool in structure */ edit_int64(vol->VolReadTime, ed3), edit_int64(vol->VolWriteTime, ed4), edit_uint64(vol->VolFirstWritten, ed5)); Dmsg1(dbglvl, ">dird %s", dir->msg); /* Do not lock device here because it may be locked from label */ if (!jcr->is_canceled()) { if (!do_get_volume_info(dcr)) { Jmsg(jcr, M_FATAL, 0, "%s", jcr->errmsg); Dmsg2(dbglvl, _("Didn't get vol info vol=%s: ERR=%s"), vol->VolCatName, jcr->errmsg); goto bail_out; } Dmsg1(420, "get_volume_info() %s", dir->msg); /* Update dev Volume info in case something changed (e.g. expired) */ dev->VolCatInfo = dcr->VolCatInfo; ok = true; } bail_out: V(vol_info_mutex); return ok; }
int pm_memcpy(POOL_MEM &pm, const char *data, int32_t n) { pm.check_size(n); memcpy(pm.c_str(), data, n); return n; }
int pm_memcpy(POOLMEM *&pm, POOL_MEM &data, int32_t n) { pm = check_pool_memory_size(pm, n); memcpy(pm, data.c_str(), n); return n; }
int main (int argc, char *argv[]) { int ch; bool no_signals = false; bool test_config = false; bool export_config = false; bool export_config_schema = 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:vx:?")) != -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 'x': /* export configuration/schema and exit */ if (*optarg == 's') { export_config_schema = true; } else if (*optarg == 'c') { export_config = true; } else { usage(); } 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 (export_config_schema) { POOL_MEM buffer; my_config = new_config_parser(); init_sd_config(my_config, configfile, M_ERROR_TERM); print_config_schema_json(buffer); printf("%s\n", buffer.c_str()); goto bail_out; } my_config = new_config_parser(); parse_sd_config(my_config, configfile, M_ERROR_TERM); if (export_config) { my_config->dump_resources(prtmsg, NULL); goto bail_out; } if (!foreground && !test_config) { daemon_start(); /* become daemon */ init_stack_dump(); /* pick up new pid */ } 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"), my_config->get_base_config_path()); } init_reservations_lock(); if (test_config) { terminate_stored(0); } my_name_is(0, (char **)NULL, me->name()); /* Set our real name */ 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->MaxConcurrentJobs * 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. */ } start_statistics_thread(); #if HAVE_NDMP /* * Seperate thread that handles NDMP connections */ if (me->ndmp_enable) { start_ndmp_thread_server(me->NDMPaddrs, me->MaxConnections); } #endif /* * Single server used for Director/Storage and File daemon */ start_socket_server(me->SDaddrs); /* to keep compiler quiet */ terminate_stored(0); bail_out: return 0; }
/* * Returns false on error * true on OK, with full_path set to where config file should be */ bool CONFIG::find_config_path(POOL_MEM &full_path) { bool found = false; POOL_MEM config_dir; POOL_MEM config_path_file; if (!m_cf) { /* * No path is given, so use the defaults. */ found = get_config_file(full_path, get_default_configdir(), m_config_default_filename); if (!found) { config_path_file.strcpy(full_path); found = get_config_include_path(full_path, get_default_configdir()); } if (!found) { Jmsg2(NULL, M_ERROR, 0, _("Failed to read config file at the default locations " "\"%s\" (config file path) and \"%s\" (config include directory).\n"), config_path_file.c_str(), full_path.c_str()); } } else if (path_exists(m_cf)) { /* * Path is given and exists. */ if (path_is_directory(m_cf)) { found = get_config_file(full_path, m_cf, m_config_default_filename); if (!found) { config_path_file.strcpy(full_path); found = get_config_include_path(full_path, m_cf); } if (!found) { Jmsg3(NULL, M_ERROR, 0, _("Failed to find configuration files under directory \"%s\". " "Did look for \"%s\" (config file path) and \"%s\" (config include directory).\n"), m_cf, config_path_file.c_str(), full_path.c_str()); } } else { full_path.strcpy(m_cf); path_get_directory(config_dir, full_path); m_config_dir = bstrdup(config_dir.c_str()); found = true; } } else if (!m_config_default_filename) { /* * Compatibility with older versions. * If m_config_default_filename is not set, * m_cf may contain what is expected in m_config_default_filename. */ found = get_config_file(full_path, get_default_configdir(), m_cf); if (!found) { Jmsg2(NULL, M_ERROR, 0, _("Failed to find configuration files at \"%s\" and \"%s\".\n"), m_cf, full_path.c_str()); } } else { Jmsg1(NULL, M_ERROR, 0, _("Failed to read config file \"%s\"\n"), m_cf); } if (found) { set_env("BAREOS_CFGDIR", m_config_dir); } return found; }
void OUTPUT_FORMATTER::rewrap(POOL_MEM &string, int wrap) { char *p, *q; int open = 0; int charsinline = 0; POOL_MEM rewrap_string(PM_MESSAGE); /* * wrap < 0: no modification * wrap = 0: single line * wrap > 0: wrap line after x characters (if api==0) */ if (wrap < 0) { return; } /* * Allocate a wrap buffer that is big enough to hold the original * string + WRAP_EXTRA_BYTES. This means we can accommodate enough * line breaks and spaces to wrap the original string. */ rewrap_string.check_size(string.max_size() + WRAP_EXTRA_BYTES); /* * Walk the input buffer and copy the data to the wrap buffer * inserting line breaks as needed. */ q = rewrap_string.c_str(); p = string.c_str(); while (*p) { charsinline++; switch (*p) { case ' ': if (api == 0 && wrap > 0 && charsinline >= wrap && open <= 0 && *(p + 1) != '|') { *q++ = '\n'; *q++ = '\t'; charsinline = 0; } else { if (charsinline > 1) { *q++ = ' '; } } break; case '|': *q++ = '|'; if (api == 0 && wrap > 0 && open <= 0) { *q++ = '\n'; *q++ = '\t'; charsinline = 0; } break; case '[': case '<': open++; *q++ = *p; break; case ']': case '>': open--; *q++ = *p; break; case '\n': case '\t': if (charsinline > 1) { if (*(p + 1) != '\n' && *(p + 1) != '\t' && *(p + 1) != ' ') { *q++ = ' '; } } break; default: *q++ = *p; break; } p++; } *q = '\0'; string.strcpy(rewrap_string); }