void logger_perror_at(const char *filename, unsigned int linenum, const char *format, ...) { begin_log_line(MC_ERROR); va_list ap; va_start(ap, format); vmbuf_sprintf(&log_buf, "[%s:%u]: ", filename, linenum); vmbuf_vsprintf(&log_buf, format, ap); char tmp[512]; vmbuf_sprintf(&log_buf, " (%s)", strerror_r(errno, tmp, 512)); va_end(ap); end_log_line(STDERR_FILENO); }
static inline int make_ht_key(struct vmbuf *buf, const struct mysql_login_info *info) { vmbuf_reset(buf); if (0 > vmbuf_sprintf(buf, "%s,%s,%s,%s,%u", info->host, info->user, info->pass, info->db, info->port)) return -1; return 0; }
int http_server_sendfile2(const char *filename, const char *additional_headers, const char *ext) { if (0 == *filename) filename = "."; struct http_server_context *ctx = http_server_get_context(); int ffd = open(filename, O_RDONLY); if (ffd < 0) return HTTP_SERVER_NOT_FOUND; struct stat st; if (0 > fstat(ffd, &st)) { LOGGER_PERROR(filename); close(ffd); return HTTP_SERVER_NOT_FOUND; } if (S_ISDIR(st.st_mode)) { close(ffd); return 1; } vmbuf_reset(&ctx->header); if (NULL != ext) http_server_header_start(HTTP_STATUS_200, mime_types_by_ext(ext)); else http_server_header_start(HTTP_STATUS_200, mime_types_by_filename(filename)); vmbuf_sprintf(&ctx->header, "%s%lu", CONTENT_LENGTH, st.st_size); if (additional_headers) vmbuf_strcpy(&ctx->header, additional_headers); http_server_header_close(); int res = http_server_sendfile_payload(ffd, st.st_size); close(ffd); if (0 > res) LOGGER_PERROR(filename); return res; }
static void write_out_stream (const char *filename, char *data) { vmbuf_reset(&write_buffer); vmbuf_sprintf(&write_buffer, "{ \"message\": \"%s|%s|", hostname, filename); json_escape_str_vmb(&write_buffer, data); vmbuf_strcpy(&write_buffer, "\" }"); vmbuf_chrcpy(&write_buffer, '\0'); if (write_to_file) { if (0 > file_writer_write(&fw, vmbuf_data(&write_buffer), vmbuf_wlocpos(&write_buffer))) { LOGGER_ERROR("%s", "failed write attempt on outfile| aborting to diagnose!"); abort(); } return; } int threshold = INTERFACE_ONERROR_RETRY_THRESHOLD; while (0 > post_to_interface(vmbuf_data(&write_buffer), vmbuf_wlocpos(&write_buffer)) && (0 < threshold--)) { if (0 == post_to_interface(vmbuf_data(&write_buffer), vmbuf_wlocpos(&write_buffer))) { LOGGER_ERROR("post failed to %s, issuing reattempt#%d", eserv.hostname, threshold); --failure; break; } } }
struct vmbuf *http_server_end_cookie(time_t expires, const char *domain, const char *path) { struct vmbuf *buf = &http_server_get_context()->header; struct tm tm; gmtime_r(&expires, &tm); vmbuf_sprintf(buf, "\";Path=%s;Domain=%s;Expires=", path, domain); vmbuf_strftime(buf, "%a, %d-%b-%Y %H:%M:%S %Z", &tm); return buf; }
static void begin_log_line(const char *msg_class) { struct tm tm, *tmp; struct timeval tv; gettimeofday(&tv, NULL); tmp = localtime_r(&tv.tv_sec, &tm); vmbuf_init(&log_buf, 4096); vmbuf_strftime(&log_buf, "%Y-%m-%d %H:%M:%S", tmp); vmbuf_sprintf(&log_buf, ".%03d.%03d %d %s ", tv.tv_usec / 1000, tv.tv_usec % 1000, getpid(), msg_class); }
int http_client_pool_post_request_send(struct http_client_context *context, struct vmbuf *post_data) { size_t size = vmbuf_wlocpos(post_data); vmbuf_sprintf(&context->request, "\r\nContent-Length: %zu\r\n\r\n", size); // TODO: use writev instead of copying vmbuf_memcpy(&context->request, vmbuf_data(post_data), size); if (0 > http_client_send_request(context)) { http_client_free(context); return -1; } return 0; }
void logger_perror(const char *format, ...) { begin_log_line(MC_ERROR); va_list ap; va_start(ap, format); char tmp[512]; vmbuf_vsprintf(&log_buf, format, ap); vmbuf_sprintf(&log_buf, " (%s)", strerror_r(errno, tmp, 512)); va_end(ap); end_log_line(STDERR_FILENO); }
struct http_client_context *http_client_pool_post_request_init(struct http_client_pool *http_client_pool, struct in_addr addr, uint16_t port, const char *hostname, const char *format, ...) { struct http_client_context *cctx = http_client_pool_create_client(http_client_pool, addr, port, NULL); if (NULL == cctx) return NULL; vmbuf_strcpy(&cctx->request, "POST "); va_list ap; va_start(ap, format); vmbuf_vsprintf(&cctx->request, format, ap); va_end(ap); vmbuf_sprintf(&cctx->request, " HTTP/1.1\r\nHost: %s", hostname); return cctx; }
int http_client_pool_get_request(struct http_client_pool *http_client_pool, struct in_addr addr, uint16_t port, const char *hostname, const char *format, ...) { struct http_client_context *cctx = http_client_pool_create_client(http_client_pool, addr, port, NULL); if (NULL == cctx) return -1; vmbuf_strcpy(&cctx->request, "GET "); va_list ap; va_start(ap, format); vmbuf_vsprintf(&cctx->request, format, ap); va_end(ap); vmbuf_sprintf(&cctx->request, " HTTP/1.1\r\nHost: %s\r\n\r\n", hostname); if (0 > http_client_send_request(cctx)) { http_client_free(http_client_pool, cctx); return -1; } return 0; }
int http_server_generate_dir_list(const char *URI) { struct http_server_context *ctx = http_server_get_context(); struct vmbuf *payload = &ctx->payload; const char *dir = URI; if (*dir == '/') ++dir; if (0 == *dir) dir = "."; vmbuf_sprintf(payload, "<html><head><title>Index of %s</title></head>", dir); vmbuf_strcpy(payload, "<body>"); vmbuf_sprintf(payload, "<h1>Index of %s</h1><hr>", dir); vmbuf_sprintf(payload, "<a href=\"..\">../</a><br><br>"); vmbuf_sprintf(payload, "<table width=\"100%%\" border=\"0\">"); DIR *d = opendir(dir); int error = 0; if (d) { struct dirent de, *dep; while (0 == readdir_r(d, &de, &dep) && dep) { if (de.d_name[0] == '.') continue; struct stat st; if (0 > fstatat(dirfd(d), de.d_name, &st, 0)) { vmbuf_sprintf(payload, "<tr><td>ERROR: %s</td><td>N/A</td></tr>", de.d_name); continue; } const char *slash = (S_ISDIR(st.st_mode) ? "/" : ""); struct tm t_res, *t; t = localtime_r(&st.st_mtime, &t_res); vmbuf_strcpy(payload, "<tr>"); vmbuf_sprintf(payload, "<td><a href=\"%s%s\">%s%s</a></td>", de.d_name, slash, de.d_name, slash); vmbuf_strcpy(payload, "<td>"); if (t) vmbuf_strftime(payload, "%F %T", t); vmbuf_strcpy(payload, "</td>"); vmbuf_sprintf(payload, "<td>%lu</td>", st.st_size); vmbuf_strcpy(payload, "</tr>"); } closedir(d); } vmbuf_strcpy(payload, "<tr><td colspan=3><hr></td></tr></table>"); vmbuf_sprintf(payload, "<address>RIBS 2.0 Port %hu</address></body>", ctx->server->port); vmbuf_strcpy(payload, "</html>"); return error; }
static int http_client_pool_post_request2( struct http_client_pool *http_client_pool, struct in_addr addr, uint16_t port, const char *hostname, const char *data, size_t size_of_data, const char *format, ...) { struct http_client_context *cctx = http_client_pool_create_client2(http_client_pool, addr, port, hostname, NULL); if (NULL == cctx) return -1; vmbuf_reset(&cctx->request); vmbuf_strcpy(&cctx->request, "POST "); va_list ap; va_start(ap, format); vmbuf_vsprintf(&cctx->request, format, ap); va_end(ap); vmbuf_sprintf(&cctx->request, " HTTP/1.1\r\nHost: %s\r\nContent-Type: application/json\r\nContent-Length: %zu\r\n\r\n", hostname, size_of_data); vmbuf_memcpy(&cctx->request, data, size_of_data); vmbuf_chrcpy(&cctx->request, '\0'); if (0 > http_client_send_request(cctx)) return http_client_free(cctx), -1; return 0; }
void logger_vlog_func_at(int fd, const char *filename, unsigned int linenum, const char *funcname, const char *format, const char *msg_class, va_list ap) { begin_log_line(msg_class); vmbuf_sprintf(&log_buf, "[%s:%u] %s(): ", filename, linenum, funcname); vmbuf_vsprintf(&log_buf, format, ap); end_log_line(fd); }
int sendemail2(struct sendemail_mta *mta, struct email *email) { if (NULL == mta) { mta = global_mta; } int cfd = socket(PF_INET, SOCK_STREAM | SOCK_NONBLOCK, IPPROTO_TCP); if (0 > cfd) return LOGGER_PERROR("sendemail: socket"), -1; const int option = 1; if (0 > setsockopt(cfd, SOL_SOCKET, SO_REUSEADDR, &option, sizeof(option))) return LOGGER_PERROR("sendemail: setsockopt SO_REUSEADDR"), close(cfd), -1; if (0 > setsockopt(cfd, IPPROTO_TCP, TCP_NODELAY, &option, sizeof(option))) return LOGGER_PERROR("sendemail: setsockopt TCP_NODELAY"), close(cfd), -1; if (0 > connect(cfd, (struct sockaddr *)&mta->saddr, sizeof(mta->saddr)) && EINPROGRESS != errno) return LOGGER_PERROR("sendemail: connect"), close(cfd), -1; if (0 > ribs_epoll_add(cfd, EPOLLIN | EPOLLOUT | EPOLLET, current_ctx)) return close(cfd), -1; struct vmbuf response = VMBUF_INITIALIZER; struct vmbuf request = VMBUF_INITIALIZER; vmbuf_init(&response, 4096); vmbuf_init(&request, 4096); int code = -1; size_t ofs = 0; READ_AND_CHECK(220); vmbuf_sprintf(&request, "EHLO %s\r\n", mta->myhost); SEND_DATA; READ_AND_CHECK(250); vmbuf_sprintf(&request, "MAIL FROM:<%s>\r\n", email->from); SEND_DATA; READ_AND_CHECK(250); struct rcptlist *rcpt = &email->rcpt; while (rcpt) { vmbuf_sprintf(&request, "RCPT TO:<%s>\r\n", rcpt->to); SEND_DATA; READ_AND_CHECK(250); rcpt = rcpt->next; } vmbuf_strcpy(&request, "DATA\r\n"); SEND_DATA; READ_AND_CHECK(354); struct iovec iov[2]= { [0] = { .iov_base = email->data, .iov_len = strlen(email->data) },
void http_server_fiber_main(void) { struct http_server_context *ctx = http_server_get_context(); struct http_server *server = ctx->server; int fd = ctx->fd; char *URI; char *headers; char *content; size_t content_length; int res; ctx->persistent = 0; vmbuf_init(&ctx->request, server->init_request_size); vmbuf_init(&ctx->header, server->init_header_size); vmbuf_init(&ctx->payload, server->init_payload_size); size_t max_req_size = server->max_req_size; for (;; http_server_yield()) { READ_FROM_SOCKET(); if (vmbuf_wlocpos(&ctx->request) > MIN_HTTP_REQ_SIZE) break; } do { if (0 == SSTRNCMP(GET, vmbuf_data(&ctx->request)) || 0 == SSTRNCMP(HEAD, vmbuf_data(&ctx->request))) { /* GET or HEAD */ while (0 != SSTRNCMP(CRLFCRLF, vmbuf_wloc(&ctx->request) - SSTRLEN(CRLFCRLF))) { http_server_yield(); READ_FROM_SOCKET(); } /* make sure the string is \0 terminated */ /* this will overwrite the first CR */ *(vmbuf_wloc(&ctx->request) - SSTRLEN(CRLFCRLF)) = 0; char *p = vmbuf_data(&ctx->request); ctx->persistent = check_persistent(p); URI = strchrnul(p, ' '); /* can't be NULL GET and HEAD constants have space at the end */ *URI = 0; ++URI; // skip the space p = strchrnul(URI, '\r'); /* HTTP/1.0 */ headers = p; if (0 != *headers) /* are headers present? */ headers += SSTRLEN(CRLF); /* skip the new line */ *p = 0; p = strchrnul(URI, ' '); /* truncate the version part */ *p = 0; /* \0 at the end of URI */ ctx->content = NULL; ctx->content_len = 0; /* minimal parsing and call user function */ http_server_process_request(URI, headers); } else if (0 == SSTRNCMP(POST, vmbuf_data(&ctx->request)) || 0 == SSTRNCMP(PUT, vmbuf_data(&ctx->request))) { /* POST or PUT */ for (;;) { *vmbuf_wloc(&ctx->request) = 0; /* wait until we have the header */ if (NULL != (content = strstr(vmbuf_data(&ctx->request), CRLFCRLF))) break; http_server_yield(); READ_FROM_SOCKET(); } *content = 0; /* terminate at the first CR like in GET */ content += SSTRLEN(CRLFCRLF); size_t content_ofs = content - vmbuf_data(&ctx->request); if (strstr(vmbuf_data(&ctx->request), EXPECT_100)) { vmbuf_sprintf(&ctx->header, "%s %s\r\n\r\n", HTTP_SERVER_VER, HTTP_STATUS_100); if (0 > vmbuf_write(&ctx->header, fd)) { close(fd); return; } vmbuf_reset(&ctx->header); } ctx->persistent = check_persistent(vmbuf_data(&ctx->request)); /* parse the content length */ char *p = strcasestr(vmbuf_data(&ctx->request), CONTENT_LENGTH); if (NULL == p) { http_server_response(HTTP_STATUS_411, HTTP_CONTENT_TYPE_TEXT_PLAIN); break; } p += SSTRLEN(CONTENT_LENGTH); content_length = atoi(p); for (;;) { if (content_ofs + content_length <= vmbuf_wlocpos(&ctx->request)) break; http_server_yield(); READ_FROM_SOCKET(); } p = vmbuf_data(&ctx->request); URI = strchrnul(p, ' '); /* can't be NULL PUT and POST constants have space at the end */ *URI = 0; ++URI; /* skip the space */ p = strchrnul(URI, '\r'); /* HTTP/1.0 */ headers = p; if (0 != *headers) /* are headers present? */ headers += SSTRLEN(CRLF); /* skip the new line */ *p = 0; p = strchrnul(URI, ' '); /* truncate http version */ *p = 0; /* \0 at the end of URI */ ctx->content = vmbuf_data_ofs(&ctx->request, content_ofs); *(ctx->content + content_length) = 0; ctx->content_len = content_length; /* minimal parsing and call user function */ http_server_process_request(URI, headers); } else { http_server_response(HTTP_STATUS_501, HTTP_CONTENT_TYPE_TEXT_PLAIN); break; } } while(0); if (vmbuf_wlocpos(&ctx->header) > 0) { epoll_worker_resume_events(fd); http_server_write(); } if (ctx->persistent) { struct epoll_worker_fd_data *fd_data = epoll_worker_fd_map + fd; fd_data->ctx = server->idle_ctx; timeout_handler_add_fd_data(&server->timeout_handler, fd_data); } else close(fd); }
void http_server_header_content_length(void) { struct http_server_context *ctx = http_server_get_context(); vmbuf_sprintf(&ctx->header, "%s%zu", CONTENT_LENGTH, vmbuf_wlocpos(&ctx->payload)); }
/* inline */ int http_client_pool_post_request_content_type(struct http_client_context *context, const char *content_type) { return vmbuf_sprintf(&context->request, "\r\nContent-Type: %s", content_type); }
struct vmbuf *http_server_begin_cookie(const char *name) { struct vmbuf *buf = &http_server_get_context()->header; vmbuf_sprintf(buf, "\r\nSet-Cookie: %s=\"", name); return buf; }
void http_server_header_start_no_body(const char *status) { struct http_server_context *ctx = http_server_get_context(); vmbuf_sprintf(&ctx->header, "%s %s\r\nServer: %s%s%s", HTTP_SERVER_VER, status, HTTP_SERVER_NAME, CONNECTION, ctx->persistent ? CONNECTION_KEEPALIVE : CONNECTION_CLOSE); }
int mysql_dumper_dump(struct mysql_login_info *mysql_login_info, const char *outputdir, const char *dbname, const char *tablename, const char *query, size_t query_len, struct mysql_dumper_type *types) { MYSQL mysql; MYSQL_STMT *stmt = NULL; mysql_init(&mysql); my_bool b_flag = 1; if (0 != mysql_options(&mysql, MYSQL_OPT_RECONNECT, (const char *)&b_flag)) return report_error(&mysql); if (NULL == mysql_real_connect(&mysql, mysql_login_info->host, mysql_login_info->user, mysql_login_info->pass, mysql_login_info->db, mysql_login_info->port, NULL, CLIENT_COMPRESS)) return report_error(&mysql); b_flag = 0; if (0 != mysql_options(&mysql, MYSQL_REPORT_DATA_TRUNCATION, (const char *)&b_flag)) return report_error(&mysql); stmt = mysql_stmt_init(&mysql); if (!stmt) return report_error(&mysql); if (0 != mysql_stmt_prepare(stmt, query, query_len)) return report_stmt_error(&mysql, stmt); MYSQL_RES *rs = mysql_stmt_result_metadata(stmt); if (!rs) return report_stmt_error(&mysql, stmt); unsigned int n = mysql_num_fields(rs); MYSQL_FIELD *fields = mysql_fetch_fields(rs); int field_types[n]; MYSQL_BIND bind[n]; my_bool is_null[n]; unsigned long length[n]; my_bool error[n]; memset(bind, 0, sizeof(MYSQL_BIND) * n); int null_terminate_str[n]; memset(null_terminate_str, 0, sizeof(int) * n); struct file_writer ffields[n]; struct file_writer vfields[2][n]; struct vmbuf buf = VMBUF_INITIALIZER; vmbuf_init(&buf, 4096); vmbuf_sprintf(&buf, "%s/%s/%s/schema.txt", outputdir, dbname, tablename); mkdir_for_file_recursive(vmbuf_data(&buf)); int fdschema = creat(vmbuf_data(&buf), 0644); struct vmfile ds_txt = VMFILE_INITIALIZER; vmbuf_reset(&buf); vmbuf_sprintf(&buf, "%s/%s/%s/ds.txt", outputdir, dbname, tablename); if (0 > vmfile_init(&ds_txt, vmbuf_data(&buf), 4096)) return LOGGER_ERROR("failed to create: %s", vmbuf_data(&buf)), vmbuf_free(&buf), -1; vmfile_sprintf(&ds_txt, "DS_LOADER_BEGIN()\n"); vmfile_sprintf(&ds_txt, "/*\n * DB: %s\n */\n", dbname); vmfile_sprintf(&ds_txt, "#undef DB_NAME\n#define DB_NAME %s\n", dbname); ssize_t len = 80 - strlen(tablename); if (len < 0) len = 4; char header[len]; memset(header, '=', len); vmfile_sprintf(&ds_txt, "/* %.*s[ %s ]%.*s */\n", (int)len / 2, header, tablename, (int)(len - (len / 2)), header); vmfile_sprintf(&ds_txt, "# undef TABLE_NAME\n# define TABLE_NAME %s\n", tablename); /* * initialize output files */ unsigned int i; for (i = 0; i < n; ++i) { file_writer_make(&ffields[i]); file_writer_make(&vfields[0][i]); file_writer_make(&vfields[1][i]); } struct hashtable ht_types = HASHTABLE_INITIALIZER; hashtable_init(&ht_types, 32); if (NULL != types) { struct mysql_dumper_type *t = types; for (; t->name; ++t) { /* storing ptr here which points to static str */ hashtable_insert(&ht_types, t->name, strlen(t->name), t, sizeof(struct mysql_dumper_type)); } } /* * parse meta data and construct bind array */ int err = 0; for (i = 0; i < n; ++i) { field_types[i] = fields[i].type; bind[i].is_unsigned = IS_UNSIGNED(fields[i].flags); int64_t ds_type = -1; const char *ds_type_str = "VAR"; /* * handle overrides */ while (NULL != types) { uint32_t ofs = hashtable_lookup(&ht_types, fields[i].name, strlen(fields[i].name)); if (!ofs) break; struct mysql_dumper_type *type = (struct mysql_dumper_type *)hashtable_get_val(&ht_types, ofs); null_terminate_str[i] = MYSQL_DUMPER_CSTR & type->flags; if (type->mysql_type) field_types[i] = type->mysql_type; bind[i].is_unsigned = (type->flags & MYSQL_DUMPER_UNSIGNED) > 0 ? 1 : 0; break; } vmbuf_reset(&buf); vmbuf_sprintf(&buf, "%s/%s/%s/%s", outputdir, dbname, tablename, fields[i].name); mkdir_for_file_recursive(vmbuf_data(&buf)); if (is_var_length_field(field_types[i])) { size_t ofs = vmbuf_wlocpos(&buf); vmbuf_sprintf(&buf, ".ofs"); if (0 > (err = file_writer_init(&vfields[0][i], vmbuf_data(&buf)))) break; vmbuf_wlocset(&buf, ofs); vmbuf_sprintf(&buf, ".dat"); if (0 > (err = file_writer_init(&vfields[1][i], vmbuf_data(&buf)))) break; } else { ds_type = get_ds_type(field_types[i], bind[i].is_unsigned); const char *s = get_ds_type_str(ds_type); if (*s) ds_type_str = s; if (0 > (err = file_writer_init(&ffields[i], vmbuf_data(&buf))) || 0 > (err = file_writer_write(&ffields[i], &ds_type, sizeof(ds_type)))) break;; } len = ribs_mysql_get_storage_size(field_types[i], fields[i].length); if (fdschema > 0) dprintf(fdschema, "%03d name = %s, size=%zu, length=%lu, type=%s (%s), is_prikey=%d, ds_type=%s\n", i, fields[i].name, len, fields[i].length, ribs_mysql_get_type_name(field_types[i]), bind[i].is_unsigned ? "unsigned" : "signed", IS_PRI_KEY(fields[i].flags), ds_type_str); if (is_var_length_field(field_types[i])) { vmfile_sprintf(&ds_txt, " DS_VAR_FIELD_LOADER(%s)\n", fields[i].name); } else { vmfile_sprintf(&ds_txt, " DS_FIELD_LOADER(%s, %s)\n", ds_type_str, fields[i].name); } bind[i].buffer_type = field_types[i]; bind[i].buffer_length = len; bind[i].buffer = malloc(len); bind[i].is_null = &is_null[i]; bind[i].length = &length[i]; bind[i].error = &error[i]; } hashtable_free(&ht_types); mysql_free_result(rs); close(fdschema); //vmfile_sprintf(&ds_txt, "/*\n * TABLE END: %s\n */\n", tablename); vmfile_sprintf(&ds_txt, "DS_LOADER_END()\n"); vmfile_close(&ds_txt); /* * execute & bind */ if (0 != err || 0 != mysql_stmt_execute(stmt) || 0 != mysql_stmt_bind_result(stmt, bind)) { err = -1; report_stmt_error(&mysql, stmt); goto dumper_close_writer; } char zeros[4096]; memset(zeros, 0, sizeof(zeros)); int mysql_err = 0; size_t count = 0, num_rows_errors = 0; /* * write all rows to output files */ while (0 == (mysql_err = mysql_stmt_fetch(stmt))) { int b = 0; for (i = 0; i < n && !b; ++i) b = b || error[i]; if (b) { ++num_rows_errors; continue; } for (i = 0; i < n; ++i) { if (is_var_length_field(field_types[i])) { size_t ofs = file_writer_wlocpos(&vfields[1][i]); if (0 > (err = file_writer_write(&vfields[0][i], &ofs, sizeof(ofs))) || 0 > (err = file_writer_write(&vfields[1][i], is_null[i] ? NULL : bind[i].buffer, is_null[i] ? 0 : length[i]))) goto dumper_error; if (null_terminate_str[i]) { const char c = '\0'; if (0 > (err = file_writer_write(&vfields[1][i], &c, sizeof(c)))) goto dumper_error; } } else { if (0 > (err = file_writer_write(&ffields[i], is_null[i] ? zeros : bind[i].buffer, bind[i].buffer_length))) goto dumper_error; } } ++count; } /* no dumper errors */ goto dumper_ok; dumper_error: LOGGER_ERROR("failed to write data, aborting"); dumper_ok: /* we are done with mysql, close it */ mysql_stmt_close(stmt); mysql_close(&mysql); LOGGER_INFO("%s: %zu records, %zu skipped", tablename, count, num_rows_errors); /* check for mysql errors */ if (mysql_err != MYSQL_NO_DATA) { LOGGER_ERROR("mysql_stmt_fetch returned an error (code=%d)\n", mysql_err); err = -1; } dumper_close_writer: /* * finalize & free memory */ for (i = 0; i < n; ++i) { if (is_var_length_field(field_types[i])) { size_t ofs = file_writer_wlocpos(&vfields[1][i]); if (0 > (err = file_writer_write(&vfields[0][i], &ofs, sizeof(ofs)))) LOGGER_ERROR("failed to write offset"); file_writer_close(&vfields[0][i]); file_writer_close(&vfields[1][i]); } else { file_writer_close(&ffields[i]); } free(bind[i].buffer); } vmbuf_free(&buf); return err; }