int Init_CONNECT(client_t *client, textbuf *buf, CTP_head_t head) { /* get the message body */ CTP_CONNECT_t mesg; int rv = recv_mesg(client->sockfd, &mesg, head); if (rv < 1) return rv; /* check version: only support current version */ if (mesg.version != PROTOCOL_VERSION) { free_mesg(mesg); err_and_close(client, UNSUPPORTED_VERSION); return 0; } free_mesg(mesg); /* transient... */ client->state = Version; /* build ACKCONNECT response */ CTP_ACKCONNECT_t response; response.version = PROTOCOL_VERSION; response.client_id = client->id; response.options = new_options(); /* send response */ rv = send_ACKCONNECT(client->sockfd, response); free_options(response.options); client->state = Connected; return rv; }
bool Program_Options::check_command() { string com_name; pointer<po::options_description> com_desc; for (auto com : *command_container) { com_name = com.first; com_desc = com.second; if (command == com_name) { vector<string> opts = po::collect_unrecognized(parsed->options, po::include_positional); opts.erase(opts.begin()); po::store(po::command_line_parser(opts). options(*com_desc). run(), vm); po::notify(vm); if ( com_name == "new") { new_options(); } else if ( com_name == "build") { build_options(); } return true; } } return false; }
int Connected_OPEN(client_t *client, textbuf *buf, CTP_head_t head) { CTP_OPEN_t mesg; int rv = recv_mesg(client->sockfd, &mesg, head); if (rv < 1) return rv; /* check for correct client id */ if (mesg.client_id != client->id) { free_mesg(mesg); return -1; } /* check file id * this server only supports a "default" file */ if (mesg.file_id != 0) { free_mesg(mesg); send_err(client, BAD_FILE_ID); return 1; } free_mesg(mesg); /* transient... */ client->state = Opening; /* build ACKOPEN response */ CTP_ACKOPEN_t response; response.options = new_options(); /* send response */ rv = send_ACKOPEN(client->sockfd, response); free_options(response.options); client->state = Open; if (rv < 1) return rv; /* send STATUS message to all clients */ CTP_STATUS_t status = get_status(buf); client_t *c; for (c = clients; c <= max_active_client; ++c) { if (c->active) send_STATUS(c->sockfd, status); } free_options(status.options); return 1; }
int Locked_EDIT(client_t *client, textbuf *buf, CTP_head_t head) { CTP_EDIT_t mesg; int rv = recv_mesg(client->sockfd, &mesg, head); if (rv < 1) return rv; /* check for correct client id */ if (mesg.client_id != client->id) { free_mesg(mesg); return -1; } switch (mesg.edit_action) { case INS: rv = tboverwrite(buf, mesg.pos, 0, mesg.data, mesg.datalen); break; case OVR: rv = tboverwrite(buf, mesg.pos, mesg.len, mesg.data, mesg.datalen); break; case DEL: rv = tboverwrite(buf, mesg.pos, mesg.len, NULL, 0); break; } if (rv < 0) { /* reject the edit */ free_mesg(mesg); rv = send_err(client, REJECT_EDIT); } else { /* prepare and send ACKEDIT */ CTP_ACKEDIT_t response; response.options = new_options(); rv = send_ACKEDIT(client->sockfd, response); free_options(response.options); /* relay EDIT to other clients */ client_t *c; for (c = clients; c <= max_active_client; ++c) { if (c != client && c->active) send_EDIT(c->sockfd, mesg); } } free_mesg(mesg); return rv; }
/* response.options MUST be free_options()ed! */ CTP_STATUS_t get_STATUS(textbuf *buf) { client_t *c; char id_buf[sizeof(client->id) + 1] = { 0 }; CTP_STATUS_t response; /* XXX TODO set response.checksum */ response.options = new_options(); /* build list of peers in options */ for (c = clients; c <= max_active_client; ++c) { if (c->active) { memcpy(id_buf, &c->id, sizeof(c->id)); add_option(response.options, "Peer ID", id_buf); /* TODO Peer Nick? */ if (c->state == Locked) add_option(response.options, "Lock ID", id_buf); } } return response; }
int Open_REQLOCK(client_t *client, textbuf *buf, CTP_head_t head) { CTP_OPEN_t mesg; int rv = recv_mesg(client->sockfd, &mesg, head); if (rv < 1) return rv; /* check for correct client id */ if (mesg.client_id != client->id) { free_mesg(mesg); return -1; } /* only one client may lock at a time */ if (locking_client != NULL) { free_mesg(mesg); send_err(client, CANT_LOCK); return 1; } free_mesg(mesg); /* transient... */ client->state = WaitLock; /* build ACKLOCK response */ CTP_ACKLOCK_t response; response.options = new_options(); /* send response */ rv = send_ACKOPEN(client->sockfd, response); free_options(response.options); client->state = Locked; locking_client = client; return rv; }