static int do_method(void) { struct timeval tv; char *command; if(slist_count(commands) == 0) return 0; gettimeofday_wrap(&tv); command = slist_head_pop(commands); write_wrap(scamper_fd, command, NULL, strlen(command)); more--; if((options & OPT_DEBUG) != 0) fprintf(stderr, "%ld: %s", (long int)tv.tv_sec, command); if(lastcommand != NULL) free(lastcommand); lastcommand = command; if(slist_count(commands) == 0 && stdin_fd == -1 && done == 0) { write_wrap(scamper_fd, "done\n", NULL, 5); done = 1; } return 0; }
/****************************************************************************** * mailbox_deliver * Deliver a message to the mailbox. * There is a lot of arithmetic here because the compiler and * assembler refuse to align mailbox buffers to arbitrary powers * of two (which would allow a simple and neat mask-based wrap). * On the plus side, this way there is no alignment or size * restriction on the mailbox buffer. *******************************************************************************/ u8 mailbox_deliver(mailbox_t *box, u8 code, u8 payload_length, u8 *payload) { u8 len, flags, freespace; if (payload_length) { len = payload_length + 2; code |= 0x80; } else { len = 1; code &= ~0x80; } flags = disable_interrupts(); if (box->tail >= box->head) { freespace = box->size - (box->tail - box->head); } else { freespace = box->head - box->tail; } /* If we write 1 into the last byte and increment tail, * then head will equal tail but the mailbox is actually * full, not empty. Don't do this. */ /* check for space. */ if (freespace < len )//|| freespace == 1) { restore_flags(flags); DEBUG("mailbox_deliver: out of room"); return 1; /* no room */ } write_wrap(box, code); if (payload_length) { u8 i; write_wrap(box, payload_length); for(i=0; i<payload_length; i++) { write_wrap(box, payload[i]); } } restore_flags(flags); return 0; }
int scamper_file_text_sting_write(const scamper_file_t *sf, const scamper_sting_t *sting) { int fd = scamper_file_getfd(sf); char buf[192], src[64], dst[64]; size_t len; uint32_t i, txc = 0; snprintf(buf, sizeof(buf), "sting from %s:%d to %s:%d, %d probes, %dms mean\n" " data-ack count %d, holec %d\n", scamper_addr_tostr(sting->src, src, sizeof(src)), sting->sport, scamper_addr_tostr(sting->dst, dst, sizeof(dst)), sting->dport, sting->count, sting->mean, sting->dataackc, sting->holec); len = strlen(buf); write_wrap(fd, buf, NULL, len); if(sting->holec > 0) { for(i=0; i<sting->pktc; i++) { if((sting->pkts[i]->flags & SCAMPER_STING_PKT_FLAG_DATA) == 0) continue; txc++; if(sting->pkts[i]->flags & SCAMPER_STING_PKT_FLAG_HOLE) { snprintf(buf, sizeof(buf), " probe %d hole\n", txc); len = strlen(buf); write_wrap(fd, buf, NULL, len); } } } return 0; }
static int do_attach(void) { char buf[256]; size_t off = 0; string_concat(buf, sizeof(buf), &off, "attach"); if((options & OPT_PRIORITY) != 0) string_concat(buf, sizeof(buf), &off, " priority %d", priority); string_concat(buf, sizeof(buf), &off, "\n"); if(write_wrap(scamper_fd, buf, NULL, off) != 0) { fprintf(stderr, "could not attach to scamper process\n"); return -1; } return 0; }
int scamper_file_text_ping_write(const scamper_file_t *sf, const scamper_ping_t *ping) { scamper_ping_reply_t *reply; int fd = scamper_file_getfd(sf); off_t off = 0; uint32_t reply_count = scamper_ping_reply_count(ping); char *header = NULL; size_t header_len = 0; char **replies = NULL; size_t *reply_lens = NULL; char *stats = NULL; size_t stats_len = 0; char *str = NULL; size_t len = 0; size_t wc = 0; int ret = -1; uint32_t i,j; /* get current position incase trunction is required */ if(fd != 1 && (off = lseek(fd, 0, SEEK_CUR)) == -1) return -1; /* get the header string */ if((header = ping_header(ping)) == NULL) goto cleanup; len = (header_len = strlen(header)); /* put together a string for each reply */ if(reply_count > 0) { if((replies = malloc_zero(sizeof(char *) * reply_count)) == NULL || (reply_lens = malloc_zero(sizeof(size_t) * reply_count)) == NULL) goto cleanup; for(i=0, j=0; i<ping->ping_sent; i++) { reply = ping->ping_replies[i]; while(reply != NULL) { /* build string representation of this reply */ if((replies[j] = ping_reply(ping, reply)) == NULL) { goto cleanup; } len += (reply_lens[j] = strlen(replies[j])); reply = reply->next; j++; } } } /* put together the summary stats */ stats = ping_stats(ping); if(stats != NULL) len += (stats_len = strlen(stats)); /* allocate a string long enough to combine the above strings */ if((str = malloc(len)) == NULL) goto cleanup; /* combine the strings created above */ memcpy(str+wc, header, header_len); wc += header_len; for(i=0; i<reply_count; i++) { memcpy(str+wc, replies[i], reply_lens[i]); wc += reply_lens[i]; } if(stats != NULL) { memcpy(str+wc, stats, stats_len); wc += stats_len; } /* * try and write the string to disk. if it fails, then truncate the * write and fail */ if(write_wrap(fd, str, &wc, len) != 0) { if(fd != 1) { if(ftruncate(fd, off) != 0) goto cleanup; } goto cleanup; } ret = 0; /* we succeeded */ cleanup: if(str != NULL) free(str); if(header != NULL) free(header); if(stats != NULL) free(stats); if(reply_lens != NULL) free(reply_lens); if(replies != NULL) { for(i=0; i<reply_count; i++) if(replies[i] != NULL) free(replies[i]); free(replies); } return ret; }
/* * do_scamperread * * the fd for the scamper process is marked as readable, so do a read * on it. */ static int do_scamperread(void) { ssize_t rc; uint8_t uu[64]; char *ptr, *head; char buf[512]; void *tmp; long l; size_t i, uus, linelen; if((rc = read(scamper_fd, buf, sizeof(buf))) > 0) { if(readbuf_len == 0) { if((readbuf = memdup(buf, rc)) == NULL) { return -1; } readbuf_len = rc; } else { if((tmp = realloc(readbuf, readbuf_len + rc)) != NULL) { readbuf = tmp; memcpy(readbuf+readbuf_len, buf, rc); readbuf_len += rc; } else return -1; } } else if(rc == 0) { close(scamper_fd); scamper_fd = -1; } else if(errno == EINTR || errno == EAGAIN) { return 0; } else { fprintf(stderr, "could not read: errno %d\n", errno); return -1; } /* process whatever is in the readbuf */ if(readbuf_len == 0) { goto done; } head = readbuf; for(i=0; i<readbuf_len; i++) { if(readbuf[i] != '\n') continue; /* skip empty lines */ if(head == &readbuf[i]) { head = &readbuf[i+1]; continue; } /* calculate the length of the line, excluding newline */ linelen = &readbuf[i] - head; /* if currently decoding data, then pass it to uudecode */ if(data_left > 0) { uus = sizeof(uu); if(uudecode_line(head, linelen, uu, &uus) != 0) { fprintf(stderr, "could not uudecode_line\n"); goto err; } if(uus != 0) { if(outfile_fd != -1) write_wrap(outfile_fd, uu, NULL, uus); if(options & OPT_STDOUT) write_wrap(STDOUT_FILENO, uu, NULL, uus); } data_left -= (linelen + 1); } /* if the scamper process is asking for more tasks, give it more */ else if(linelen == 4 && strncasecmp(head, "MORE", linelen) == 0) { more++; } /* new piece of data */ else if(linelen > 5 && strncasecmp(head, "DATA ", 5) == 0) { l = strtol(head+5, &ptr, 10); if(*ptr != '\n' || l < 1) { head[linelen] = '\0'; fprintf(stderr, "could not parse %s\n", head); goto err; } data_left = l; } /* feedback letting us know that the command was accepted */ else if(linelen >= 2 && strncasecmp(head, "OK", 2) == 0) { /* err, nothing to do */ } /* feedback letting us know that the command was not accepted */ else if(linelen >= 3 && strncasecmp(head, "ERR", 3) == 0) { if(lastcommand != NULL) { fprintf(stderr, "command not accepted: %s", lastcommand); more++; } else { goto err; } } else { head[linelen] = '\0'; fprintf(stderr, "unknown response '%s'\n", head); goto err; } head = &readbuf[i+1]; } if(head != &readbuf[readbuf_len]) { readbuf_len = &readbuf[readbuf_len] - head; ptr = memdup(head, readbuf_len); free(readbuf); readbuf = ptr; } else { readbuf_len = 0; free(readbuf); readbuf = NULL; } done: return 0; err: return -1; }
static int do_stdinread(void) { ssize_t rc; char *ptr, *head, *command; char buf[512]; void *tmp; size_t i, linelen; if((rc = read(stdin_fd, buf, sizeof(buf))) > 0) { if(stdinbuf_len == 0) { if((stdinbuf = memdup(buf, rc)) == NULL) { return -1; } stdinbuf_len = rc; } else { if((tmp = realloc(stdinbuf, stdinbuf_len + rc)) != NULL) { stdinbuf = tmp; memcpy(stdinbuf+stdinbuf_len, buf, rc); stdinbuf_len += rc; } else return -1; } } else if(rc == 0) { if(done == 0) write_wrap(scamper_fd, "done\n", NULL, 5); done = 1; stdin_fd = -1; return 0; } else if(errno == EINTR || errno == EAGAIN) { return 0; } else { fprintf(stderr, "could not read: errno %d\n", errno); return -1; } /* process whatever is in the stdinbuf */ if(stdinbuf_len == 0) { goto done; } head = stdinbuf; for(i=0; i<stdinbuf_len; i++) { if(stdinbuf[i] != '\n') continue; /* calculate the length of the line, including newline */ linelen = &stdinbuf[i] - head + 1; /* skip empty lines */ if(linelen == 1 || head[0] == '#') { head = &stdinbuf[i+1]; continue; } /* make a copy of the command string */ if((command = malloc(linelen+1)) == NULL) { fprintf(stderr, "could not malloc command\n"); goto err; } memcpy(command, head, linelen); command[linelen] = '\0'; /* put the command string on the list of things to do */ if(slist_tail_push(commands, command) == NULL) { fprintf(stderr, "could not push command onto list\n"); free(command); goto err; } head = &stdinbuf[i+1]; } if(head != &stdinbuf[stdinbuf_len]) { stdinbuf_len = &stdinbuf[stdinbuf_len] - head; ptr = memdup(head, stdinbuf_len); free(stdinbuf); stdinbuf = ptr; } else { stdinbuf_len = 0; free(stdinbuf); stdinbuf = NULL; } done: return 0; err: return -1; }
int scamper_file_csv_trace_write(const scamper_file_t *sf, const scamper_trace_t *trace) { scamper_trace_hop_t *hop; int fd = scamper_file_getfd(sf); size_t wc, len, off = 0; off_t foff = 0; char *str = NULL, *header = NULL, **hops = NULL; int i, j, hopc = 0, rc = -1; if(fd != STDOUT_FILENO && (foff = lseek(fd, 0, SEEK_CUR)) == -1) return -1; if((header = header_tostr()) == NULL) goto cleanup; len = strlen(header); for(i=trace->firsthop-1; i<trace->hop_count; i++) for(hop = trace->hops[i]; hop != NULL; hop = hop->hop_next) hopc++; if(hopc > 0) { if((hops = malloc_zero(sizeof(char *) * hopc)) == NULL) goto cleanup; for(i=trace->firsthop-1, j=0; i<trace->hop_count; i++) { for(hop = trace->hops[i]; hop != NULL; hop = hop->hop_next) { if((hops[j] = hop_tostr(trace, hop)) == NULL) goto cleanup; len += strlen(hops[j]); j++; } } } len += 1; /* \0 */ if((str = malloc(len)) == NULL) goto cleanup; string_concat(str, len, &off, "%s", header); if(hopc > 0) { for(j=0; j<hopc; j++) string_concat(str, len, &off, "%s", hops[j]); } assert(off+1 == len); if(write_wrap(fd, str, &wc, off) != 0) { if(fd != STDOUT_FILENO) { if(ftruncate(fd, foff) != 0) goto cleanup; } goto cleanup; } rc = 0; /* we succeeded */ cleanup: if(hops != NULL) { for(i=0; i<hopc; i++) if(hops[i] != NULL) free(hops[i]); free(hops); } if(header != NULL) free(header); if(str != NULL) free(str); return rc; }