int connector_write(connector *cr, unsigned char *msg, size_t sz) { if (cr && cr->state == STATE_CONNECTED) { return conn_write(cr->c, msg, sz); } return -1; }
void csync_send_file(FILE *in) { char buffer[512]; int rc, chunk; long size; fflush(in); size = ftell(in); rewind(in); conn_printf("octet-stream %ld\n", size); while ( size > 0 ) { chunk = size > 512 ? 512 : size; rc = fread(buffer, 1, chunk, in); if ( rc <= 0 ) csync_fatal("Read-error while sending data.\n"); chunk = rc; rc = conn_write(buffer, chunk); if ( rc != chunk ) csync_fatal("Write-error while sending data.\n"); size -= chunk; } }
void conn_reset(connection_t conn) { DCB tempdcb; unsigned char reset[] = { 0, 0xFF, 0 }; tempdcb.DCBlength = sizeof( DCB ); if ( !GetCommState( conn->hcomm, &tempdcb )) { return; } tempdcb.BaudRate = CBR_300 ; if ( !SetCommState( conn->hcomm, &tempdcb ) ) { return; } // Send reset sequence conn_write(conn, reset,sizeof(reset)); // delay a bit. It takes about 80ms to get sequence into board Sleep(80); SetCommState( conn->hcomm, &conn->dcb ); }
static int conn_puts(BIO *bp, const char *str) { int n,ret; n=TINYCLR_SSL_STRLEN(str); ret=conn_write(bp,str,n); return(ret); }
static int conn_puts(BIO *bp, const char *str) { int n,ret; n=strlen(str); ret=conn_write(bp,str,n); return(ret); }
static int net_connect_req_handler(struct net_handle_cxt* cxt, struct net_req* req) { PLOGD("Entering CONNECT handler!"); struct strbuf* buf = &req->data->buf; PLOGD("HTTP/%d.%d", req->ver_major, req->ver_minor); req->host = req->path; PLOGD("Host: %s", buf->p + req->host); PLOGD("Port: %d", req->port); struct conn* client = cxt->client; PLOGD("From client: %s", ep_tostring(&client->ep)); struct conn* server = net_connect_to_server(cxt, buf->p + req->host, htons(req->port)); if (server == NULL) { // No server available net_bad_gateway(client); return -1; } struct net_handle_list* p = mem_alloc(sizeof(struct net_handle_list)); p->server = server; mem_incref(server); p->next = NULL; p->req = req; mem_incref(req); if (cxt->head == NULL) cxt->head = cxt->tail = p; else { cxt->tail->next = p; cxt->tail = p; } event_post(cxt->ev_notice_rsp, (void*)1); static char msg[] = "HTTP/1.1 200 OK\r\n\r\n"; int ret = conn_write(client, msg, strlen(msg)); if (ret) { net_bad_gateway(client); mem_decref(server, conn_done); return -1; } while (1) { ret = conn_copy(server, client, 64*1024); if (ret) break; } PLOGI("%s CONNECT %s %d", ep_tostring(client), buf->p + req->host, client->tx); mem_decref(server, conn_done); return ret; }
static void send_smpp_thread(void *arg) { ESME *esme; Octstr *os; SMPP_PDU *pdu; unsigned long id; esme = arg; id = 0; while (!quitting && counter_value(num_to_esme) < max_to_esme) { id = counter_increase(num_to_esme) + 1; while (!quitting && counter_value(num_from_esme) + 500 < id) gwthread_sleep(1.0); if (quitting) break; pdu = smpp_pdu_create(deliver_sm, counter_increase(message_id_counter)); pdu->u.deliver_sm.source_addr = octstr_create("456"); pdu->u.deliver_sm.destination_addr = octstr_create("123"); pdu->u.deliver_sm.short_message = octstr_format("%ld", id); if (esme->version > 0x33) pdu->u.deliver_sm.receipted_message_id = octstr_create("receipted_message_id\0"); os = smpp_pdu_pack(NULL, pdu); conn_write(esme->conn, os); octstr_destroy(os); smpp_pdu_destroy(pdu); if (first_to_esme == (time_t) -1) time(&first_to_esme); debug("test.smpp", 0, "Delivered SMS %ld of %ld to bearerbox via SMPP.", id, max_to_esme); if ((id % enquire_interval) == 0) { pdu = smpp_pdu_create(enquire_link, counter_increase(message_id_counter)); os = smpp_pdu_pack(NULL, pdu); conn_write(esme->conn, os); octstr_destroy(os); smpp_pdu_destroy(pdu); debug("test.smpp", 0, "Sent enquire_link to bearerbox."); } } time(&last_to_esme); if (id == max_to_esme) info(0, "All messages sent to ESME."); debug("test.smpp", 0, "%s terminates.", __func__); }
void *worker_run(void* userdata) { int num_events, flush_outbox; worker_t* self = userdata; ev_event_t *event; conn_t *conn; ev_init(&self->loop); ev_watch(&self->loop, self->conn_queue[0], EV_READABLE, self); ev_watch(&self->loop, self->msg_queue[0], EV_READABLE, NULL); while(self->running) { num_events = ev_poll(&self->loop); flush_outbox = 0; if (num_events == -1) continue; while (--num_events >= 0) { event = self->loop.fired[num_events]; if (!event->fired) continue; if (!event->userdata) { if (event->fired & EV_READABLE) worker_flush_inbox(self); else flush_outbox = 1; continue; } else if (event->userdata == self) { worker_accept(self); continue; } conn = event->userdata; if (event->fired & EV_READABLE) if (conn_read(conn) == -1) continue; if (event->fired & EV_WRITEABLE) if (conn_write(conn) == -1) continue; } if (flush_outbox) worker_flush_outbox(self); } worker_cleanup(self); return NULL; }
static bool echo_write(conn_t *conn, struct buf *buf) { if (!conn_write(conn, buf->bytes, buf->used)) { free(buf); return false; } conn_next(conn, echo_close, NULL); next_close(conn, buf); return true; }
int conn_write(conn *c, unsigned short cmd, uint64_t uid) { unsigned char *msg; size_t sz; int ret = create_msg(cmd, uid, &msg, &sz); if (0 != ret) return ret; ret = conn_write(c, msg, sz); free(msg); return ret; }
static int sms_to_client(Connection *client, Msg *msg) { Octstr *line; Octstr *msgdata = NULL; /* NULL to allow octstr_destroy */ char *contents; int len; debug("bb.sms", 0, "smsc_fake: sending message to client"); // msg_dump(msg, 0); line = octstr_duplicate(msg->sms.sender); octstr_append_char(line, ' '); octstr_append(line, msg->sms.receiver); if (octstr_len(msg->sms.udhdata)) { octstr_append(line, octstr_imm(" udh ")); msgdata = octstr_duplicate(msg->sms.udhdata); octstr_url_encode(msgdata); octstr_append(line, msgdata); octstr_destroy(msgdata); octstr_append_char(line, ' '); msgdata = octstr_duplicate(msg->sms.msgdata); octstr_url_encode(msgdata); octstr_append(line, msgdata); } else { contents = octstr_get_cstr(msg->sms.msgdata); len = octstr_len(msg->sms.msgdata); while (len > 0) { len--; if (contents[len] < 32 || contents[len] > 126) { octstr_append(line, octstr_imm(" data ")); msgdata = octstr_duplicate(msg->sms.msgdata); octstr_url_encode(msgdata); octstr_append(line, msgdata); goto notelse; /* C lacks "else" clause for while loops */ } } octstr_append(line, octstr_imm(" text ")); octstr_append(line, msg->sms.msgdata); } notelse: octstr_append_char(line, 10); if (conn_write(client, line) == -1) { octstr_destroy(msgdata); octstr_destroy(line); return -1; } octstr_destroy(msgdata); octstr_destroy(line); return 1; }
static int sms_to_client(Connection *client, Msg *msg) { Octstr *line; Octstr *msgdata = NULL; /* NULL to allow octstr_destroy */ debug("bb.sms", 0, "smsc_fake: sending message to client"); /* msg_dump(msg, 0); */ line = octstr_duplicate(msg->sms.sender); octstr_append_char(line, ' '); octstr_append(line, msg->sms.receiver); if (octstr_len(msg->sms.udhdata)) { octstr_append(line, octstr_imm(" udh ")); msgdata = octstr_duplicate(msg->sms.udhdata); octstr_url_encode(msgdata); octstr_append(line, msgdata); octstr_destroy(msgdata); octstr_append(line, octstr_imm(" data ")); msgdata = octstr_duplicate(msg->sms.msgdata); octstr_url_encode(msgdata); octstr_append(line, msgdata); } else { if (msg->sms.coding == DC_8BIT) { octstr_append(line, octstr_imm(" data ")); msgdata = octstr_duplicate(msg->sms.msgdata); octstr_url_encode(msgdata); octstr_append(line, msgdata); } else if (msg->sms.coding == DC_UCS2) { octstr_append(line, octstr_imm(" ucs-2 ")); msgdata = octstr_duplicate(msg->sms.msgdata); octstr_url_encode(msgdata); octstr_append(line, msgdata); } else { octstr_append(line, octstr_imm(" text ")); octstr_append(line, msg->sms.msgdata); } } octstr_append_char(line, 10); if (conn_write(client, line) == -1) { octstr_destroy(msgdata); octstr_destroy(line); return -1; } octstr_destroy(msgdata); octstr_destroy(line); return 1; }
static int do_write_response(client_ctx *cx) { conn *c = &cx->incoming; conn_write(c, c->resp_buf, c->resp_size); buff_pull(&cx->incoming); c->req_size = 0; c->resp_size = 0; conn_read(c); return s_read_size; }
static int cgwop_send(Connection *conn, struct cgwop *cgwop) { Octstr *dta = cgwop_tostr(cgwop); if (dta == NULL) return -1; /* couldn't convert to string */ if (conn_write(conn, dta) == -1) { octstr_destroy(dta); return -1; } octstr_destroy(dta); return 1; }
static void handle_pdu(ESME *esme, SMPP_PDU *pdu) { SMPP_PDU *resp; Octstr *os; int i; debug("test.smpp", 0, "Handling SMPP PDU of type %s", pdu->type_name); for (i = 0; i < num_handlers; ++i) { if (handlers[i].type == pdu->type) { resp = handlers[i].handler(esme, pdu); if (resp != NULL) { os = smpp_pdu_pack(NULL, resp); conn_write(esme->conn, os); octstr_destroy(os); smpp_pdu_destroy(resp); } return; } } error(0, "Unhandled SMPP PDU."); smpp_pdu_dump(octstr_imm(""), pdu); }
int server_write(struct connection *server) { struct conn_info *info = server->info; if (!STAILQ_EMPTY(&info->ready_queue)) { server_make_iov(info); } if (info->iov.len <= 0) { cmd_iov_reset(&info->iov); return CORVUS_OK; } int status = conn_write(server, 0); if (status == CORVUS_ERR) { LOG(ERROR, "server_write: server %d fail to write iov", server->fd); return CORVUS_ERR; } if (status == CORVUS_AGAIN) return CORVUS_OK; ATOMIC_INC(info->send_bytes, status); if (info->iov.cursor >= info->iov.len) { cmd_iov_free(&info->iov); } if (!STAILQ_EMPTY(&info->ready_queue) || info->iov.cursor < info->iov.len) { if (conn_register(server) == CORVUS_ERR) { LOG(ERROR, "server_write: fail to reregister server %d", server->fd); return CORVUS_ERR; } } info->last_active = time(NULL); return CORVUS_OK; }
static int conn_puts(BIO *bp, const char *str) { return conn_write(bp, str, strlen(str)); }
static int net_transfer_body_HTTP_1_1(struct conn* dst, struct conn* src, struct net_data* data) { if (strcmp(data->buf.p, "HEAD") == 0) return 0; int ret = 0; char* keyval = net_data_get_ent(data, "Transfer-Encoding"); if (keyval == NULL || strcmp(keyval, "chunked")) { // Not chunked encoding keyval = net_data_get_ent(data, "Content-Length"); int len = 0; if (keyval) len += atoi(keyval); if (len > 0) { ret = conn_copy(dst, src, len); if (ret) return ret; } return 0; } // Transfer-Encoding: chunked // FIXME HTTP rfc tells that proxy should forward decoded body struct strbuf buf; strbuf_init(&buf); while (1) { strbuf_reset(&buf); ret = conn_gets(src, HTTP_CHUNK_HEADER_MAXLEN, &buf); if (ret <= 0) { ret = -1; break; } strbuf_cat(&buf, "\r\n"); ret = conn_write(dst, buf.p, buf.len); if (ret) { break; } int len = -1; sscanf(buf.p, "%x", &len); if (len == 0) { // Last chunck ret = 0; break; } // Also copy the \r\n ret = conn_copy(dst, src, len+2); if (ret) break; } if (ret == 0) { // Chunked trailer part while (1) { strbuf_reset(&buf); ret = conn_gets(src, HTTP_HEADER_MAXLEN, &buf); if (ret < 0) return ret; strbuf_cat(&buf, "\r\n"); if (conn_write(dst, buf.p, buf.len)) { ret = -1; break; } if (ret == 0) break; } } strbuf_done(&buf); return ret; }
void conn_prepare(connection_t conn) { unsigned char buffer[1]; buffer[0] = HDLC_frameFlag; conn_write(conn,buffer,1); }
enum conn_cbresult_t tcp_standard_callback(tcpconn_t *connection, enum conn_callback_t id, void *userdata) { int res = CONN_CBRESULT_OK; int n, advancestep; size_t used; time_t start, expire; int keysize; char *certsubject, *issuer, *fulltext; myconn_t *rec = (myconn_t *)userdata; dbgprintf("CB: %s\n", conn_callback_names[id]); switch (id) { case CONN_CB_CONNECT_START: /* Client mode: New outbound connection start */ break; case CONN_CB_CONNECT_FAILED: /* Client mode: New outbound connection failed */ rec->talkresult = TALK_CONN_FAILED; rec->textlog = newstrbuffer(0); addtobuffer(rec->textlog, strerror(connection->errcode)); conn_close_connection(connection, NULL); break; case CONN_CB_CONNECT_COMPLETE: /* Client mode: New outbound connection succeded */ rec->textlog = newstrbuffer(0); rec->talkresult = TALK_OK; /* Will change below if we fail later */ rec->readbufsz = USERBUFSZ; rec->readbuf = rec->readp = malloc(rec->readbufsz); *(rec->readbuf) = '\0'; rec->writebuf = rec->writep = malloc(USERBUFSZ); *(rec->writebuf) = '\0'; break; case CONN_CB_SSLHANDSHAKE_OK: /* Client/server mode: SSL handshake completed OK (peer certificate ready) */ certsubject = conn_peer_certificate(connection, &start, &expire, &keysize, &issuer, &fulltext); if (certsubject) { rec->peercertificate = certsubject; /* certsubject is malloc'ed by conn_peer_certificate */ rec->peercertificateissuer = issuer; /* ditto issuer */ rec->peercertificatestart = start; rec->peercertificateexpiry = expire; rec->peercertificatekeysize = keysize; rec->peercertificatedetails = fulltext; } if (strcasecmp(rec->dialog[rec->step], "CLOSE") == 0) conn_close_connection(connection, NULL); break; case CONN_CB_SSLHANDSHAKE_FAILED: /* Client/server mode: SSL handshake failed (connection will close) */ rec->talkresult = TALK_BADSSLHANDSHAKE; conn_close_connection(connection, NULL); break; case CONN_CB_READCHECK: /* Client/server mode: Check if application wants to read data */ if (!rec->dialog[rec->step]) res = CONN_CBRESULT_FAILED; else if (rec->istelnet > 0) res = CONN_CBRESULT_OK; else res = ((strncasecmp(rec->dialog[rec->step], "EXPECT:", 7) == 0) || (strncasecmp(rec->dialog[rec->step], "READ", 4) == 0)) ? CONN_CBRESULT_OK : CONN_CBRESULT_FAILED; break; case CONN_CB_READ: /* Client/server mode: Ready for application to read data w/ conn_read() */ /* Make sure we have some buffer space */ used = (rec->readp - rec->readbuf); if ((rec->readbufsz - used) < USERBUFSZ) { rec->readbufsz += USERBUFSZ; rec->readbuf = (char *)realloc(rec->readbuf, rec->readbufsz); rec->readp = rec->readbuf + used; } /* Read the data */ n = conn_read(connection, rec->readp, (rec->readbufsz - used - 1)); if (n <= 0) return CONN_CBRESULT_OK; /* n == 0 happens during SSL handshakes, n < 0 means connection will close */ rec->bytesread += n; /* Process data for some protocols */ if (rec->istelnet) n = telnet_datahandler(rec, n); if (rec->talkprotocol == TALK_PROTO_HTTP) n = http_datahandler(rec, n, 0, &advancestep); /* Save the data */ if (n > 0) { *(rec->readp + n) = '\0'; if (rec->talkprotocol == TALK_PROTO_PLAIN) addtobuffer(rec->textlog, rec->readp); rec->readp += n; } /* See how the dialog is progressing */ if (strncasecmp(rec->dialog[rec->step], "EXPECT:", 7) == 0) { int explen, expstart; expstart = 7 + strspn(rec->dialog[rec->step] + 7, " \t"); explen = strlen(rec->dialog[rec->step] + expstart); if ((n < explen) && (strncasecmp(rec->readbuf, rec->dialog[rec->step] + expstart, n) == 0)) { /* * Got the right data so far, but not the complete amount. * Do nothing, we'll just keep reading until we have all of the data */ } else if (strncasecmp(rec->readbuf, rec->dialog[rec->step] + expstart, explen) == 0) { /* Got the expected data, go to next step */ rec->step++; rec->readp = rec->readbuf; *rec->readp = '\0'; } else { /* Got some unexpected data, give up */ rec->talkresult = TALK_BADDATA; conn_close_connection(connection, NULL); } } else if (strcasecmp(rec->dialog[rec->step], "READALL") == 0) { /* No need to save the data twice (we store it in rec->textlog), so reset the readp to start of our readbuffer */ rec->readp = rec->readbuf; *(rec->readp) = '\0'; if (advancestep) rec->step++; } else if (strcasecmp(rec->dialog[rec->step], "READ") == 0) { rec->step++; } /* See if we have reached a point where we switch to TLS mode */ if (rec->dialog[rec->step] && (strcasecmp(rec->dialog[rec->step], "STARTTLS") == 0)) { res = CONN_CBRESULT_STARTTLS; rec->step++; } /* See if we're done */ if (strcasecmp(rec->dialog[rec->step], "CLOSE") == 0) conn_close_connection(connection, NULL); break; case CONN_CB_WRITECHECK: /* Client/server mode: Check if application wants to write data */ if (!rec->dialog[rec->step]) res = CONN_CBRESULT_FAILED; else if (rec->istelnet != 0) res = (rec->istelnet < 0) ? CONN_CBRESULT_OK : CONN_CBRESULT_FAILED; else { if ((*rec->writep == '\0') && (strncasecmp(rec->dialog[rec->step], "SEND:", 5) == 0)) { char *sendstart = rec->dialog[rec->step] + 5; sendstart += strspn(sendstart, " \t"); strcpy(rec->writebuf, sendstart); rec->writep = rec->writebuf; } res = (*rec->writep != '\0') ? CONN_CBRESULT_OK : CONN_CBRESULT_FAILED; } break; case CONN_CB_WRITE: /* Client/server mode: Ready for application to write data w/ conn_write() */ if (rec->istelnet < 0) { n = conn_write(connection, rec->writep, -(rec->istelnet)); if (n <= 0) return CONN_CBRESULT_OK; /* n == 0 happens during SSL handshakes, n < 0 means connection will close */ rec->writep += n; rec->istelnet += n; if (rec->istelnet == 0) rec->istelnet = 1; } else { n = conn_write(connection, rec->writep, strlen(rec->writep)); if (n <= 0) return CONN_CBRESULT_OK; /* n == 0 happens during SSL handshakes, n < 0 means connection will close */ if (n > 0) { rec->byteswritten += n; switch (rec->talkprotocol) { case TALK_PROTO_PLAIN: case TALK_PROTO_HTTP: addtobufferraw(rec->textlog, rec->writep, n); break; default: break; } rec->writep += n; if (*rec->writep == '\0') { rec->step++; /* Next step */ if (last_write_step(rec)) { conn_close_connection(connection, "w"); } } } } /* See if we have reached a point where we switch to TLS mode */ if (rec->dialog[rec->step] && (strcasecmp(rec->dialog[rec->step], "STARTTLS") == 0)) { res = CONN_CBRESULT_STARTTLS; rec->step++; } /* See if we're done */ if (strcasecmp(rec->dialog[rec->step], "CLOSE") == 0) conn_close_connection(connection, NULL); break; case CONN_CB_TIMEOUT: rec->talkresult = TALK_CONN_TIMEOUT; conn_close_connection(connection, NULL); break; case CONN_CB_CLOSED: /* Client/server mode: Connection has been closed */ /* See if we need to report an error from closing the connection unexpectedly */ if ((rec->talkresult == TALK_OK) && rec->dialog[rec->step]) { /* * We should only close if * - we hit a CLOSE command * - we hit the end of the command list (NULL dialog step) * - peer disconnects during a READ step * So if the current step is NOT a CLOSE or a READALL step, then * the close was unexpected - so flag it as an error. */ if ((strcasecmp(rec->dialog[rec->step], "CLOSE") != 0) && (strcasecmp(rec->dialog[rec->step], "READALL") != 0)) rec->talkresult = TALK_INTERRUPTED; } rec->elapsedus = connection->elapsedus; return 0; case CONN_CB_CLEANUP: /* Client/server mode: Connection cleanup */ if (rec->readbuf) xfree(rec->readbuf); if (rec->writebuf) xfree(rec->writebuf); connection->userdata = NULL; test_is_done(rec); return 0; default: break; } return res; }
/* The main program. */ int main(int argc, char **argv) { Connection *server; Octstr *line; Octstr **msgs; int i; int mptr, num_msgs; long num_received, num_sent; double first_received_at, last_received_at; double first_sent_at, last_sent_at; double start_time, end_time; double delta; int interactive, maxfd; char *cptr; char buffer[IN_BUFSIZE]; fd_set rset; struct timeval alarm; FILE *fp; gwlib_init(); setup_signal_handlers(); host = octstr_create("localhost"); start_time = get_current_time(); mptr = get_and_set_debugs(argc, argv, check_args); num_msgs = argc - mptr; interactive = 0; msgs = NULL; fp = NULL; if (num_msgs <= 0) { interactive = 1; num_msgs = 0; info(0, "Entering interactive mode. Type your message on the command line"); /* set up file pointer to stdin */ fp = stdin; /* initialize set for select */ FD_ZERO(&rset); } else { msgs = gw_malloc(sizeof(Octstr *) * num_msgs); for (i = 0; i < num_msgs; i ++) { msgs[i] = octstr_create(argv[mptr + i]); octstr_append_char(msgs[i], 10); /* End of line */ } info(0, "Host %s Port %d interval %.3f max-messages %ld", octstr_get_cstr(host), port, interval, max_send); srand((unsigned int) time(NULL)); } info(0, "fakesmsc starting"); server = conn_open_tcp(host, port, NULL); if (server == NULL) panic(0, "Failed to open connection"); num_sent = 0; num_received = 0; first_received_at = 0; first_sent_at = 0; last_received_at = 0; last_sent_at = 0; /* infinitely loop */ while (1) { /* Are we on interactive mode? */ if (interactive == 1) { /* Check if we need to clean things up beforehand */ if ( num_msgs > 0 ) { for (i = 0; i < num_msgs; i ++) octstr_destroy(msgs[i]); gw_free(msgs); num_msgs = 0; } /* we want either the file pointer or timer */ FD_SET(fileno(fp), &rset); /* get the largest file descriptor */ maxfd = fileno(fp) + 1; /* set timer to go off in 3 seconds */ alarm.tv_sec = IN_TIMEOUT; alarm.tv_usec = 0; if (select(maxfd, &rset, NULL, NULL, &alarm) == -1) goto over; /* something went off, let's see if it's stdin */ if (FD_ISSET(fileno(fp), &rset)) { /* stdin is readable */ cptr = fgets(buffer, IN_BUFSIZE, stdin); if( strlen( cptr ) < 2 ) goto rcv; } else { /* timer kicked in */ goto rcv; } num_msgs = 1; msgs = gw_malloc(sizeof(Octstr*)); msgs[0] = octstr_create(cptr); } /* if we still have something to send as MO message */ if (num_sent < max_send) { Octstr *os = choose_message(msgs, num_msgs); Octstr *msg = rnd > 0 ? randomize(os) : os; if (conn_write(server, msg) == -1) panic(0, "write failed"); ++num_sent; if (num_sent == max_send) info(0, "fakesmsc: sent message %ld", num_sent); else debug("send", 0, "fakesmsc: sent message %ld", num_sent); if (rnd > 0) octstr_destroy(msg); last_sent_at = get_current_time(); if (first_sent_at == 0) first_sent_at = last_sent_at; } rcv: do { delta = interval * num_sent - (get_current_time() - first_sent_at); if (delta < 0) delta = 0; if (num_sent >= max_send) delta = -1; conn_wait(server, delta); if (conn_error(server) || conn_eof(server) || sigint_received) goto over; /* read as much as the smsc module provides us */ while ((line = conn_read_line(server))) { last_received_at = get_current_time(); if (first_received_at == 0) first_received_at = last_received_at; ++num_received; if (num_received == max_send) { info(0, "Got message %ld: <%s>", num_received, octstr_get_cstr(line)); } else { debug("receive", 0, "Got message %ld: <%s>", num_received, octstr_get_cstr(line)); } octstr_destroy(line); } } while (delta > 0 || num_sent >= max_send); } over: conn_destroy(server); /* destroy the MO messages */ for (i = 0; i < num_msgs; i ++) octstr_destroy(msgs[i]); gw_free(msgs); end_time = get_current_time(); info(0, "fakesmsc: %ld messages sent and %ld received", num_sent, num_received); info(0, "fakesmsc: total running time %.1f seconds", end_time - start_time); delta = last_sent_at - first_sent_at; if (delta == 0) delta = .01; if (num_sent > 1) info(0, "fakesmsc: from first to last sent message %.1f s, " "%.1f msgs/s", delta, (num_sent - 1) / delta); delta = last_received_at - first_received_at; if (delta == 0) delta = .01; if (num_received > 1) info(0, "fakesmsc: from first to last received message %.1f s, " "%.1f msgs/s", delta, (num_received - 1) / delta); info(0, "fakesmsc: terminating"); return 0; }
static void proto_handle_get(conn_t* cn, const char* line) { struct stat st; // Reject filenames with just "." and ".." if(memcmp(line, ".\0", 2) == 0 || memcmp(line, "..\0", 3) == 0) { conn_printf(cn, "ERROR Protocol violation (%d)\n", __LINE__); conn_abort(cn); return; } if(lstat(line,&st) == 0) { if(S_ISREG(st.st_mode)) { int fd; md5_state_t md5_state; md5_init(&md5_state); char buffer[PATH_MAX]; ssize_t size; char md5str[33]; char modestr[11]; #ifdef O_NOATIME if((fd = open(line,O_RDONLY|O_NOATIME))==-1) { #else if((fd = open(line,O_RDONLY))==-1) { #endif conn_perror(cn, "WARNING open()"); conn_printf(cn, "WARNING Can't open file: %s\n", line); return; } // Calcuate MD5 { unsigned char md5bin[16]; while((size = read(fd, buffer, sizeof buffer))) md5_append(&md5_state, (unsigned char*)buffer, size); md5_finish(&md5_state, (unsigned char*)md5bin); if(lseek(fd, SEEK_SET, 0)==-1) { conn_perror(cn, "ERROR lseek()"); conn_abort(cn); return; } md5bin2str(md5bin, md5str); } mode2str(st.st_mode, modestr); conn_printf(cn, "PUT %ld %s %s %ld %ld %ld %s\n", (long int)st.st_size, md5str, modestr, st.st_atime, st.st_ctime, st.st_mtime, line); while((size = read(fd, buffer, sizeof buffer))) conn_write(cn, buffer, size); close(fd); } else if(S_ISDIR(st.st_mode)) { char modestr[11]; mode2str(st.st_mode, modestr); conn_printf(cn, "MKDIR %s %ld %ld %ld %s\n", modestr, st.st_atime, st.st_ctime, st.st_mtime, line); } else if(S_ISLNK(st.st_mode)) { char buffer[PATH_MAX]; conn_printf(cn, "SLNK %s\n", line); ssize_t l; if((l=readlink(line, buffer, sizeof buffer))==-1) { conn_perror(cn, "WARNING readlink()"); return; } buffer[l] = '\0'; conn_printf(cn, "%s\n", buffer); } else { conn_printf(cn, "WARNING Ignored %s\n", line); } } } static void proto_handle_put(conn_t* cn, const char* line) { const char* delim = " "; char* saveptr = NULL; char* token; char* ptr = (char*)line; int c = 0; ssize_t size = 0; mode_t mode = 0; time_t mtime = 0; time_t ctime = 0; time_t atime = 0; char* name = NULL; char* md5 = NULL; while((token = strtok_r(ptr, delim, &saveptr))) { switch(c) { case 0: size = atol(token); break; case 1: md5 = token; break; case 2: mode = str2mode(token); break; case 3: atime = atol(token); break; case 4: ctime = atol(token); break; case 5: mtime = atol(token); break; case 6: name = token; break; } c++; ptr = NULL; } if(c != 7) { conn_printf(cn, "ERROR Protocol violation (%d)\n", __LINE__); conn_abort(cn); return ; } int fd = creat(name, O_CREAT|O_TRUNC); if(fd == -1) { conn_perror(cn, "WARNING creat()"); return; } if(chmod(name,mode)==-1) { perror("WARNING chmod()"); } struct utimbuf t; t.actime = atime; t.modtime = mtime; if(utime(name,&t)==-1) { perror("WARNING utime"); } // CONTENT int bytes_left = size; int r; md5_state_t md5_state; unsigned char md5bin[16]; char md5str[33]; md5_init(&md5_state); while(!cn->abort && bytes_left) { if(cn->rbuf_len == 0) (void)conn_read(cn); r = MIN(bytes_left, cn->rbuf_len); if(r) { write(fd, cn->rbuf, r); md5_append(&md5_state, (unsigned char*)cn->rbuf, r); conn_shift(cn,r); bytes_left -= r; } assert(bytes_left >= 0); } close(fd); md5_finish(&md5_state, (unsigned char*)md5bin); md5bin2str(md5bin, md5str); // Check md5 if(strcmp(md5str,md5)!=0) { // Mismatch! conn_printf(cn, "WARNING %s md5-mismatch (%s <-> %s), removing file\n", name, md5str, md5); if(unlink(name)==-1) { perror("WARNING: unlink()"); } } else { struct utimbuf t; t.actime = atime; t.modtime = mtime; if(utime(name,&t)==-1) { perror("utime"); conn_printf(cn, "WARNING Can't timestamp on directory: %s\n", name); } // md5 is fine conn_printf(cn, "GET %s\n", name); } } static void proto_handle_slnk(conn_t* cn, const char* line) { char curdir[PATH_MAX]; // read next line to get target char target[PATH_MAX]; if(!conn_readline(cn, target, sizeof target)) return; getcwd(curdir, sizeof curdir); // Make sure it dosnt exist unlink(line); if(chdir(my_dirname(line))==-1) { conn_perror(cn, "WARNING chdir()"); return; } if(symlink(target, my_basename(line))==-1) { conn_perror(cn, "ERROR symlink()"); conn_abort(cn); return; } chdir(curdir); conn_printf(cn, "GET %s\n", line); }