static void gen_any( qli_nod* node, qli_req* request) { /************************************** * * g e n _ a n y * ************************************** * * Functional description * Generate the BLR for a statistical expresionn. * **************************************/ qli_rlb* rlb; // If there is a request associated with the statement, prepare to // generate BLR. Otherwise assume that a request is alrealdy initialized. qli_req* new_request = (qli_req*) node->nod_arg[e_any_request]; if (new_request) { request = new_request; gen_request(request); const qli_msg* receive = (qli_msg*) node->nod_arg[e_any_send]; if (receive) gen_send_receive(receive, blr_receive); const qli_msg* send = (qli_msg*) node->nod_arg[e_any_receive]; gen_send_receive(send, blr_send); rlb = CHECK_RLB(request->req_blr); STUFF(blr_if); } else rlb = CHECK_RLB(request->req_blr); STUFF(blr_any); gen_rse(node->nod_arg[e_any_rse], request); USHORT value; // not feasible to change it to bool. dsc desc; if (new_request) { desc.dsc_dtype = dtype_short; desc.dsc_length = sizeof(SSHORT); desc.dsc_scale = 0; desc.dsc_sub_type = 0; desc.dsc_address = (UCHAR*) &value; QLI_validate_desc(desc); STUFF(blr_assignment); value = TRUE; gen_literal(&desc, request); gen_parameter(node->nod_import, request); STUFF(blr_assignment); value = FALSE; gen_literal(&desc, request); gen_parameter(node->nod_import, request); gen_compile(request); } }
static int http_connect(git_transport *transport, int direction) { transport_http *t = (transport_http *) transport; int ret; git_buf request = GIT_BUF_INIT; const char *service = "upload-pack"; const char *url = t->parent.url, *prefix_http = "http://", *prefix_https = "https://"; const char *default_port; if (direction == GIT_DIR_PUSH) { giterr_set(GITERR_NET, "Pushing over HTTP is not implemented"); return -1; } t->parent.direction = direction; if (git_vector_init(&t->refs, 16, NULL) < 0) return -1; if (!git__prefixcmp(url, prefix_http)) { url = t->parent.url + strlen(prefix_http); default_port = "80"; } if (!git__prefixcmp(url, prefix_https)) { url += strlen(prefix_https); default_port = "443"; } t->path = strchr(url, '/'); if ((ret = gitno_extract_host_and_port(&t->host, &t->port, url, default_port)) < 0) goto cleanup; t->service = git__strdup(service); GITERR_CHECK_ALLOC(t->service); if ((ret = do_connect(t, t->host, t->port)) < 0) goto cleanup; /* Generate and send the HTTP request */ if ((ret = gen_request(&request, t->path, t->host, "GET", service, 0, 1)) < 0) { giterr_set(GITERR_NET, "Failed to generate request"); goto cleanup; } if (gitno_send(transport, request.ptr, request.size, 0) < 0) goto cleanup; ret = store_refs(t); cleanup: git_buf_free(&request); git_buf_clear(&t->buf); return ret; }
static void gen_database() { if (global_first_flag) return; global_first_flag = true; align(0); for (const gpre_req* request = gpreGlob.requests; request; request = request->req_next) gen_request(request); }
static void gen_store( qli_nod* node, qli_req* request) { /************************************** * * g e n _ s t o r e * ************************************** * * Functional description * Generate code for STORE statement. * **************************************/ // If there is a request associated with the statement, prepare to // generate BLR. Otherwise assume that a request is alrealdy initialized. if (node->nod_arg[e_sto_request]) { request = (qli_req*) node->nod_arg[e_sto_request]; gen_request(request); } qli_rlb* rlb = CHECK_RLB(request->req_blr); // If there is a message to be sent, build a receive for it if (node->nod_arg[e_sto_send]) gen_send_receive((qli_msg*) node->nod_arg[e_sto_send], blr_receive); // Generate the STORE statement proper. STUFF(blr_store); qli_ctx* context = (qli_ctx*) node->nod_arg[e_sto_context]; qli_rel* relation = context->ctx_relation; STUFF(blr_rid); STUFF_WORD(relation->rel_id); STUFF(context->ctx_context); // Build the body of the loop. STUFF(blr_begin); gen_statement(node->nod_arg[e_sto_statement], request); STUFF(blr_end); // If this is our request, compile it. if (node->nod_arg[e_sto_request]) gen_compile(request); }
static int http_stream_write_single( git_smart_subtransport_stream *stream, const char *buffer, size_t len) { http_stream *s = (http_stream *)stream; http_subtransport *t = OWNING_SUBTRANSPORT(s); git_buf request = GIT_BUF_INIT; assert(t->connected); if (s->sent_request) { giterr_set(GITERR_NET, "Subtransport configured for only one write"); return -1; } clear_parser_state(t); if (gen_request(&request, s, len) < 0) { giterr_set(GITERR_NET, "Failed to generate request"); return -1; } if (gitno_send(&t->socket, request.ptr, request.size, 0) < 0) goto on_error; if (len && gitno_send(&t->socket, buffer, len, 0) < 0) goto on_error; git_buf_free(&request); s->sent_request = 1; return 0; on_error: git_buf_free(&request); return -1; }
static int http_stream_write_chunked( git_smart_subtransport_stream *stream, const char *buffer, size_t len) { http_stream *s = (http_stream *)stream; http_subtransport *t = OWNING_SUBTRANSPORT(s); assert(t->connected); /* Send the request, if necessary */ if (!s->sent_request) { git_buf request = GIT_BUF_INIT; clear_parser_state(t); if (gen_request(&request, s, 0) < 0) { giterr_set(GITERR_NET, "Failed to generate request"); return -1; } if (gitno_send(&t->socket, request.ptr, request.size, 0) < 0) { git_buf_free(&request); return -1; } git_buf_free(&request); s->sent_request = 1; } if (len > CHUNK_SIZE) { /* Flush, if necessary */ if (s->chunk_buffer_len > 0) { if (write_chunk(&t->socket, s->chunk_buffer, s->chunk_buffer_len) < 0) return -1; s->chunk_buffer_len = 0; } /* Write chunk directly */ if (write_chunk(&t->socket, buffer, len) < 0) return -1; } else { /* Append as much to the buffer as we can */ int count = min(CHUNK_SIZE - s->chunk_buffer_len, len); if (!s->chunk_buffer) s->chunk_buffer = git__malloc(CHUNK_SIZE); memcpy(s->chunk_buffer + s->chunk_buffer_len, buffer, count); s->chunk_buffer_len += count; buffer += count; len -= count; /* Is the buffer full? If so, then flush */ if (CHUNK_SIZE == s->chunk_buffer_len) { if (write_chunk(&t->socket, s->chunk_buffer, s->chunk_buffer_len) < 0) return -1; s->chunk_buffer_len = 0; if (len > 0) { memcpy(s->chunk_buffer, buffer, len); s->chunk_buffer_len = len; } } } return 0; }
static int http_stream_read( git_smart_subtransport_stream *stream, char *buffer, size_t buf_size, size_t *bytes_read) { http_stream *s = (http_stream *)stream; http_subtransport *t = OWNING_SUBTRANSPORT(s); parser_context ctx; size_t bytes_parsed; replay: *bytes_read = 0; assert(t->connected); if (!s->sent_request) { git_buf request = GIT_BUF_INIT; clear_parser_state(t); if (gen_request(&request, s, 0) < 0) { giterr_set(GITERR_NET, "Failed to generate request"); return -1; } if (gitno_send(&t->socket, request.ptr, request.size, 0) < 0) { git_buf_free(&request); return -1; } git_buf_free(&request); s->sent_request = 1; } if (!s->received_response) { if (s->chunked) { assert(s->verb == post_verb); /* Flush, if necessary */ if (s->chunk_buffer_len > 0 && write_chunk(&t->socket, s->chunk_buffer, s->chunk_buffer_len) < 0) return -1; s->chunk_buffer_len = 0; /* Write the final chunk. */ if (gitno_send(&t->socket, "0\r\n\r\n", 5, 0) < 0) return -1; } s->received_response = 1; } while (!*bytes_read && !t->parse_finished) { t->parse_buffer.offset = 0; if (gitno_recv(&t->parse_buffer) < 0) return -1; /* This call to http_parser_execute will result in invocations of the * on_* family of callbacks. The most interesting of these is * on_body_fill_buffer, which is called when data is ready to be copied * into the target buffer. We need to marshal the buffer, buf_size, and * bytes_read parameters to this callback. */ ctx.t = t; ctx.s = s; ctx.buffer = buffer; ctx.buf_size = buf_size; ctx.bytes_read = bytes_read; /* Set the context, call the parser, then unset the context. */ t->parser.data = &ctx; bytes_parsed = http_parser_execute(&t->parser, &t->settings, t->parse_buffer.data, t->parse_buffer.offset); t->parser.data = NULL; /* If there was a handled authentication failure, then parse_error * will have signaled us that we should replay the request. */ if (PARSE_ERROR_REPLAY == t->parse_error) { s->sent_request = 0; if (http_connect(t) < 0) return -1; goto replay; } if (t->parse_error < 0) return -1; if (bytes_parsed != t->parse_buffer.offset) { giterr_set(GITERR_NET, "HTTP parser error: %s", http_errno_description((enum http_errno)t->parser.http_errno)); return -1; } } return 0; }
static int http_negotiate_fetch(git_transport *transport, git_repository *repo, const git_vector *wants) { transport_http *t = (transport_http *) transport; int ret; unsigned int i; char buff[128]; gitno_buffer buf; git_revwalk *walk = NULL; git_oid oid; git_pkt_ack *pkt; git_vector *common = &t->common; git_buf request = GIT_BUF_INIT, data = GIT_BUF_INIT; gitno_buffer_setup(transport, &buf, buff, sizeof(buff)); if (git_vector_init(common, 16, NULL) < 0) return -1; if (git_fetch_setup_walk(&walk, repo) < 0) return -1; do { if ((ret = do_connect(t, t->host, t->port)) < 0) goto cleanup; if ((ret = git_pkt_buffer_wants(wants, &t->caps, &data)) < 0) goto cleanup; /* We need to send these on each connection */ git_vector_foreach (common, i, pkt) { if ((ret = git_pkt_buffer_have(&pkt->oid, &data)) < 0) goto cleanup; } i = 0; while ((i < 20) && ((ret = git_revwalk_next(&oid, walk)) == 0)) { if ((ret = git_pkt_buffer_have(&oid, &data)) < 0) goto cleanup; i++; } git_pkt_buffer_done(&data); if ((ret = gen_request(&request, t->path, t->host, "POST", "upload-pack", data.size, 0)) < 0) goto cleanup; if ((ret = gitno_send(transport, request.ptr, request.size, 0)) < 0) goto cleanup; if ((ret = gitno_send(transport, data.ptr, data.size, 0)) < 0) goto cleanup; git_buf_clear(&request); git_buf_clear(&data); if (ret < 0 || i >= 256) break; if ((ret = parse_response(t)) < 0) goto cleanup; if (t->pack_ready) { ret = 0; goto cleanup; } } while(1); cleanup: git_buf_free(&request); git_buf_free(&data); git_revwalk_free(walk); return ret; }
static void gen_statistical( qli_nod* node, qli_req* request) { /************************************** * * g e n _ s t a t i s t i c a l * ************************************** * * Functional description * Generate the BLR for a statistical expresionn. * **************************************/ USHORT operatr; switch (node->nod_type) { case nod_average: operatr = blr_average; break; case nod_count: // count2 // operatr = node->nod_arg [e_stt_value] ? blr_count2 : blr_count; operatr = blr_count; break; case nod_max: operatr = blr_maximum; break; case nod_min: operatr = blr_minimum; break; case nod_total: operatr = blr_total; break; case nod_agg_average: operatr = blr_agg_average; break; case nod_agg_count: // count2 // operatr = node->nod_arg [e_stt_value] ? blr_agg_count2 : blr_agg_count; operatr = blr_agg_count; break; case nod_agg_max: operatr = blr_agg_max; break; case nod_agg_min: operatr = blr_agg_min; break; case nod_agg_total: operatr = blr_agg_total; break; case nod_from: operatr = node->nod_arg[e_stt_default] ? blr_via : blr_from; break; default: ERRQ_bugcheck(355); // Msg355 gen_statistical: not understood } // If there is a request associated with the statement, prepare to // generate BLR. Otherwise assume that a request is alrealdy initialized. qli_rlb* rlb; qli_req* new_request = (qli_req*) node->nod_arg[e_stt_request]; if (new_request) { request = new_request; gen_request(request); const qli_msg* receive = (qli_msg*) node->nod_arg[e_stt_send]; if (receive) gen_send_receive(receive, blr_receive); const qli_msg* send = (qli_msg*) node->nod_arg[e_stt_receive]; gen_send_receive(send, blr_send); rlb = CHECK_RLB(request->req_blr); STUFF(blr_assignment); } else rlb = CHECK_RLB(request->req_blr); STUFF(operatr); if (node->nod_arg[e_stt_rse]) gen_rse(node->nod_arg[e_stt_rse], request); // count 2 // if (node->nod_arg [e_stt_value]) if (node->nod_arg[e_stt_value] && node->nod_type != nod_agg_count) gen_expression(node->nod_arg[e_stt_value], request); if (node->nod_arg[e_stt_default]) gen_expression(node->nod_arg[e_stt_default], request); if (new_request) { gen_parameter(node->nod_import, request); gen_compile(request); } }
static void gen_function( qli_nod* node, qli_req* request) { /************************************** * * g e n _ f u n c t i o n * ************************************** * * Functional description * Generate blr for a function reference. * **************************************/ qli_req* new_request; qli_rlb* rlb; // If there is a request associated with the statement, prepare to // generate BLR. Otherwise assume that a request is already initialized. if (request && (request->req_flags & (REQ_project | REQ_group_by))) { new_request = NULL; rlb = CHECK_RLB(request->req_blr); } else if (new_request = (qli_req*) node->nod_arg[e_fun_request]) { request = new_request; gen_request(request); const qli_msg* receive = (qli_msg*) node->nod_arg[e_fun_send]; if (receive) gen_send_receive(receive, blr_receive); const qli_msg* send = (qli_msg*) node->nod_arg[e_fun_receive]; gen_send_receive(send, blr_send); rlb = CHECK_RLB(request->req_blr); STUFF(blr_assignment); } else rlb = CHECK_RLB(request->req_blr); // Generate function body STUFF(blr_function); qli_fun* function = (qli_fun*) node->nod_arg[e_fun_function]; qli_symbol* symbol = function->fun_symbol; STUFF(symbol->sym_length); for (const UCHAR* p = (UCHAR*) symbol->sym_string; *p;) STUFF(*p++); // Generate function arguments qli_nod* args = node->nod_arg[e_fun_args]; STUFF(args->nod_count); qli_nod** ptr = args->nod_arg; for (const qli_nod* const* const end = ptr + args->nod_count; ptr < end; ptr++) gen_expression(*ptr, request); if (new_request) { gen_parameter(node->nod_import, request); gen_compile(request); } }
static void gen_for( qli_nod* node, qli_req* request) { /************************************** * * g e n _ f o r * ************************************** * * Functional description * Generate BLR for a FOR loop, included synchronization messages. * **************************************/ // If there is a request associated with the statement, prepare to // generate BLR. Otherwise assume that a request is alrealdy initialized. if (node->nod_arg[e_for_request]) { request = (qli_req*) node->nod_arg[e_for_request]; gen_request(request); } qli_rlb* rlb = CHECK_RLB(request->req_blr); // If the statement requires an end of file marker, build a BEGIN/END around // the whole statement. const qli_msg* message = (qli_msg*) node->nod_arg[e_for_receive]; if (message) STUFF(blr_begin); // If there is a message to be sent, build a receive for it if (node->nod_arg[e_for_send]) gen_send_receive((qli_msg*) node->nod_arg[e_for_send], blr_receive); // Generate the FOR loop proper. STUFF(blr_for); gen_rse(node->nod_arg[e_for_rse], request); STUFF(blr_begin); // If data is to be received (included EOF), build a send const qli_par* eof = 0; dsc desc; USHORT value; if (message) { gen_send_receive(message, blr_send); STUFF(blr_begin); // Build assigments for all values referenced. for (const qli_par* parameter = message->msg_parameters; parameter; parameter = parameter->par_next) { if (parameter->par_value) { STUFF(blr_assignment); gen_expression(parameter->par_value, request); gen_parameter(parameter, request); } } // Next, make a FALSE for the end of file parameter eof = (qli_par*) node->nod_arg[e_for_eof]; desc.dsc_dtype = dtype_short; desc.dsc_length = sizeof(SSHORT); desc.dsc_scale = 0; desc.dsc_sub_type = 0; desc.dsc_address = (UCHAR*) &value; QLI_validate_desc(desc); STUFF(blr_assignment); value = FALSE; gen_literal(&desc, request); gen_parameter(eof, request); STUFF(blr_end); } // Build the body of the loop. const qli_msg* continuation = request->req_continue; if (continuation) { STUFF(blr_label); const USHORT label = request->req_label++; STUFF(label); STUFF(blr_loop); STUFF(blr_select); gen_send_receive(continuation, blr_receive); STUFF(blr_leave); STUFF(label); } qli_nod* sub = node->nod_arg[e_for_statement]; gen_statement(sub, request); STUFF(blr_end); if (continuation) STUFF(blr_end); // Finish off by building a SEND to indicate end of file if (message) { gen_send_receive(message, blr_send); STUFF(blr_assignment); value = TRUE; gen_literal(&desc, request); gen_parameter(eof, request); STUFF(blr_end); } // If this is our request, compile it. if (node->nod_arg[e_for_request]) gen_compile(request); }