diff options
author | Nathan Straz <nstraz@redhat.com> | 2013-08-12 13:35:17 -0400 |
---|---|---|
committer | Nathan Straz <nstraz@redhat.com> | 2013-09-11 17:40:06 -0400 |
commit | b7aafc98a56966d4aab712ac0f73df0ae07ca657 (patch) | |
tree | aefa2138f74f4e5cce7f5b6724191b18c52c68d3 | |
parent | 2faad967427b001262712523a7ffbf3e9b28d32a (diff) | |
download | qarsh-b7aafc98a56966d4aab712ac0f73df0ae07ca657.tar.gz qarsh-b7aafc98a56966d4aab712ac0f73df0ae07ca657.tar.xz qarsh-b7aafc98a56966d4aab712ac0f73df0ae07ca657.zip |
Add new data packet type
-rw-r--r-- | qarsh_packet.c | 86 | ||||
-rw-r--r-- | qarsh_packet.h | 13 |
2 files changed, 98 insertions, 1 deletions
diff --git a/qarsh_packet.c b/qarsh_packet.c index 6617362..eb4eac0 100644 --- a/qarsh_packet.c +++ b/qarsh_packet.c @@ -48,6 +48,7 @@ void parse_qp_kill(char *buf, int *buflen, struct qa_packet *qp); void parse_qp_recvfile(char *buf, int *buflen, struct qa_packet *qp); void parse_qp_sendfile(char *buf, int *buflen, struct qa_packet *qp); void parse_qp_rstat(char *buf, int *buflen, struct qa_packet *qp); +void parse_qp_data(char *buf, int *buflen, struct qa_packet *qp); char *store_qp_hello(char *buf, struct qa_packet *qp); char *store_qp_returncode(char *buf, struct qa_packet *qp); @@ -59,6 +60,7 @@ char *store_qp_kill(char *buf, struct qa_packet *qp); char *store_qp_recvfile(char *buf, struct qa_packet *qp); char *store_qp_sendfile(char *buf, struct qa_packet *qp); char *store_qp_rstat(char *buf, struct qa_packet *qp); +char *store_qp_data(char *buf, struct qa_packet *qp); void free_qp_hello(struct qa_packet *qp); void free_qp_returncode(struct qa_packet *qp); @@ -67,6 +69,7 @@ void free_qp_setuser(struct qa_packet *qp); void free_qp_recvfile(struct qa_packet *qp); void free_qp_sendfile(struct qa_packet *qp); void free_qp_rstat(struct qa_packet *qp); +void free_qp_data(struct qa_packet *qp); void dump_qp_ack(struct qa_packet *qp); void dump_qp_runcmd(struct qa_packet *qp); @@ -77,6 +80,7 @@ void dump_qp_kill(struct qa_packet *qp); void dump_qp_recvfile(struct qa_packet *qp); void dump_qp_sendfile(struct qa_packet *qp); void dump_qp_rstat(struct qa_packet *qp); +void dump_qp_data(struct qa_packet *qp); struct packet_internals { @@ -152,6 +156,12 @@ struct packet_internals { .pi_store = store_qp_rstat, .pi_free = free_qp_rstat, .pi_dump = dump_qp_rstat + }, { + .pi_name = "data", + .pi_parse = parse_qp_data, + .pi_store = store_qp_data, + .pi_free = free_qp_data, + .pi_dump = dump_qp_data } }; @@ -232,6 +242,14 @@ fetch_off_t(char *buf, int *buflen, off_t *out) return buf + sizeof i; } +char * +fetch_void(char *buf, int *buflen, int count, void *out) +{ + memcpy(out, buf, count); + *buflen -= count; + return buf+count; +} + void parse_qp_hello(char *buf, int *buflen, struct qa_packet *qp) { @@ -310,6 +328,22 @@ parse_qp_rstat(char *buf, int *buflen, struct qa_packet *qp) buf = fetch_off_t(buf, buflen, &(qp->qp_rstat.qp_st_size)); } +void +parse_qp_data(char *buf, int *buflen, struct qa_packet *qp) +{ + buf = fetch_int(buf, buflen, (int *)&(qp->qp_data.qp_remfd)); + buf = fetch_off_t(buf, buflen, &(qp->qp_data.qp_offset)); + buf = fetch_int(buf, buflen, (int *)&(qp->qp_data.qp_count)); + if (qp->qp_data.qp_count > *buflen) { + fprintf(stderr, "Blob is larger than rest of packet, %d > %d\n", + qp->qp_data.qp_count, *buflen); + free(qp); + } else { + qp->qp_data.qp_blob = malloc(qp->qp_data.qp_count); + qp->qp_data.free_blob = 1; + buf = fetch_void(buf, buflen, qp->qp_data.qp_count, qp->qp_data.qp_blob); + } +} struct qa_packet * parse_packet(char *buf, int buflen) @@ -363,6 +397,15 @@ store_off_t(char *buf, off_t o) return buf + sizeof o; } +static char * +store_void(char *buf, int count, void *d) +{ + char *cp; + cp = store_int(buf, count); + memcpy(cp, d, count); + return cp+count; +} + char * store_qp_hello(char *buf, struct qa_packet *qp) { @@ -449,6 +492,15 @@ store_qp_rstat(char *buf, struct qa_packet *qp) return buf; } +char * +store_qp_data(char *buf, struct qa_packet *qp) +{ + buf = store_int(buf, qp->qp_data.qp_remfd); + buf = store_off_t(buf, qp->qp_data.qp_offset); + buf = store_void(buf, qp->qp_data.qp_count, qp->qp_data.qp_blob); + return buf; +} + int qptostr(struct qa_packet *qp, char *qpstr, int maxsize) { @@ -628,6 +680,27 @@ make_qp_rstat(const char *path, const struct stat *sb) return qp; } +struct qa_packet * +make_qp_data(const int remfd, const off_t offset, const int count, void *blob) +{ + struct qa_packet *qp; + qp = malloc(sizeof *qp); + assert(qp); + memset(qp, 0, sizeof *qp); + + qp->qp_type = QP_DATA; + qp->qp_data.qp_remfd = remfd; + qp->qp_data.qp_offset = offset; + qp->qp_data.qp_count = count; + /* data packets are different, the blob is just a pointer which + * must stick around until after the packet is sent. This is to + * avoid multiple data copies */ + qp->qp_data.free_blob = 0; + qp->qp_data.qp_blob = blob; + + return qp; +} + /* * Packet deallocation functions */ @@ -674,6 +747,11 @@ free_qp_rstat(struct qa_packet *qp) condfree(qp->qp_rstat.qp_path); } +void +free_qp_data(struct qa_packet *qp) +{ + if (qp->qp_data.free_blob) free(qp->qp_data.qp_blob); +} void qpfree(struct qa_packet *qp) @@ -762,6 +840,14 @@ dump_qp_rstat(struct qa_packet *qp) } void +dump_qp_data(struct qa_packet *qp) +{ + fprintf(stderr, "\tremfd: %d\n", qp->qp_data.qp_remfd); + fprintf(stderr, "\toffset: %lld\n", (long long int)qp->qp_data.qp_offset); + fprintf(stderr, "\tcount: %d\n", qp->qp_data.qp_count); +} + +void dump_qp(struct qa_packet *qp) { fprintf(stderr, "%s #%d\n", QP_NAME(qp->qp_type), qp->qp_seq); diff --git a/qarsh_packet.h b/qarsh_packet.h index ec391c3..42f4b61 100644 --- a/qarsh_packet.h +++ b/qarsh_packet.h @@ -36,7 +36,8 @@ enum qa_packet_type { QP_KILL = 7, QP_RECVFILE = 8, QP_SENDFILE = 9, - QP_RSTAT = 10 + QP_RSTAT = 10, + QP_DATA = 11 }; struct qp_hello_pkt { @@ -96,6 +97,13 @@ struct qp_rstat_pkt { off_t qp_st_size; }; +struct qp_data_pkt { + int qp_remfd; /* remote fd to write to */ + off_t qp_offset; /* offset in file for this data */ + int qp_count; /* length of data buffer */ + int free_blob; /* Whether qpfree should free the blob */ + void *qp_blob; +}; #define QP_VERSION 1 @@ -113,6 +121,7 @@ struct qa_packet { struct qp_recvfile_pkt recvfile; struct qp_sendfile_pkt sendfile; struct qp_rstat_pkt rstat; + struct qp_data_pkt data; } qp_u; }; @@ -126,6 +135,7 @@ struct qa_packet { #define qp_recvfile qp_u.recvfile #define qp_sendfile qp_u.sendfile #define qp_rstat qp_u.rstat +#define qp_data qp_u.data /* Prototypes */ char *qp_packet_type(enum qa_packet_type t); @@ -140,6 +150,7 @@ struct qa_packet *make_qp_kill(int sig); struct qa_packet *make_qp_recvfile(const char *path, int if_port, off_t count, mode_t mode); struct qa_packet *make_qp_sendfile(const char *path, int of_port); struct qa_packet *make_qp_rstat(const char *path, const struct stat *sb); +struct qa_packet *make_qp_data(const int remfd, const off_t offset, const int count, void *blob); int qptostr(struct qa_packet *qp, char *qpstr, int maxsize); void qpfree(struct qa_packet *qp); void dump_qp(struct qa_packet *qp); |