Beispiel #1
0
int process_answer(char *dns_response, int offset) {
   unsigned char data[200];

   int numBytes = 2; // skip initial 2 bytes

   int type = get_short(dns_response, offset + numBytes);
   numBytes += 2;    // count the type
   numBytes += 2;    // skip the address class (should be 0x0001, IPv4)
   numBytes += 4;    // skip the TTL (recommended cache time)

   int data_length1 = get_short(dns_response, offset + numBytes);
   numBytes += 2;

   if (type == 1) {
      // this is a normal query response (i.e. name -> address)
      get_ip_address(dns_response, offset + numBytes, data);
      numBytes += 4;
      printf("Response:  %u.%u.%u.%u\n", data[0],data[1],data[2],data[3]);
   } else if (type == 5) {
      // this is a CNAME query response (i.e. an alias)
      int data_length = get_domain_name(dns_response, offset + numBytes, data);
      numBytes += data_length;
      printf("Alias:  %s\n", data);
   }

   return numBytes;
}
Beispiel #2
0
int IP_header::decode(unsigned char * data,int itype, int i_id)
{
    reset();
    ethertype = itype;
    id        = i_id;
    int len=0;
    // ether frame done (ignored mac's)
    // ip

    int version = data[0] >> 4;
    proto=0;
    if (version==4)
    {
        if (ethertype==0)
            ethertype=0x800;
        int header_len = (data[0]&0xf)*4;
        proto = data[9];
        src_ip.__in6_u.__u6_addr32[3] = get_int(&data[12]);
        dst_ip.__in6_u.__u6_addr32[3] = get_int(&data[16]);
        int totallen    = get_short(&data[2]);
        length          = totallen-header_len;    
        int flags       = get_short(&data[6]);
        offset          = (flags & 0x1fff)<<3;
        flags >>= 13;
        if (flags&1)
            fragments = 1;
        data += header_len;
        len  += header_len;
    }
    else if (version==6)
static void handle_query_response(DNSServiceRef sdr, ipc_msg_hdr *hdr, char *data)
    {
    DNSServiceFlags flags;
    uint32_t interfaceIndex, ttl;
    DNSServiceErrorType errorCode;
    char name[kDNSServiceMaxDomainName];
    uint16_t rrtype, rrclass, rdlen;
    char *rdata;
    int str_error = 0;
    (void)hdr;//Unused

    flags = get_flags(&data);
    interfaceIndex = get_long(&data);
    errorCode = get_error_code(&data);
    if (get_string(&data, name, kDNSServiceMaxDomainName) < 0) str_error = 1;
    rrtype = get_short(&data);
    rrclass = get_short(&data);
    rdlen = get_short(&data);
    rdata = get_rdata(&data, rdlen);
	ttl = get_long(&data);

	if (!errorCode && str_error) errorCode = kDNSServiceErr_Unknown;
	((DNSServiceQueryRecordReply)sdr->app_callback)(sdr, flags, interfaceIndex, errorCode, name, rrtype, rrclass,
													rdlen, rdata, ttl, sdr->app_context);
    return;
    }
Beispiel #4
0
uint_t
get_int(fcode_env_t *env)
{
	uint_t u;

	/*
	 * Logical or DOES NOT guarantee left to right evaluation...
	 */
	u = get_short(env) << 16;
	return (u | get_short(env));
}
Beispiel #5
0
static int create_videobuf_handler(unsigned char major, unsigned char minor, unsigned char *data, int len, void *context)
{
	short w, h,
#ifdef DEBUG
		count, 
#endif
		truecolor;

	if (videobuf_created)
		return 1;
	else
		videobuf_created = 1;

	w = get_short(data);
	h = get_short(data+2);

#ifdef DEBUG
	if (minor > 0) {
		count = get_short(data+4);
	} else {
		count = 1;
	}
#endif

	if (minor > 1) {
		truecolor = get_short(data+6);
	} else {
		truecolor = 0;
	}

	g_width = w << 3;
	g_height = h << 3;

	/* TODO: * 4 causes crashes on some files */
	/* only malloc once */
	if (g_vBuffers == NULL)
		g_vBackBuf1 = g_vBuffers = mve_alloc(g_width * g_height * 8);
	if (truecolor) {
		g_vBackBuf2 = (unsigned short *)g_vBackBuf1 + (g_width * g_height);
	} else {
		g_vBackBuf2 = (unsigned char *)g_vBackBuf1 + (g_width * g_height);
	}

	memset(g_vBackBuf1, 0, g_width * g_height * 4);

#ifdef DEBUG
	con_printf(CON_CRITICAL, "DEBUG: w,h=%d,%d count=%d, tc=%d\n", w, h, count, truecolor);
#endif

	g_truecolor = truecolor;

	return 1;
}
Beispiel #6
0
static int video_palette_handler(unsigned char major, unsigned char minor, unsigned char *data, int len, void *context)
{
	short start, count;
	unsigned char *p;

	start = get_short(data);
	count = get_short(data+2);

	p = data + 4;

	mve_setpalette(p - 3*start, start, count);

	return 1;
}
Beispiel #7
0
void
bendof(fcode_env_t *env)
{
	short offset = get_short(env);
	branch_common(env, offset, 0, 1);
	bresolve(env);
}
Beispiel #8
0
void QOption::setName(const QString &name)
{
	int comma = name.indexOf(',');
	if (comma>0) {
        QString name1 = name.left(comma);
        QString name2 = name.mid(comma+1);
        if (name1.startsWith("--")) {
            mLongName = name1.mid(2);
            mShortName = get_short(name2);
        } else if (name1.startsWith("-")) {
            mShortName = name1.mid(1);
            mLongName = get_long(name2);
        } else {
            if (name2.startsWith("--")) {
                mLongName = name2.mid(2);
                mShortName = name1;
            } else if (name2.startsWith("-")) {
                mShortName = name2.mid(1);
                mLongName = name1;
            } else {
                mShortName = name2;
                mLongName = name1;
            }
        }
	} else {
        if (name.startsWith("--"))
            mLongName = name.mid(2);
        else if (name.startsWith("-"))
            mShortName = name.mid(1);
        else
            mShortName = name;
	}
}
Beispiel #9
0
/***********************************************************************
 *
 * Function:    unpack_MailSyncPref
 *
 * Summary:     unpacks Mail
 *
 * Parameters:  MailSyncPref_t*, char* to buffer, buffer length
 *
 * Returns:     effective buffer length
 *
 ***********************************************************************/
int
unpack_MailSyncPref(MailSyncPref_t *pref, unsigned char *record, size_t len)
{
	unsigned char *start = record;

	pref->syncType = get_byte(record);
	record += 1;
	pref->getHigh = get_byte(record);
	record += 1;
	pref->getContaining = get_byte(record);
	record += 2;
	pref->truncate = get_short(record);
	record += 2;

	if (get_byte(record)) {
		pref->filterTo = strdup((char *)record);
		record += strlen((char *)record);
	} else
		pref->filterTo = 0;
	record++;
	if (get_byte(record)) {
		pref->filterFrom = strdup((char *)record);
		record += strlen((char *)record);
	} else
		pref->filterFrom = 0;
	record++;
	if (get_byte(record)) {
		pref->filterSubject = strdup((char *)record);
		record += strlen((char *)record);
	} else
		pref->filterSubject = 0;
	record++;

	return (record - start);
}
Beispiel #10
0
/***********************************************************************
 *
 * Function:    unpack_MailAppInfo
 *
 * Summary:     unpacks MailAppInfo
 *
 * Parameters:  MailAppInfo_t*, char* to buffer, buffer length
 *
 * Returns:     effective buffer length
 *
 ***********************************************************************/
int
unpack_MailAppInfo(MailAppInfo_t *appinfo, unsigned char *record, size_t len)
{
	int 	i;
	unsigned char *start = record;

	i = unpack_CategoryAppInfo(&appinfo->category, record, len);
	if (!i)
		return i;
	record += i;
	len -= i;
	if (len < 11)
		return 0;
	appinfo->dirty = get_short(record);
	record += 2;
	appinfo->sortOrder = get_byte(record);
	record += 2;
	appinfo->unsentMessage = get_long(record);
	record += 4;

/* ai->signature = 0; 			*/
/* strdup(start + get_short(record)); 	*/
	record += 3;

	return (record - start);
}
Beispiel #11
0
static int create_timer_handler(unsigned char major, unsigned char minor, unsigned char *data, int len, void *context)
{

#if !defined(_WIN32) && !defined(macintosh) // FIXME
	__extension__ long long temp;
#else
	long temp;
#endif

	if (timer_created)
		return 1;
	else
		timer_created = 1;

	micro_frame_delay = get_int(data) * (int)get_short(data+4);
	if (g_spdFactorNum != 0)
	{
		temp = micro_frame_delay;
		temp *= g_spdFactorNum;
		temp /= g_spdFactorDenom;
		micro_frame_delay = (int)temp;
	}

	return 1;
}
Beispiel #12
0
void
bqbranch(fcode_env_t *env)
{
	short offset = (short)get_short(env);

	branch_common(env, offset, 1, 0);
}
static void handle_resolve_response(DNSServiceRef sdr, ipc_msg_hdr *hdr, char *data)
    {
    DNSServiceFlags flags;
    char fullname[kDNSServiceMaxDomainName];
    char target[kDNSServiceMaxDomainName];
    uint16_t txtlen;
    union { uint16_t s; u_char b[2]; } port;
    uint32_t ifi;
    DNSServiceErrorType err;
    unsigned char *txtrecord;
    int str_error = 0;
    (void)hdr; 		//unused

    flags = get_flags(&data);
    ifi = get_long(&data);
    err = get_error_code(&data);
    if (get_string(&data, fullname, kDNSServiceMaxDomainName) < 0) str_error = 1;
    if (get_string(&data, target, kDNSServiceMaxDomainName) < 0) str_error = 1;
    port.b[0] = *data++;
    port.b[1] = *data++;
    txtlen = get_short(&data);
    txtrecord = (unsigned char *)get_rdata(&data, txtlen);

	if (!err && str_error) err = kDNSServiceErr_Unknown;
    ((DNSServiceResolveReply)sdr->app_callback)(sdr, flags, ifi, err, fullname, target, port.s, txtlen, txtrecord, sdr->app_context);
    }
Beispiel #14
0
static int init_video_handler(unsigned char major, unsigned char minor, unsigned char *data, int len, void *context)
{
	short width, height;

	if (video_initialized)
		return 1; /* maybe we actually need to change width/height here? */
	else
		video_initialized = 1;

	width = get_short(data);
	height = get_short(data+2);
	g_screenWidth = width;
	g_screenHeight = height;

	return 1;
}
Beispiel #15
0
static Xauth *
read_numeric(FILE *fp)
{
    Xauth *auth;

    auth = (Xauth *) malloc (sizeof (Xauth));
    if (!auth) goto bad;
    auth->family = 0;
    auth->address = NULL;
    auth->address_length = 0;
    auth->number = NULL;
    auth->number_length = 0;
    auth->name = NULL;
    auth->name_length = 0;
    auth->data = NULL;
    auth->data_length = 0;

    if (!get_short (fp, (unsigned short *) &auth->family))
      goto bad;
    if (!get_short (fp, (unsigned short *) &auth->address_length))
      goto bad;
    if (!get_bytes (fp, (unsigned int) auth->address_length, &auth->address))
      goto bad;
    if (!get_short (fp, (unsigned short *) &auth->number_length))
      goto bad;
    if (!get_bytes (fp, (unsigned int) auth->number_length, &auth->number))
      goto bad;
    if (!get_short (fp, (unsigned short *) &auth->name_length))
      goto bad;
    if (!get_bytes (fp, (unsigned int) auth->name_length, &auth->name))
      goto bad;
    if (!get_short (fp, (unsigned short *) &auth->data_length))
      goto bad;
    if (!get_bytes (fp, (unsigned int) auth->data_length, &auth->data))
      goto bad;
    
    switch (getinput (fp)) {		/* get end of line */
      case EOF:
      case '\n':
	return auth;
    }

  bad:
    if (auth) XauDisposeAuth (auth);	/* won't free null pointers */
    return NULL;
}
Beispiel #16
0
void process_dns_response(char *dns_response) {
   int num_answers = get_short(dns_response, 6);
   int num_authoritative = get_short(dns_response, 8);
   int num_additional = get_short(dns_response, 10);

   // skip to the answer section
   //  Note: This is a hack, since the we just happen to know the length of the query
   //        section.  Normally, you'd have to parse the question again and go from
   //        there.
   int offset = 31; // location of the first answer

   // process each answer that is returned
   int ans;
   for (ans = 0; ans < num_answers; ans++) {
      offset += process_answer(dns_response, offset);
   }

   // we'll ignore the authoritative name servers and additional sections
}
Beispiel #17
0
static int slp_field(char *tag, int type) {
	int length;

	get_short();
	if (netval < 0) {
	    return (-1);
	}
	length = netval;

	/* special case for NA field in SrvTypeRqst */
	if (type == FIELD_TYPENA && length == 0xffff) {
	    sprintf(get_line(0, 0), "%s: length = -1: Use all NAs", tag);
	    return (0);
	}

	sprintf(get_line(0, 0), "%s: length = %d", tag, length);
	if (length > msglength) {
	    /* framing error: message is not long enough to contain data */
	    sprintf(get_line(0, 0),
		    "  [Framing error: remaining pkt length = %u]",
		    msglength);
	    return (-1);
	}

	if (length > 0) {
	    char *buf = malloc(length + 1);
	    if (buf != NULL) {
		if (v1_charset) {
		    if (!make_utf8(buf, length, p, length)) {
			strcpy(buf, "[Invalid Character Encoding]");
		    }
		} else {
		    memcpy(buf, p, length);
		    buf[length] = '\0';		/* ensure null-terminated */
		}

		switch (type) {
		    case FIELD_PREVRESP:
			slp_prevresp(buf);
			break;

		    default:
			sprintf(get_line(0, 0), "  \"%s\"", buf);
			break;
		}
		free(buf);
	    }

	    p += length;
	    msglength -= length;
	}

	/* return ok */
	return (0);
}
Beispiel #18
0
Ptr
CDR::get_bytes (Short& len)
{
  Ptr ptr; 
  len = get_short ();
  ptr = next;
  next += len;
  remaining -= len;
  len--;
  return ptr;
}
Beispiel #19
0
String
CDR::get_string (Short& len)
{
  String str;
  len = get_short ();
  str = next;
  next += len;
  remaining -= len;
  len--; // don't count null terminator
  return str;
}
Beispiel #20
0
static int video_data_handler(unsigned char major, unsigned char minor, unsigned char *data, int len, void *context)
{
	short nFrameHot, nFrameCold;
	short nXoffset, nYoffset;
	short nXsize, nYsize;
	unsigned short nFlags;
	unsigned char *temp;

	nFrameHot  = get_short(data);
	nFrameCold = get_short(data+2);
	nXoffset   = get_short(data+4);
	nYoffset   = get_short(data+6);
	nXsize     = get_short(data+8);
	nYsize     = get_short(data+10);
	nFlags     = get_ushort(data+12);

	if (nFlags & 1)
	{
		temp = (unsigned char *)g_vBackBuf1;
		g_vBackBuf1 = g_vBackBuf2;
		g_vBackBuf2 = temp;
	}

	/* convert the frame */
	if (g_truecolor) {
		decodeFrame16((unsigned char *)g_vBackBuf1, g_pCurMap, g_nMapLength, data+14, len-14);
	} else {
		decodeFrame8(g_vBackBuf1, g_pCurMap, g_nMapLength, data+14, len-14);
	}

	return 1;
}
Beispiel #21
0
static int slpv1_url(boolean_t auth_present) {
	time_t exp;
	int lifetime, length;

	get_short();
	if ((lifetime = netval) < 0)
	    return (-1);
	get_short();
	if ((length = netval) < 0)
	    return (-1);

	exp = time(0) + lifetime;
	sprintf(get_line(0, 0), "URL: length = %u, lifetime = %d (%24.24s)",
		length, lifetime, ctime(&exp));
	if (length > msglength) {
	    /* framing error: message is not long enough to contain data */
	    sprintf(get_line(0, 0),
		"  [Framing error: remaining pkt length = %u]",  msglength);
	    return (-1);
	}

	if (length > 0) {
	    char *buf = malloc(length + 1);
	    if (buf != NULL) {
		if (!make_utf8(buf, length, p, length)) {
			strcpy(buf, "[Invalid Character Encoding]");
		}
		sprintf(get_line(0, 0), "  \"%s\"", buf);
		free(buf);
	    }
	}
	msglength -= length;
	p += length;

	if (auth_present)
	    return (slpv1_authblock());

	return (0);
}
Beispiel #22
0
int main(void) {
    unsigned char data = 0x00;
    unsigned short addr = 0x00;

    init_sys();
    init_uart();
    init_am27c();
    wait_for_sequence(seq, seq_len);

    for (;;) {
        addr = get_short();
        data = am27c_get_data(addr);
        UARTCharPut(UART0_BASE, data);
    }
}
Beispiel #23
0
/* ARGSUSED */
static double guess_numeric_type(Acr_VR_Entry *vr_entry, 
                                 Acr_byte_order byte_order,
                                 char *data, long data_length)
{
   switch (data_length) {
   case ACR_SIZEOF_SHORT:
      return get_short(vr_entry, byte_order, data, data_length);
      break;
   case ACR_SIZEOF_LONG:
      return get_long(vr_entry, byte_order, data, data_length);
      break;
   default:
      return string_to_numeric(vr_entry, byte_order, data, data_length);
   }

}
Beispiel #24
0
static void
show_nbp_tuples(uint8_t *p, int tuples, uint8_t *tail)
{
    uint16_t net;
    uint8_t node;
    uint8_t sock;
    uint8_t enumer;
    char obj[100];
    char *op;
    char *otail = &obj[sizeof (obj)];

    while (tuples--) {
        op = obj;
        if ((p + 5) > tail)
            goto out;
        net = get_short(p);
        p += 2;
        node = *p++;
        sock = *p++;
        enumer = *p++;

        if (p > tail || &p[1]+p[0] > tail)
            goto out;
        op += snprintf(op, otail-op, "%.*s", p[0], &p[1]);

        p = &p[1]+p[0];
        if (p > tail || &p[1]+p[0] > tail)
            goto out;
        op += snprintf(op, otail-op, ":%.*s", p[0], &p[1]);

        p = &p[1]+p[0];
        if (p > tail || &p[1]+p[0] > tail)
            goto out;
        (void) snprintf(op, otail-op, "@%.*s", p[0], &p[1]);
        p = &p[1]+p[0];

        (void) snprintf(get_line(0, 0), get_line_remain(),
                        "Name = \"%s\"", obj);
        (void) snprintf(get_line(0, 0), get_line_remain(),
                        "Net = %d, node = %d, sock = %d, enum = %d",
                        net, node, sock, enumer);
    }
    return;
out:
    (void) snprintf(get_line(0, 0), get_line_remain(),
                    "NBP (short tuple)");
}
Beispiel #25
0
/*
 * get a field off the disk from the current file offset
 */
int get_dbf_field(dbhead_t *dbh, dbfield_t *dbf)
{
	struct dbf_dfield	dbfield;
	int ret;

	if ((ret = read(dbh->db_fd, &dbfield, sizeof(dbfield))) <= 0) {
		return ret;
	}

	/* Check for the '0Dh' field terminator , if found return '2'
	   which will tell the loop we are at the end of fields */
	if (dbfield.dbf_name[0]==0x0d) {
		return 2;
	}

	/* build the field name */
	copy_crimp(dbf->db_fname, dbfield.dbf_name, DBF_NAMELEN);

	dbf->db_type = dbfield.dbf_type;
	switch (dbf->db_type) {
	    case 'N':
	    case 'F':
		dbf->db_flen = dbfield.dbf_flen[0];
		dbf->db_fdc = dbfield.dbf_flen[1];
		break;
            case 'D':
		dbf->db_flen = 8;
		break;
	    case 'L':
		dbf->db_flen = 1;
		break;
	    default:
	    	dbf->db_flen = get_short(dbfield.dbf_flen);
		break;
	}

	if ((dbf->db_format = get_dbf_f_fmt(dbf)) == NULL) {
		/* something went wrong, most likely this fieldtype is not supported */
		return -1;
	}

	return 0;
}
Beispiel #26
0
void Args::accept_arg(Pass1 *pass1, ParseNode *arg)
{
	assert(arg->token == RULE_ARG);
	std::list<ParseNode *>::iterator i = arg->children.begin();
	assert(i != arg->children.end());
	assert((*i)->token == CTokenEnums::TOKEN_IDENT);
	std::string base_size = (*i)->text;
	short scalar = 1;
	++i;	// skip past base type
	assert(i != arg->children.end());
	if((*i)->token == '*')
	{
		++i;	// skip past *
		assert(i != arg->children.end());
		assert((*i)->token == CTokenEnums::TOKEN_NUM);
		scalar = get_short((*i)->text);
		if(scalar <= 1)
		{
			throw ParseError(std::string("Invalid argument type: ") + base_size + "*" + (*i)->text,
				arg->lineNum, arg->fileNum, __LINE__
			);
		}
		++i;	// skip scalar
	}
	assert((*i)->token == CTokenEnums::TOKEN_IDENT);
	std::string arg_name = (*i)->text;
	Arg xarg;
	xarg.arg_name = arg_name;
	xarg.size_name = base_size;
	xarg.scalar = scalar;
	Size tmp = pass1->get_exact_size(base_size);
	///std::cout << "(" << base_size << " " << tmp.base << " " << tmp.scalar << ")";
	if(tmp.scalar == 0)
		xarg.base_size = -1;	// parameterized size
	else
	{
		xarg.base_size = tmp.base;
		assert(xarg.scalar == 1);
	}
	///argnums[arg_name] = args.size();
	args.push_back(xarg);
}
Beispiel #27
0
/***********************************************************************
 *
 * Function:    unpack_AddressAppInfo
 *
 * Summary:     Fill in the app info structure based on the raw app 
 *		info data
 *
 * Parameters:  AddressAppInfo_t*, char * to record, record length
 *
 * Returns:     The necessary length of the buffer if record is NULL,
 *		or 0 on error, the length of the data used from the 
 *		buffer otherwise
 *
 ***********************************************************************/
int
unpack_AddressAppInfo(AddressAppInfo_t *ai, const unsigned char *record, size_t len)
{
	size_t 	i,
		destlen = 4 + 16 * 22 + 2 + 2;

	unsigned char *start = record;
	unsigned long r;

	ai->type = address_v1;

	i = unpack_CategoryAppInfo(&ai->category, record, len);
	if (!record)
		return i + destlen;
	if (!i)
		return i;
	record += i;
	len -= i;

	if (len < destlen)
		return 0;

	r = get_long(record);
	for (i = 0; i < 22; i++)
		ai->labelRenamed[i] = !!(r & (1 << i));

	record += 4;
	memcpy(ai->labels, record, 16 * 22);
	record += 16 * 22;
	ai->country = get_short(record);
	record += 2;
	ai->sortByCompany = get_byte(record);
	record += 2;

	for (i = 3; i < 8; i++)
		strcpy(ai->phoneLabels[i - 3], ai->labels[i]);
	for (i = 19; i < 22; i++)
		strcpy(ai->phoneLabels[i - 19 + 5], ai->labels[i]);

	return (record - start);
}
Beispiel #28
0
int load_main(const char *outfile_name)
{
	FILE *o;
	int i, c, len;
	if ((len = get_short()) < 0) exit(1);
	for (i=0; i<len; i++) {
		if ((c = getchar()) == EOF) exit(1);
	}
	find_key(0x00);
	find_key(0x01);
	find_key(0x61);
	print_string("design: ");
	find_key(0x62);
	print_string("part:   ");
	find_key(0x63);
	print_string("date:   ");
	find_key(0x64);
	print_string("time:   ");
	find_key(0x65);
	len = get_long();
	printf("length: %d\n", len);
	if (outfile_name == NULL) {
		for (i=0; i<len/4; i++) {
			printf(" 0x%.8x\n", get_long());
		}
	} else if ((o=fopen(outfile_name,"w"))!=NULL) {
		for (i=0; i<len; i++) {
			fputc(getchar(),o);
		}
		if (fclose(o)) {
			perror("fclose");
			unlink(outfile_name);
		} else {
			printf("wrote:  %s\n",outfile_name);
		}
	}
	return 0;
}
Beispiel #29
0
static int skip_field(int type) {
	unsigned short stringlen;

	get_short();
	if (netval < 0) {
	    return (-1);
	}
	stringlen = netval;

	/* special case for NA field in SrvTypeRqst */
	if (type == FIELD_TYPENA && stringlen == 0xffff) {
	    stringlen = 0;
	}

	if (stringlen > msglength) {
	    return (-1);
	}

	msglength -= stringlen;
	p += stringlen;

	return (stringlen);
}
Beispiel #30
0
void print_string(const char *name)
{
	int i, c, len;
	char *str;
	if ((len = get_short()) < 0) {
		fprintf(stderr,"print_string got EOF instead of length\n");
		exit(1);
	}
	str = malloc(len+1);
	if (str == NULL) {
		perror("print_string malloc");
		exit(1);
	}
	for (i=0; i<len; i++) {
		if ((c = getchar()) == EOF) {
			fprintf(stderr,"print_string found EOF in string of length %d\n", len);
			exit(1);
		}
		str[i] = c;
	}
	str[len] = '\0';
	printf("%s%s\n", name, str);
}