int load_arg(struct katcl_line *l, char *arg, int fmt, int flags) { unsigned char *tmp; int len, i, j, v, result; switch(fmt){ case FMT_BIN : case FMT_TEXT : return append_string_katcl(l, flags, arg); case FMT_AUTO : case FMT_HEX : if(strncmp(arg, "0x", 2)){ return append_string_katcl(l, flags, arg); } else { len = strlen(arg + 2); if(len % 2){ fprintf(stderr, "warning: argument %s contains an odd number of hex characters, ignoring the trailing one\n", arg); len--; } len = len / 2; if(len == 0){ /* NULL parameters are really bad form */ return append_buffer_katcl(l, flags, NULL, 0); } tmp = malloc(len); if(tmp == NULL){ fprintf(stderr, "warning: argument %s contains an odd number of hex characters, ignoring the trailing one\n", arg); return -1; } j = 2; for(i = 0; i < len; i++){ v = h2n(arg[j++]); if(v < 0){ free(tmp); return -1; } tmp[i] = 0xf0 & (v << 4); v = h2n(arg[j++]); if(v < 0){ free(tmp); return -1; } tmp[i] |= 0x0f & v; } result = append_buffer_katcl(l, flags, tmp, len); free(tmp); return result; } break; default : fprintf(stderr, "error: unhandled format %d\n", fmt); return -1; } }
int write_word_wops(struct wops_state *w, char *name, uint32_t value) { int result[4], status, i; int expect[4] = { 7, 0, 2, 5 }; char *ptr; uint32_t tmp; if(maintain_wops(w) < 0){ return -1; } tmp = htonl(value); result[0] = append_string_katcl(w->w_line, KATCP_FLAG_FIRST | KATCP_FLAG_STRING, "?write"); result[1] = append_string_katcl(w->w_line, KATCP_FLAG_STRING, name); result[2] = append_unsigned_long_katcl(w->w_line, KATCP_FLAG_ULONG, 0); result[3] = append_buffer_katcl(w->w_line, KATCP_FLAG_LAST | KATCP_FLAG_BUFFER, &tmp, 4); expect[1] = strlen(name) + 1; for(i = 0; i < 4; i++){ if(result[i] != expect[i]){ #ifdef DEBUG fprintf(stderr, "write: result[%d]=%d != %d\n", i, result[i], expect[i]); #endif return -1; } } while((status = complete_rpc_katcl(w->w_line, 0, &(w->w_when))) == 0); if(status < 0){ if(w->w_line){ destroy_rpc_katcl(w->w_line); w->w_line = NULL; } #ifdef DEBUG fprintf(stderr, "write: complete call failed\n"); #endif return -1; } ptr = arg_string_katcl(w->w_line, 1); if(ptr == NULL){ #ifdef DEBUG fprintf(stderr, "write: unable to acquire first parameter\n"); #endif return -1; } if(strcmp(ptr, KATCP_OK)){ #ifdef DEBUG fprintf(stderr, "write: problematic return code %s\n", ptr); #endif return 1; } return 0; }
int vsend_katcl(struct katcl_line *l, va_list args) { int flags, result, check; char *string; void *buffer; unsigned long value; int len; #ifdef KATCP_USE_FLOATS double dvalue; #endif check = KATCP_FLAG_FIRST; do{ flags = va_arg(args, int); if((check & flags) != check){ /* WARNING: tests first arg for FLAG_FIRST */ #ifdef DEBUG fprintf(stderr, "vsend: flag check failed 0x%x\n", flags); #endif return -1; } check = 0; switch(flags & KATCP_TYPE_FLAGS){ case KATCP_FLAG_STRING : string = va_arg(args, char *); result = append_string_katcl(l, flags & KATCP_ORDER_FLAGS, string); break; case KATCP_FLAG_SLONG : value = va_arg(args, unsigned long); result = append_signed_long_katcl(l, flags & KATCP_ORDER_FLAGS, value); break; case KATCP_FLAG_ULONG : value = va_arg(args, unsigned long); result = append_unsigned_long_katcl(l, flags & KATCP_ORDER_FLAGS, value); break; case KATCP_FLAG_XLONG : value = va_arg(args, unsigned long); result = append_hex_long_katcl(l, flags & KATCP_ORDER_FLAGS, value); break; case KATCP_FLAG_BUFFER : buffer = va_arg(args, void *); len = va_arg(args, int); result = append_buffer_katcl(l, flags & KATCP_ORDER_FLAGS, buffer, len); break; #ifdef KATCP_USE_FLOATS case KATCP_FLAG_DOUBLE : dvalue = va_arg(args, double); result = append_double_katcl(l, flags & KATCP_ORDER_FLAGS, dvalue); break; #endif default : #ifdef DEBUG fprintf(stderr, "vsend: bad type flag 0x%x\n", flags); #endif result = (-1); break; } #if DEBUG > 1 fprintf(stderr, "vsend: appended: flags=0x%02x, result=%d\n", flags, result); #endif if(result <= 0){ #ifdef DEBUG fprintf(stderr, "vsend: bad result for type 0x%x\n", flags); #endif return -1; } } while(!(flags & KATCP_FLAG_LAST)); return 0; }