void PgReader::initialize() { // First thing we do, is set up a connection if (!m_session) m_session = pg_connect(m_connection); }
/* * Function: PG_SETTING * * Provides access to run-time parameters of the server such as those returned * by `SHOW` commands. * * Parameter [0-4]: <host,port,db,user,passwd> * * Parameter [setting]: run-time configuration parameter name * * Returns: determined by parameter vartype */ int PG_SETTING(AGENT_REQUEST *request, AGENT_RESULT *result) { int ret = SYSINFO_RET_FAIL; // Request result code const char *__function_name = "PG_SETTING"; // Function name for log file PGconn *conn = NULL; PGresult *res = NULL; char *setting = NULL; char *value = NULL; char *type = NULL; char query[MAX_STRING_LEN]; zabbix_log(LOG_LEVEL_DEBUG, "In %s()", __function_name); // Build the query setting = get_rparam(request, PARAM_FIRST); if(NULL == setting || '\0' == *setting) { zabbix_log(LOG_LEVEL_ERR, "No setting name specified in %s()", __function_name); goto out; } zbx_snprintf(query, sizeof(query), PGSQL_GET_SETTING, setting); // Connect to PostreSQL if(NULL == (conn = pg_connect(request))) goto out; // Execute the query res = PQexec(conn, query); if(PQresultStatus(res) != PGRES_TUPLES_OK) { zabbix_log(LOG_LEVEL_ERR, "Failed to execute PostgreSQL query in %s() with: %s", __function_name, PQresultErrorMessage(res)); goto out; } if(0 == PQntuples(res)) { zabbix_log(LOG_LEVEL_DEBUG, "No results returned for query \"%s\" in %s()", query, __function_name); goto out; } // Set result value = strdup(PQgetvalue(res, 0, 0)); type = strdup(PQgetvalue(res, 0, 1)); if(0 == strncmp("integer", type, 7)) SET_UI64_RESULT(result, strtoull(value, NULL, 10)); else if(0 == strncmp("real", type, 4)) SET_DBL_RESULT(result, strtold(value, NULL)); else SET_STR_RESULT(result, value); ret = SYSINFO_RET_OK; out: PQclear(res); PQfinish(conn); zabbix_log(LOG_LEVEL_DEBUG, "End of %s(%s)", __function_name, request->key); return ret; }
/* * Custom key pg.table.discovery * * Returns all known Tables in a PostgreSQL database * * Parameter [0-4]: <host,port,db,user,passwd> * * * Returns: * { * "data":[ * { * "{#DATABASE}":"MyDatabase", * "{#SCHEMA}":"public", * "{#TABLESPACE}":"pg_default", * "{#TABLE}":"MyTable", * "{#TYPE}":"MyTable", * "{#OWNER}":"postgres", * "{#PERSISTENCE":"permenant|temporary", * "{#ISSUBCLASS}":"0"}]} */ int PG_TABLE_DISCOVERY(AGENT_REQUEST *request, AGENT_RESULT *result) { int ret = SYSINFO_RET_FAIL; // Request result code const char *__function_name = "PG_TABLE_DISCOVERY"; // Function name for log file struct zbx_json j; // JSON response for discovery rule PGconn *conn = NULL; PGresult *res = NULL; char query[MAX_STRING_LEN] = PGSQL_DISCOVER_TABLES; int i = 0, count = 0; zabbix_log(LOG_LEVEL_DEBUG, "In %s()", __function_name); // Connect to PostreSQL if(NULL == (conn = pg_connect(request))) goto out; // Execute a query res = PQexec(conn, query); if(PQresultStatus(res) != PGRES_TUPLES_OK) { zabbix_log(LOG_LEVEL_ERR, "Failed to execute PostgreSQL query in %s() with: %s", __function_name, PQresultErrorMessage(res)); goto out; } if(0 == (count = PQntuples(res))) { zabbix_log(LOG_LEVEL_DEBUG, "No results returned for query \"%s\" in %s()", query, __function_name); } // Create JSON array of discovered objects zbx_json_init(&j, ZBX_JSON_STAT_BUF_LEN); zbx_json_addarray(&j, ZBX_PROTO_TAG_DATA); for(i = 0; i < count; i++) { zbx_json_addobject(&j, NULL); zbx_json_addstring(&j, "{#OID}", PQgetvalue(res, i, 0), ZBX_JSON_TYPE_STRING); zbx_json_addstring(&j, "{#DATABASE}", PQgetvalue(res, i, 1), ZBX_JSON_TYPE_STRING); zbx_json_addstring(&j, "{#SCHEMA}", PQgetvalue(res, i, 2), ZBX_JSON_TYPE_STRING); zbx_json_addstring(&j, "{#TABLESPACE}", PQgetvalue(res, i, 3), ZBX_JSON_TYPE_STRING); zbx_json_addstring(&j, "{#TABLE}", PQgetvalue(res, i, 4), ZBX_JSON_TYPE_STRING); zbx_json_addstring(&j, "{#TYPE}", PQgetvalue(res, i, 5), ZBX_JSON_TYPE_STRING); zbx_json_addstring(&j, "{#OWNER}", PQgetvalue(res, i, 6), ZBX_JSON_TYPE_STRING); zbx_json_addstring(&j, "{#PERSISTENCE}", PQgetvalue(res, i, 7), ZBX_JSON_TYPE_STRING); zbx_json_addstring(&j, "{#ISSUBCLASS}", PQgetvalue(res, i, 8), ZBX_JSON_TYPE_STRING); zbx_json_close(&j); } // Finalize JSON response zbx_json_close(&j); SET_STR_RESULT(result, strdup(j.buffer)); zbx_json_free(&j); ret = SYSINFO_RET_OK; out: PQclear(res); PQfinish(conn); zabbix_log(LOG_LEVEL_DEBUG, "End of %s()", __function_name); return ret; }
/* * Custom keys pg.index.* (for each field in pg_stat_all_indexes) * * Returns the requested statistic for the specified index * * Parameters: * 0: connection string * 1: connection database * 2: filter by index name (default: sum of all indexes) * * Returns: u */ int PG_STAT_ALL_INDEXES(AGENT_REQUEST *request, AGENT_RESULT *result) { int ret = SYSINFO_RET_FAIL; // Request result code const char *__function_name = "PG_STAT_ALL_INDEXES"; // Function name for log file char *index = NULL; PGconn *conn = NULL; PGresult *res = NULL; char *field; char query[MAX_STRING_LEN]; char *buffer = NULL; zabbix_log(LOG_LEVEL_DEBUG, "In %s()", __function_name); // Get stat field from requested key name "pb.table.<field>" field = &request->key[9]; // Build query index = get_rparam(request, PARAM_FIRST); if(NULL == index || '\0' == *index) zbx_snprintf(query, sizeof(query), "SELECT SUM(%s) FROM pg_stat_all_indexes", field); else zbx_snprintf(query, sizeof(query), "SELECT %s FROM pg_stat_all_indexes WHERE indexrelname = '%s'", field, index); // Connect to PostreSQL if(NULL == (conn = pg_connect(request))) goto out; // Execute a query res = pg_exec(conn, query); if(PQresultStatus(res) != PGRES_TUPLES_OK) { zabbix_log(LOG_LEVEL_ERR, "Failed to execute PostgreSQL query in %s() with: %s", __function_name, PQresultErrorMessage(res)); goto out; } if(0 == PQntuples(res)) { zabbix_log(LOG_LEVEL_ERR, "No results returned for query \"%s\" in %s()", query, __function_name); goto out; } // Set result buffer = strdup(PQgetvalue(res, 0, 0)); SET_UI64_RESULT(result, atoi(buffer)); ret = SYSINFO_RET_OK; out: PQclear(res); PQfinish(conn); zabbix_log(LOG_LEVEL_DEBUG, "End of %s()", __function_name); return ret; }
/* * Function: pg_get_int * * Executes a PostgreSQL Query using connection details from a Zabbix agent * request structure and updates the agent result structure with the integer * value of the first column of the first row returned. * * Parameter [request]: Zabbix agent request structure. * Passed to pg_connect to fetch as valid PostgreSQL * server connection * * Parameter [result]: Zabbix agent result structure * * Paramater [query]: PostgreSQL query to execute. Query should return a * single scalar integer value * * Returns: SYSINFO_RET_OK or SYSINFO_RET_FAIL on error */ int pg_get_int(AGENT_REQUEST *request, AGENT_RESULT *result, const char *query) { int ret = SYSINFO_RET_FAIL; // Request result code const char *__function_name = "pg_get_int"; // Function name for log file PGconn *conn = NULL; PGresult *res = NULL; char *buffer = NULL; zabbix_log(LOG_LEVEL_DEBUG, "In %s(%s)", __function_name, request->key); // Connect to PostreSQL if(NULL == (conn = pg_connect(request))) goto out; // Execute a query res = pg_exec(conn, query); if(PQresultStatus(res) != PGRES_TUPLES_OK) { zabbix_log(LOG_LEVEL_ERR, "Failed to execute PostgreSQL query in %s(%s) with: %s", __function_name, request->key, PQresultErrorMessage(res)); goto out; } if(0 == PQntuples(res)) { zabbix_log(LOG_LEVEL_DEBUG, "No results returned for query \"%s\" in %s(%s)", query, __function_name, request->key); goto out; } // Set result buffer = strdup(PQgetvalue(res, 0, 0)); // Convert E Notation if(1 < strlen(buffer) && '.' == buffer[1]) { double dbl = strtod(buffer, NULL); SET_UI64_RESULT(result, (unsigned long long) dbl); } else { SET_UI64_RESULT(result, strtoull(buffer, NULL, 10)); } ret = SYSINFO_RET_OK; out: PQclear(res); PQfinish(conn); zabbix_log(LOG_LEVEL_DEBUG, "End of %s(%s)", __function_name, request->key); return ret; }
/* Ein Datum in die Datenbank schreiben */ static void pg_insert(char *query){ PGresult *res; if(pg_connect()){ res = PQexec(connection, query); if(!res || PQresultStatus(res) != PGRES_COMMAND_OK){ DEBUGOUT2("Fehler beim INSERT: %s\n", query); #ifndef NO_LOGING snprintf(get_error_buffer(), ERR_BUFFERSIZE, "Fehler beim INSERT: %s", query); log_error(get_error_buffer()); #endif } else { DEBUGOUT2("Query: '%s' ausgefuehrt\n", query); } PQclear(res); } }
/* * Function: pg_get_string * * Executes a PostgreSQL Query using connection details from a Zabbix agent * request structure and updates the agent result structure with the string * value of the first column of the first row returned. * * Parameter [request]: Zabbix agent request structure. * Passed to pg_connect to fetch as valid PostgreSQL * server connection * * Parameter [result]: Zabbix agent result structure * * Paramater [query]: PostgreSQL query to execute. Query should return a * single scalar string value * * Returns: SYSINFO_RET_OK or SYSINFO_RET_FAIL on error */ int pg_get_string(AGENT_REQUEST *request, AGENT_RESULT *result, const char *query) { int ret = SYSINFO_RET_FAIL; // Request result code const char *__function_name = "pg_get_string"; // Function name for log file PGconn *conn = NULL; PGresult *res = NULL; char *buffer = NULL; zabbix_log(LOG_LEVEL_DEBUG, "In %s(%s)", __function_name, request->key); // Connect to PostreSQL if(NULL == (conn = pg_connect(request))) goto out; // Execute a query res = pg_exec(conn, query); if(PQresultStatus(res) != PGRES_TUPLES_OK) { zabbix_log(LOG_LEVEL_ERR, "Failed to execute PostgreSQL query in %s(%s) with: %s", __function_name, request->key, PQresultErrorMessage(res)); goto out; } if(0 == PQntuples(res)) { zabbix_log(LOG_LEVEL_DEBUG, "No results returned for query \"%s\" in %s(%s)", query, __function_name, request->key); goto out; } // Set result buffer = strdup(PQgetvalue(res, 0, 0)); SET_STR_RESULT(result, buffer); ret = SYSINFO_RET_OK; out: PQclear(res); PQfinish(conn); zabbix_log(LOG_LEVEL_DEBUG, "End of %s(%s)", __function_name, request->key); return ret; }
long int pg_version(AGENT_REQUEST *request) { PGconn *conn = NULL; PGresult *res = NULL; long int version = 0; // connect to PostgreSQL conn = pg_connect(request); if (NULL == conn) return 0; // get server version res = pg_exec(conn, "SELECT setting FROM pg_settings WHERE name='server_version_num'", NULL); if(0 == PQntuples(res)) { zabbix_log(LOG_LEVEL_ERR, "Failed to get PostgreSQL server version"); return 0; } // convert to integer version = atol(PQgetvalue(res, 0, 0)); zabbix_log(LOG_LEVEL_DEBUG, "PostgreSQL server version: %lu", version); return version; }
/* * Function: pg_get_discovery * * Executes a PostgreSQL Query using connection details from a Zabbix agent * request structure and updates the agent result structure with the JSON * discovery data for each returned row. * * Parameter [request]: Zabbix agent request structure. * Passed to pg_connect to fetch as valid PostgreSQL * server connection * * Parameter [result]: Zabbix agent result structure * * Paramater [query]: PostgreSQL query to execute. Query should column names that match the desired discovery fields. * * Returns: SYSINFO_RET_OK or SYSINFO_RET_FAIL on error */ int pg_get_discovery(AGENT_REQUEST *request, AGENT_RESULT *result, const char *query) { int ret = SYSINFO_RET_FAIL; // Request result code const char *__function_name = "pg_get_discovery"; // Function name for log file PGconn *conn = NULL; PGresult *res = NULL; struct zbx_json j; // JSON response for discovery rule int i = 0, x = 0, columns = 0, rows = 0; char *colname = NULL, *c = NULL; char buffer[MAX_STRING_LEN]; zabbix_log(LOG_LEVEL_DEBUG, "In %s(%s)", __function_name, request->key); // Connect to PostreSQL if(NULL == (conn = pg_connect(request))) goto out; // Execute a query res = pg_exec(conn, query); if(PQresultStatus(res) != PGRES_TUPLES_OK) { zabbix_log(LOG_LEVEL_ERR, "Failed to execute PostgreSQL query in %s(%s) with: %s", __function_name, request->key, PQresultErrorMessage(res)); goto out; } rows = PQntuples(res); columns = PQnfields(res); // Create JSON array of discovered objects zbx_json_init(&j, ZBX_JSON_STAT_BUF_LEN); zbx_json_addarray(&j, ZBX_PROTO_TAG_DATA); // create discovery instance for each row for(i = 0; i < rows; i++) { zbx_json_addobject(&j, NULL); // add each fields as a discovery field for(x = 0; x < columns; x++) { // set discovery key name to uppercase column name zbx_snprintf(buffer, sizeof(buffer), "{#%s}", PQfname(res, x)); for(c = &buffer[0]; *c; c++) *c = toupper(*c); zbx_json_addstring(&j, buffer, PQgetvalue(res, i, x), ZBX_JSON_TYPE_STRING); } zbx_json_close(&j); } // Finalize JSON response zbx_json_close(&j); SET_STR_RESULT(result, strdup(j.buffer)); zbx_json_free(&j); ret = SYSINFO_RET_OK; out: PQclear(res); PQfinish(conn); zabbix_log(LOG_LEVEL_DEBUG, "End of %s(%s)", __function_name, request->key); return ret; }
/* * Function: pg_get_result * * Executes a PostgreSQL Query using connection details from a Zabbix agent * request structure and updates the agent result structure with the value of * the first column of the first row returned. * * type may be * * Query parameters may be provided as a NULL terminated sequence of *char * values in the ... parameter. * * Parameter [request]: Zabbix agent request structure. * Passed to pg_connect to fetch as valid PostgreSQL * server connection * * Parameter [result]: Zabbix agent result structure * * Parameter [type]: Result type to set. May be one of AR_STRING, AR_UINT64 * or AR_DOUBLE. * * Paramater [query]: PostgreSQL query to execute. Query should return a * single scalar string value. Parameters defined using PostgreSQL's * '$n' notation will be replaced with the corresponding variadic * argument provided in ... * * Returns: SYSINFO_RET_OK or SYSINFO_RET_FAIL on error */ int pg_get_result(AGENT_REQUEST *request, AGENT_RESULT *result, int type, const char *query, PGparams params) { int ret = SYSINFO_RET_FAIL; // Request result code const char *__function_name = "pg_get_result"; // Function name for log file PGconn *conn = NULL; PGresult *res = NULL; char *value = NULL; zabbix_log(LOG_LEVEL_DEBUG, "In %s(%s)", __function_name, request->key); // Connect to PostreSQL if(NULL == (conn = pg_connect(request))) goto out; // Execute a query res = pg_exec(conn, query, params); if(PQresultStatus(res) != PGRES_TUPLES_OK) { zabbix_log(LOG_LEVEL_ERR, "Failed to execute PostgreSQL query in %s(%s) with: %s", __function_name, request->key, PQresultErrorMessage(res)); goto out; } if(0 == PQntuples(res)) { zabbix_log(LOG_LEVEL_DEBUG, "No results returned for query \"%s\" in %s(%s)", query, __function_name, request->key); goto out; } // get scalar value (freed later by PQclear) value = PQgetvalue(res, 0, 0); // Set result switch(type) { case AR_STRING: // string result (zabbix will clean the strdup'd buffer) SET_STR_RESULT(result, strdup(value)); break; case AR_UINT64: // integer result // Convert E Notation if(1 < strlen(value) && '.' == value[1]) { double dbl = strtod(value, NULL); SET_UI64_RESULT(result, (unsigned long long) dbl); } else { SET_UI64_RESULT(result, strtoull(value, NULL, 10)); } break; case AR_DOUBLE: // double result SET_DBL_RESULT(result, strtold(value, NULL)); break; default: // unknown result type zabbix_log(LOG_LEVEL_ERR, "Unsupported result type: 0x%0X in %s", type, __function_name); goto out; } ret = SYSINFO_RET_OK; out: PQclear(res); PQfinish(conn); zabbix_log(LOG_LEVEL_DEBUG, "End of %s(%s)", __function_name, request->key); return ret; }
int main(int argc, char **argv) { int lev = LOG_NOTICE; int opt, fg = 0, err = 0, nopass = 0, nport; char *cfgfile = NULL; char *logfile = NULL; const char *shuser = getenv("USER"); const char *dbdsn = NULL; char *dbuser = NULL; char *dbpasswd = NULL; char *port = NULL; char *prefix = NULL; char prompt[64]; char hostname[_POSIX_HOST_NAME_MAX]; char serveruri[_POSIX_HOST_NAME_MAX * 2]; wordexp_t expresult; config_t config; tf_node *orgroot = NULL; tf_node *infroot = NULL; tf_node *servinst = NULL; tf_host *host = NULL; tf_access_map *accmap = NULL; tf_property *instprop = NULL; tf_host **hostarr = NULL; tf_error dberr; int result = 0; hostname[0] = '\0'; while (err == 0 && (opt = getopt(argc, argv, "c:d:fh:l:p:P:t:u:w")) != -1) { switch (opt) { case 'c': cfgfile = strdup(optarg); break; case 'd': lev = atoi(optarg); break; case 'f': fg = 1; break; case 'h': strncpy(hostname, optarg, _POSIX_HOST_NAME_MAX); break; case 'l': logfile = strdup(optarg); break; case 'p': dbpasswd = strdup(optarg); break; case 'P': prefix = strdup(optarg); break; case 't': port = strdup(optarg); break; case 'u': dbuser = strdup(optarg); break; case 'w': nopass = 1; break; default: err = 1; } } argc -= optind; argv += optind; if (argc != 0 || err || !cfgfile) { printf("USAGE: tfadmin setup [options] -c <file>\n"); printf("\n"); printf("Common Options:\n"); printf(" -c <file> configuration file (required)\n"); printf(" -d <level> log level (default: 5)\n"); printf(" -f write log messages to standard out\n"); printf(" -l <file> log file (default: ~/tfadmin.log)\n"); printf("\n"); printf("Team Services Options:\n"); printf(" -h <host> hostname where HAProxy is installed (default: localhost)\n"); printf(" -t <port> TCP port HAProxy listens on (default: 8080)\n"); printf(" -P <prefix> URL prefix with leading forward slash (default: /tfs)\n"); printf("\n"); printf("Database Options:\n"); printf(" -u <username> database user to connect as (default: shell user)\n"); printf(" -p <password> password for the database user (will prompt if omitted)\n"); printf(" -w never prompt for password\n"); printf("\n"); result = 1; goto cleanup; } if (!logfile) { wordexp("~/tfadmin.log", &expresult, 0); logfile = strdup(expresult.we_wordv[0]); wordfree(&expresult); } config_init(&config); if (config_read_file(&config, cfgfile) != CONFIG_TRUE) { fprintf(stderr, "tfadmin: failed to read config file!\n"); result = 1; goto cleanup; } config_lookup_string(&config, "configdsn", &dbdsn); nport = (port) ? atoi(port) : 0; if (port && (nport == 0 || nport != (nport & 0xffff))) { fprintf(stderr, "listening port must be a valid TCP port number (was %d)\n", nport); result = 1; goto cleanup_config; } else if (!port) port = strdup("8080"); /* default */ if (prefix && (strcmp(prefix, "") == 0 || prefix[0] != '/')) { fprintf(stderr, "prefix must be a valid URI (was %s)\n", prefix); result = 1; goto cleanup_config; } else if (!prefix) prefix = strdup("/tfs"); /* default */ if (!dbuser && shuser) dbuser = strdup(shuser); else if (!dbuser) { fprintf(stderr, "tfadmin: no database user specified!\n"); result = 1; goto cleanup_config; } if (!nopass && !dbpasswd) { snprintf(prompt, 64, "Password for user %s: ", dbuser); dbpasswd = getpass(prompt); } else if (!dbpasswd) dbpasswd = strdup(""); if (!log_open(logfile, lev, fg)) { fprintf(stderr, "tfadmin: failed to open log file!\n"); result = 1; goto cleanup_config; } if (pg_pool_init(1) != 1) { log_fatal("failed to initialise PG context pool"); fprintf(stderr, "tfadmin: failed to initialise (see %s for details)\n", logfile); result = 1; goto cleanup_log; } if (!pg_connect(dbdsn, dbuser, dbpasswd, 1, NULL)) { log_fatal("failed to connect to PG"); fprintf(stderr, "tfadmin: failed to connect to the database (see %s for details)\n", logfile); result = 1; goto cleanup_db; } pgctx *ctx = pg_context_acquire(NULL); if (!ctx) { log_fatal("failed to obtain PG context!"); fprintf(stderr, "tfadmin: failed to connect to the database (see %s for details)\n", logfile); result = 1; goto cleanup_db; } if (tf_fetch_hosts(ctx, &hostarr) == TF_ERROR_SUCCESS) { hostarr = tf_free_host_array(hostarr); pg_context_release(ctx); printf("Team Foundation deployment is already initialised\n"); goto cleanup_db; } pg_context_release(ctx); ctx = pg_acquire_trans(NULL); if (!ctx) { log_fatal("failed to obtain PG context!"); fprintf(stderr, "tfadmin: failed to connect to the database (see %s for details)\n", logfile); result = 1; goto cleanup_db; } if (tf_init_configdb(ctx) != TF_ERROR_SUCCESS) goto error; printf("Building initial catalog\n"); orgroot = tf_new_node( NULL, TF_CATALOG_TYPE_ORGANIZATIONAL_ROOT, "Organizational Root", "The root of the catalog tree that describes the organizational makeup of the TFS deployment."); sprintf(orgroot->child, TF_CATALOG_ORGANIZATION_ROOT); if ((dberr = tf_add_node(ctx, orgroot)) != TF_ERROR_SUCCESS) goto error; infroot = tf_new_node( NULL, TF_CATALOG_TYPE_INFRASTRUCTURE_ROOT, "Infrastructure Root", "The root of the catalog tree that describes the physical makeup of the TFS deployment."); sprintf(infroot->child, TF_CATALOG_INFRASTRUCTURE_ROOT); if ((dberr = tf_add_node(ctx, infroot)) != TF_ERROR_SUCCESS) goto error; servinst = tf_new_node( orgroot, TF_CATALOG_TYPE_SERVER_INSTANCE, "Team Foundation Server Instance", NULL); dberr = tf_add_node(ctx, servinst); if (dberr != TF_ERROR_SUCCESS) goto error; printf("Registering services\n"); if (!hostname[0]) gethostname(hostname, _POSIX_HOST_NAME_MAX); snprintf(serveruri, _POSIX_HOST_NAME_MAX * 2, "http://%s:%s/%s", hostname, port, prefix); accmap = tf_new_access_map(TF_ACCESSMAP_PUBLIC_MONIKER, TF_ACCESSMAP_PUBLIC_DISPLNAME, serveruri); dberr = tf_add_access_map(ctx, accmap); if (dberr != TF_ERROR_SUCCESS) goto error; dberr = tf_set_default_access_map(ctx, accmap); accmap = tf_free_access_map(accmap); if (dberr != TF_ERROR_SUCCESS) goto error; tf_service *service = tf_new_service( TF_SERVICE_LOCATION_ID, TF_SERVICE_LOCATION_TYPE, TF_SERVICE_LOCATION_NAME, TF_CATALOG_TOOL_FRAMEWORK); tf_set_service_url(service, TF_LOCATION_SERVICE_ENDPOINT, TF_SERVICE_RELTO_CONTEXT); dberr = tf_add_service(ctx, service); if (dberr != TF_ERROR_SUCCESS) goto error; tf_service_ref *ref = tf_new_service_ref(&servinst->resource, service, "Location"); service = tf_free_service(service); dberr = tf_add_service_ref(ctx, ref); ref = tf_free_service_ref(ref); if (dberr != TF_ERROR_SUCCESS) goto error; service = tf_new_service( TF_SERVICE_CATALOG_ID, TF_SERVICE_CATALOG_TYPE, TF_SERVICE_CATALOG_NAME, TF_CATALOG_TOOL_FRAMEWORK); tf_set_service_url(service, TF_CATALOG_SERVICE_ENDPOINT, TF_SERVICE_RELTO_CONTEXT); dberr = tf_add_service(ctx, service); if (dberr != TF_ERROR_SUCCESS) goto error; ref = tf_new_service_ref(&servinst->resource, service, "Catalog"); service = tf_free_service(service); dberr = tf_add_service_ref(ctx, ref); ref = tf_free_service_ref(ref); if (dberr != TF_ERROR_SUCCESS) goto error; printf("Registering Team Foundation service host\n"); host = tf_new_host(TF_TEAM_FOUNDATION_SERVICE_NAME, dbdsn); dberr = tf_add_host(ctx, host); if (dberr != TF_ERROR_SUCCESS) goto error; instprop = tf_new_property( TF_PROPERTY_INSTANCE_ID_ID, servinst->resource.propertyid, host->id); dberr = tf_add_property(ctx, instprop); if (dberr != TF_ERROR_SUCCESS) goto error; printf("Team Foundation deployment is initialised\n"); pg_release_commit(ctx); goto cleanup_db; error: pg_release_rollback(ctx); result = 1; fprintf(stderr, "tfadmin: the operation failed (see %s for details)\n", logfile); cleanup_db: orgroot = tf_free_node(orgroot); infroot = tf_free_node(infroot); servinst = tf_free_node(servinst); host = tf_free_host(host); pg_disconnect(); cleanup_log: log_close(); cleanup_config: config_destroy(&config); cleanup: if (cfgfile) free(cfgfile); if (logfile) free(logfile); if (dbuser) free(dbuser); if (dbpasswd) free(dbpasswd); if (port) free(port); if (prefix) free(prefix); return result; }