Example #1
0
LOCAL void ReadNB05(void)
{
	ulong		cnt;
	ushort		tMod = 0;
	ulong		i;

	// locate directory, read number of entries, allocate space, read
	// directory entries and sort into ascending module index order

	if ((link_read (exefile, (char *)&lfoDir, sizeof (long)) != sizeof (long)) ||
	  (link_lseek (exefile, lfoDir + lfoBase, SEEK_SET) == -1L) ||
	  (link_read (exefile, (char *)&DirHead, sizeof (DirHead)) !=
	  sizeof (OMFDirHeader))) {
		ErrorExit(ERR_INVALIDEXE, NULL, NULL);
	}

	if (!DirHead.cDir) {
		ErrorExit(ERR_INVALIDEXE, NULL, NULL);
	}

	cSST = DirHead.cDir;

	// read directory into local memory to sort, then copy to far memory buffer

	cnt = (cSST + 6) * sizeof (OMFDirEntry);
	DASSERT(cnt <= UINT_MAX);

	if ((pDir = (OMFDirEntry *)TrapMalloc ((size_t)cnt)) == NULL) {
		ErrorExit(ERR_NOMEM, NULL, NULL);
	}

	if (link_read (exefile, (char *)pDir, (size_t)(sizeof (OMFDirEntry) * cSST)) !=
		 (sizeof (OMFDirEntry) * cSST)) {
		ErrorExit(ERR_INVALIDEXE, NULL, NULL);
	}

	for (i = 0; i < cSST; i++) {
		if ((pDir[i].iMod != 0) && (pDir[i].iMod != 0xffff)) {
			if (pDir[i].iMod != tMod) {
				if (pDir[i].SubSection != sstModule) {
					// module entry not first, need to sort
					break;
				}

				tMod = pDir[i].iMod;
			}
		}
	}

	if (i != cSST) {
		qsort(pDir, (size_t) cSST, sizeof(OMFDirEntry), modsort);
	}

}
Example #2
0
INT64_T chirp_client_getfile_buffer(struct chirp_client * c, const char *path, char **buffer, time_t stoptime)
{
	INT64_T length;
	INT64_T result;

	char safepath[CHIRP_LINE_MAX];
	url_encode(path, safepath, sizeof(safepath));

	*buffer = 0;

	length = simple_command(c, stoptime, "getfile %s\n", safepath);
	if(length <= 0)
		return length;

	*buffer = malloc(length + 1);
	if(!*buffer) {
		c->broken = 1;
		errno = ENOMEM;
		return -1;
	}

	result = link_read(c->link, *buffer, length, stoptime);
	if(result < 0) {
		free(*buffer);
		c->broken = 1;
		return -1;
	}

	(*buffer)[length] = 0;

	return result;
}
Example #3
0
INT64_T chirp_alloc_putstream(const char *path, struct link * l, time_t stoptime)
{
	INT64_T fd, result, actual, total = 0;
	int buffer_size = 65536;
	char *buffer;

	fd = chirp_alloc_open(path, O_CREAT | O_TRUNC | O_WRONLY, 0700);
	if(fd < 0)
		return fd;

	link_putliteral(l, "0\n", stoptime);

	buffer = malloc(buffer_size);

	while(1) {
		result = link_read(l, buffer, buffer_size, stoptime);
		if(result <= 0)
			break;

		actual = chirp_alloc_pwrite(fd, buffer, result, total);
		if(actual != result)
			break;

		total += actual;
	}

	free(buffer);

	chirp_alloc_close(fd);

	return total;
}
Example #4
0
LOCAL ushort CheckSignature(void)
{
	if (link_read (exefile, Signature, 4) == 4) {
		if ((Signature[0] != 'N') || (Signature[1] != 'B')) {
			ErrorExit(ERR_RELINK, NULL, NULL);
		}

		if (Signature[2] == '0') {
			if (Signature[3] == '5') {
				return(SIG05);
			}
		}

		if ((Signature[2] == '0' && Signature[3] == '9') ||
			(Signature[2] == '1' && Signature[3] == '0')) {
			// Just return a zero here when stripping.
			// They just have to match until we strip

			if (strip) {
				return(0);
			}

			Warn(WARN_PACKED, NULL, NULL);
			AppExit(0);
		}

		ErrorExit(ERR_RELINK, NULL, NULL);
	}

	ErrorExit(ERR_INVALIDEXE, NULL, NULL);
}
Example #5
0
static int jx_getchar( struct jx_parser *p )
{
	int c=0;

	if(p->putback_char_valid) {
		p->putback_char_valid = 0;
		return p->putback_char;
	}

	if(p->source_file) {
		c = fgetc(p->source_file);
	} else if(p->source_string) {
		c = *p->source_string;
		if(c) {
			p->source_string++;
		} else {
			c = EOF;
		}
	} else if(p->source_link) {
		char ch;
		int result = link_read(p->source_link,&ch,1,p->stoptime);
		if(result==1) {
			c = ch;
		} else {
			c = EOF;
		}
	}

	return c;
}
Example #6
0
INT64_T link_stream_to_buffer(struct link * link, char **buffer, time_t stoptime)
{
	INT64_T buffer_size = 8192;
	INT64_T total = 0;
	INT64_T actual;
	char *newbuffer;

	*buffer = malloc(buffer_size);
	if(!*buffer)
		return -1;

	while(1) {
		actual = link_read(link, &(*buffer)[total], buffer_size - total, stoptime);
		if(actual <= 0)
			break;

		total += actual;

		if((buffer_size - total) < 1) {
			buffer_size *= 2;
			newbuffer = realloc(*buffer, buffer_size);
			if(!newbuffer) {
				free(*buffer);
				return -1;
			}
			*buffer = newbuffer;
		}
	}

	(*buffer)[total] = 0;

	return total;
}
Example #7
0
INT64_T link_stream_to_file(struct link * link, FILE * file, INT64_T length, time_t stoptime)
{
	char buffer[65536];
	INT64_T total = 0;
	INT64_T ractual, wactual;

	while(length > 0) {
		INT64_T chunk = MIN(sizeof(buffer), length);

		ractual = link_read(link, buffer, chunk, stoptime);
		if(ractual <= 0)
			break;

		wactual = full_fwrite(file, buffer, ractual);
		if(wactual != ractual) {
			total = -1;
			break;
		}

		total += ractual;
		length -= ractual;
	}

	return total;
}
Example #8
0
int son_phy_read_fileno(son_phy_t * phy, int fd, void * buffer, u32 nbyte){
#if defined __link
	if( phy->driver ){
		return link_read(phy->driver, fd, buffer, nbyte);
	}
#endif
	return -1;
}
Example #9
0
int son_phy_read(son_phy_t * phy, void * buffer, u32 nbyte){
	if( phy->message ){
		return phy_read_message(phy, buffer, nbyte);
	}
	if( phy->driver == 0 ){
		//read using fread
		return fread(buffer, 1, nbyte, phy->f);
	} else {
#if defined __link
		return link_read(phy->driver, phy->fd, buffer, nbyte);
#else
		return -1;
#endif
	}
}
Example #10
0
INT64_T chirp_client_sread_finish(struct chirp_client * c, INT64_T fd, void *buffer, INT64_T length, INT64_T stride_length, INT64_T stride_skip, INT64_T offset, time_t stoptime)
{
	INT64_T result;
	INT64_T actual;

	result = get_result(c, stoptime);
	if(result > 0) {
		actual = link_read(c->link, buffer, result, stoptime);
		if(actual != result) {
			errno = ECONNRESET;
			return -1;
		}
	}

	return result;
}
Example #11
0
INT64_T chirp_client_ticket_list(struct chirp_client * c, const char *subject, char ***list, time_t stoptime)
{
	INT64_T result;

	size_t size = 0;
	*list = NULL;

	result = simple_command(c, stoptime, "ticket_list %s\n", subject);

	if(result == 0) {

		while(1) {
			char line[CHIRP_LINE_MAX];
			size_t length;

			if(!link_readline(c->link, line, CHIRP_LINE_MAX, stoptime))
				goto failure;
			if(sscanf(line, "%zu", &length) != 1)
				goto failure;
			if(length == 0)
				break;

			size++;
			*list = xxrealloc(*list, sizeof(char *) * (size + 1));
			(*list)[size - 1] = xxmalloc(sizeof(char) * (length + 1));
			if(!link_read(c->link, (*list)[size - 1], length, stoptime))
				goto failure;
			(*list)[size - 1][length] = '\0';
			(*list)[size] = NULL;
		}

		return 0;
	      failure:
		if(*list != NULL) {
			char **tmp = *list;
			while(tmp[0]) {
				free(tmp[0]);
			}
			free(*list);
		}
		c->broken = 1;
		errno = ECONNRESET;
		return -1;
	}

	return result;
}
Example #12
0
INT64_T cfs_basic_putfile(const char *path, struct link * link, INT64_T length, INT64_T mode, time_t stoptime)
{
	int fd;
	INT64_T result;

	mode = 0600 | (mode & 0100);

	fd = cfs->open(path, O_WRONLY | O_CREAT | O_TRUNC, (int) mode);
	if(fd >= 0) {
		char buffer[65536];
		INT64_T total = 0;

		link_putliteral(link, "0\n", stoptime);

		while(length > 0) {
			INT64_T ractual, wactual;
			INT64_T chunk = MIN((int) sizeof(buffer), length);

			ractual = link_read(link, buffer, chunk, stoptime);
			if(ractual <= 0)
				break;

			wactual = cfs->pwrite(fd, buffer, ractual, total);
			if(wactual != ractual) {
				total = -1;
				break;
			}

			total += ractual;
			length -= ractual;
		}

		result = total;

		if(length != 0) {
			if(result >= 0)
				link_soak(link, length - result, stoptime);
			result = -1;
		}
		cfs->close(fd);
	} else {
		result = -1;
	}
	return result;
}
Example #13
0
INT64_T chirp_client_whoareyou(struct chirp_client * c, const char *rhost, char *buffer, INT64_T length, time_t stoptime)
{
	INT64_T result;
	INT64_T actual;

	result = simple_command(c, stoptime, "whoareyou %s %lld\n", rhost, length);

	if(result > 0) {
		actual = link_read(c->link, buffer, result, stoptime);
		if(actual != result) {
			c->broken = 1;
			errno = ECONNRESET;
			return -1;
		}
	}

	return result;
}
Example #14
0
INT64_T chirp_client_flistxattr(struct chirp_client *c, INT64_T fd, char *list, size_t size, time_t stoptime)
{
	INT64_T result = send_command(c, stoptime, "flistxattr %lld\n", fd);
    if (result < 0) 
        return result;
	result = get_result(c, stoptime);
    if (result < 0) 
        return result;
    if (result > (int) size) {
		link_soak(c->link, result, stoptime);
        errno = ERANGE;
        return result;
    }
	if(!link_read(c->link, list, result, stoptime)) {
        return -1;
    }
    return result;
}
Example #15
0
int64_t link_soak(struct link * link, int64_t length, time_t stoptime)
{
	int64_t total = 0;

	while(length > 0) {
		char buffer[1<<16];
		size_t chunk = MIN(sizeof(buffer), (size_t)length);

		ssize_t ractual = link_read(link, buffer, chunk, stoptime);
		if(ractual <= 0)
			break;

		total += ractual;
		length -= ractual;
	}

	return total;
}
Example #16
0
INT64_T link_soak(struct link * link, INT64_T length, time_t stoptime)
{
	char buffer[65536];
	INT64_T total = 0;
	INT64_T ractual;

	while(length > 0) {
		INT64_T chunk = MIN(sizeof(buffer), length);

		ractual = link_read(link, buffer, chunk, stoptime);
		if(ractual <= 0)
			break;

		total += ractual;
		length -= ractual;
	}

	return total;
}
Example #17
0
static int read_token(void *link, void **bufp, size_t * sizep)
{
	char line[AUTH_LINE_MAX];
	time_t stoptime = time(0) + 3600;
	int result;

	if(link_readline(link, line, sizeof(line), stoptime)) {
		*sizep = atoi(line);
		*bufp = malloc(*sizep);
		if(*bufp) {
			result = link_read(link, *bufp, *sizep, stoptime);
			if(result == (int) *sizep) {
				return GLOBUS_SUCCESS;
			}
			free(*bufp);
		}
	}

	return GLOBUS_GSS_ASSIST_TOKEN_EOF;
}
Example #18
0
LOCAL void CopyTable(OMFDirEntry *pDir, _vmhnd_t *pAddr, ulong *pSize)
{
	_vmhnd_t TableAddr;
	char	 *pTable;

	if ((TableAddr = (_vmhnd_t)TrapMalloc (pDir->cb)) == NULL) {
		ErrorExit(ERR_NOMEM, NULL, NULL);
	}

	pTable = (char *) TableAddr;

	link_lseek(exefile, pDir->lfo + lfoBase, SEEK_SET);

	if (link_read(exefile, pTable, pDir->cb) != pDir->cb) {
		ErrorExit(ERR_INVALIDEXE, NULL, NULL);
	}

	*pAddr = TableAddr;
	*pSize = pDir->cb;
}
Example #19
0
INT64_T chirp_client_fgetxattr(struct chirp_client *c, INT64_T fd, const char *name, void *data, size_t size, time_t stoptime)
{
	INT64_T result = send_command(c, stoptime, "fgetxattr %lld %s\n", fd, name);
    if (result < 0)
        return result;

	result = get_result(c, stoptime);
    if (result < 0) { 
		if (errno == EINVAL) errno = ENOATTR;
        return result;
	} else if (result > (int) size) {
		link_soak(c->link, result, stoptime);
        errno = ERANGE;
        return result;
    }
	if(!link_read(c->link, data, result, stoptime)) {
        return -1;
    }
    return result;
}
Example #20
0
INT64_T chirp_client_llistxattr(struct chirp_client *c, const char *path, char *list, size_t size, time_t stoptime)
{
	char safepath[CHIRP_LINE_MAX];
	url_encode(path, safepath, sizeof(safepath));
	INT64_T result = send_command(c, stoptime, "llistxattr %s\n", safepath);
    if (result < 0) 
        return result;
	result = get_result(c, stoptime);
    if (result < 0) 
        return result;
    if (result > (int) size) {
		link_soak(c->link, result, stoptime);
        errno = ERANGE;
        return result;
    }
	if(!link_read(c->link, list, result, stoptime)) {
        return -1;
    }
    return result;
}
Example #21
0
INT64_T chirp_client_lgetxattr(struct chirp_client *c, const char *path, const char *name, void *data, size_t size, time_t stoptime)
{
	char safepath[CHIRP_LINE_MAX];
	url_encode(path, safepath, sizeof(safepath));
	INT64_T result = send_command(c, stoptime, "lgetxattr %s %s\n", safepath, name);
    if (result < 0)
        return result;
	result = get_result(c, stoptime);
    if (result < 0) {
		if (errno == EINVAL) errno = ENOATTR;
        return result;
	} else if (result > (int) size) {
		link_soak(c->link, result, stoptime);
        errno = ERANGE;
        return result;
    }
	if(!link_read(c->link, data, result, stoptime)) {
        return -1;
    }
    return result;
}
Example #22
0
INT64_T chirp_client_localpath(struct chirp_client * c, const char *path, char *localpath, int length, time_t stoptime)
{
	INT64_T result;
	INT64_T actual;

	char safepath[CHIRP_LINE_MAX];
	url_encode(path, safepath, sizeof(safepath));

	result = simple_command(c, stoptime, "localpath %s\n", path);

	if(result > 0) {
		actual = link_read(c->link, localpath, result, stoptime);
		if(actual != result) {
			c->broken = 1;
			errno = ECONNRESET;
			return -1;
		}
	}

	return result;
}
Example #23
0
int get_results(struct link *mpi_link, struct itable *active_list, struct list *complete_list, int timeout)
{
	char line[MPI_QUEUE_LINE_MAX];
	int num_results, n = 0;
	int stoptime = time(0) + timeout;

	debug(D_MPI, "Getting any results\n");
	link_putliteral(mpi_link, "get results\n", stoptime);
	if(link_readline(mpi_link, line, sizeof(line), stoptime)) {
		debug(D_MPI, "received: %s\n", line);
		sscanf(line, "num results %d", &num_results);
	} else {
		return 0;
	}
	debug(D_MPI, "%d results available\n", num_results);

	while(n++ < num_results && link_readline(mpi_link, line, sizeof(line), stoptime)) {
		struct mpi_queue_task *t;
		int taskid, status, result, result_length;
		
		sscanf(line, "result %d %d %d %d", &taskid, &status, &result, &result_length);
		t = itable_remove(active_list, taskid);
		if(!t) {
			debug(D_NOTICE, "Invalid taskid (%d) returned\n", taskid);
			return -1;
		}
		if(result_length) {
			t->output = malloc(result_length+1);
			link_read(mpi_link, t->output, result_length, time(0) + timeout);
			t->output[result_length] = 0;
		}
		t->status = MPI_QUEUE_TASK_STATUS_COMPLETE;
		t->return_status = result;
		t->result = status;
		list_push_tail(complete_list, t);
	}
	return num_results;
}
Example #24
0
void handle_tcp_update( struct link *update_port )
{
	char data[TCP_PAYLOAD_MAX];

	time_t stoptime = time(0) + HANDLE_TCP_UPDATE_TIMEOUT;

	struct link *l = link_accept(update_port,stoptime);
	if(!l) return;

	char addr[LINK_ADDRESS_MAX];
	int port;

	link_address_remote(l,addr,&port);

	int length = link_read(l,data,sizeof(data)-1,stoptime);

	if(length>0) {
		data[length] = 0;
		handle_update(addr,port,data,length,"tcp");
	}

	link_close(l);
}
Example #25
0
INT64_T chirp_client_md5(struct chirp_client * c, const char *path, unsigned char digest[16], time_t stoptime)
{
	INT64_T result;
	INT64_T actual;

	char safepath[CHIRP_LINE_MAX];
	url_encode(path, safepath, sizeof(safepath));

	result = simple_command(c, stoptime, "md5 %s\n", path);

	if(result == 16) {
		actual = link_read(c->link, (char *) digest, 16, stoptime);
		if(actual != result) {
			errno = ECONNRESET;
			result = -1;
		}

	} else if(result >= 0) {
		result = -1;
		errno = ECONNRESET;
	}
	return result;
}
Example #26
0
int64_t link_stream_to_file(struct link * link, FILE * file, int64_t length, time_t stoptime)
{
	int64_t total = 0;

	while(length > 0) {
		char buffer[1<<16];
		size_t chunk = MIN(sizeof(buffer), (size_t)length);

		ssize_t ractual = link_read(link, buffer, chunk, stoptime);
		if(ractual <= 0)
			break;

		ssize_t wactual = full_fwrite(file, buffer, ractual);
		if(wactual != ractual) {
			total = -1;
			break;
		}

		total += ractual;
		length -= ractual;
	}

	return total;
}
Example #27
0
ssize_t link_stream_to_buffer(struct link * link, char **buffer, time_t stoptime)
{
	ssize_t total = 0;
	buffer_t B;
	buffer_init(&B);

	while(1) {
		char buf[1<<16];
		ssize_t actual = link_read(link, buf, sizeof(buf), stoptime);
		if(actual <= 0)
			break;
		if (buffer_putlstring(&B, buf, actual) == -1) {
			buffer_free(&B);
			return -1;
		}
		total += actual;
	}

	if (buffer_dup(&B, buffer) == -1)
		total = -1;
	buffer_free(&B);

	return total;
}
Example #28
0
int s3_getacl(char* bucketname, char* filename, char* owner, struct hash_table* acls, const char* access_key_id, const char* access_key) {
	struct s3_message mesg;
	struct link* server;
	time_t stoptime = time(0)+s3_timeout;
	char path[HEADER_LINE_MAX];
	char response[HEADER_LINE_MAX];
	char * text;
	char * start;
	char * temp;
	int length;
 
	if(!s3_endpoint) return -1;
	if(filename) sprintf(path, "%s?acl", filename);
	else sprintf(path, "/?acl");

	mesg.type = S3_MESG_GET;
	mesg.path = path;
	mesg.bucket = bucketname;
	mesg.content_type = NULL;
	mesg.content_md5 = NULL;
	mesg.content_length = 0;
	mesg.date = time(0);
	mesg.expect = 0;
	mesg.amz_headers = NULL;

	//server = link_connect(s3_address, 80, stoptime);

	sign_message(&mesg, access_key_id, access_key);
	server = s3_send_message(&mesg, NULL, stoptime);
	if(!server)
		return -1;
	//length = s3_message_to_string(&mesg, &text);

	//link_putlstring(server, text, length, stoptime);
	//free(text);

	link_readline(server, response, HEADER_LINE_MAX, stoptime);
	if(strcmp(response, "HTTP/1.1 200 OK")) {
		// Error: transfer failed; close connection and return failure
		//fprintf(stderr, "Error: request file failed\nResponse: %s\n", response);
		link_close(server);
		return -1;
	}

	do {
		if(!strncmp(response, "Content-Length:", 14)) sscanf(response, "Content-Length: %d", &length);
		if(!strcmp(response, "Transfer-Encoding: chunked")) length = 0;
		if(!strcmp(response, "Server: AmazonS3")) break;
	} while(link_readline(server, response, HEADER_LINE_MAX, stoptime));
	link_readline(server, response, HEADER_LINE_MAX, stoptime);

	if(length) {
		text = malloc(length+1);
		link_read(server, text, length, stoptime);
	} else {
		struct list *buf;
		char *temp;
		unsigned int clen = 0;
		buf = list_create();
		do {
			link_readline(server, response, HEADER_LINE_MAX, stoptime);
			sscanf(response, "%x", &clen);
			//link_readline(server, response, HEADER_LINE_MAX, stoptime);
			if(clen) {
				text = malloc(clen+1);
				link_read(server, text, clen, stoptime);
				link_readline(server, response, HEADER_LINE_MAX, stoptime);
				list_push_tail(buf, text);
				length += clen;
			}
		} while(clen);
		text = malloc(length+1);
		text[0] = '\0';
		while((temp = list_pop_head(buf))) {
			sprintf(text, "%s%s", text, temp);
			free(temp);
		}
		list_delete(buf);
	}
	link_close(server);

	if(owner) sscanf(strstr(text, "<Owner>"), "<Owner><ID>%[^<]</ID>", owner);
	temp = text;
	while( (start = strstr(temp, "<Grant>")) ) {
		char id[1024];
		char display_name[1024];
		char permission[1024];
		char type;
		struct s3_acl_object *acl;
		char *end;

		end = strstr(start, "</Grant>");
		end[7] = '\0';
		temp = end + 8;

		memset(display_name, 0, 1024);
		type = S3_ACL_ID;
		if( sscanf(start, "<Grant><Grantee %*[^>]><ID>%[^<]</ID><DisplayName>%[^<]</DisplayName></Grantee><Permission>%[^<]</Permission></Grantee>", id, display_name, permission) != 3 ) {
			type = S3_ACL_URI;
			sscanf(start, "<Grant><Grantee %*[^>]><URI>http://acs.amazonaws.com/groups/global/%[^<]</URI></Grantee><Permission>%[^<]</Permission></Grantee>", id, permission);
		}

		if( !(acl = hash_table_lookup(acls, id)) ) {
			acl = malloc(sizeof(*acl));
			acl->acl_type = type;
			if(*display_name) acl->display_name = strdup(display_name);
			else acl->display_name = NULL;
			acl->perm = 0;
			hash_table_insert(acls, id, acl);
		}

		if(!strcmp(permission, "FULL_CONTROL")) {
			acl->perm = acl->perm | S3_ACL_FULL_CONTROL;
		} else if(!strcmp(permission, "READ")) {
			acl->perm = acl->perm | S3_ACL_READ;
		} else if(!strcmp(permission, "WRITE")) {
			acl->perm = acl->perm | S3_ACL_WRITE;
		} else if(!strcmp(permission, "READ_ACP")) {
			acl->perm = acl->perm | S3_ACL_READ_ACP;
		} else if(!strcmp(permission, "WRITE_ACP")) {
			acl->perm = acl->perm | S3_ACL_WRITE_ACP;
		}
	}

	free(text);
	return 0;
}
Example #29
0
uint8 Link::read(unsigned addr) {
  if(link_read) return link_read(addr);
  return cpu.regs.mdr;
}
Example #30
0
INT64_T chirp_client_ticket_get(struct chirp_client * c, const char *name, char **subject, char **ticket, time_t * duration, char ***rights, time_t stoptime)
{
	INT64_T result;
	char ticket_subject[CHIRP_LINE_MAX];

	*subject = *ticket = NULL;
	*rights = NULL;

	ticket_translate(name, ticket_subject);

	result = simple_command(c, stoptime, "ticket_get %s\n", ticket_subject);

	if(result == 0) {
		char line[CHIRP_LINE_MAX];
		size_t length;
		size_t nrights = 0;

		if(!link_readline(c->link, line, CHIRP_LINE_MAX, stoptime))
			goto failure;
		if(sscanf(line, "%zu", &length) != 1)
			goto failure;
		*subject = xxmalloc((length + 1) * sizeof(char));
		if(!link_read(c->link, *subject, length, stoptime))
			goto failure;
		(*subject)[length] = '\0';

		if(!link_readline(c->link, line, CHIRP_LINE_MAX, stoptime))
			goto failure;
		if(sscanf(line, "%zu", &length) != 1)
			goto failure;
		*ticket = xxmalloc((length + 1) * sizeof(char));
		if(!link_read(c->link, *ticket, length, stoptime))
			goto failure;
		(*ticket)[length] = '\0';

		if(!link_readline(c->link, line, CHIRP_LINE_MAX, stoptime))
			goto failure;
		unsigned long long tmp;
		if(sscanf(line, "%llu", &tmp) != 1)
			goto failure;
		*duration = (time_t) tmp;

		while(1) {
			char path[CHIRP_PATH_MAX];
			char acl[CHIRP_LINE_MAX];
			if(!link_readline(c->link, line, CHIRP_LINE_MAX, stoptime))
				goto failure;
			if(sscanf(line, "%s %s", path, acl) == 2) {
				*rights = xxrealloc(*rights, sizeof(char *) * 2 * (nrights + 2));
				(*rights)[nrights * 2 + 0] = xxstrdup(path);
				(*rights)[nrights * 2 + 1] = xxstrdup(acl);
				(*rights)[nrights * 2 + 2] = NULL;
				(*rights)[nrights * 2 + 3] = NULL;
				nrights++;
			} else if(sscanf(line, "%" SCNd64 , &result) == 1 && result == 0) {
				break;
			} else
				goto failure;
		}

		return 0;
	      failure:
		free(*subject);
		free(*ticket);
		if(*rights != NULL) {
			char **tmp = *rights;
			while(tmp[0] && tmp[1]) {
				free(tmp[0]);
				free(tmp[1]);
			}
			free(*rights);
		}
		*subject = *ticket = NULL;
		c->broken = 1;
		errno = ECONNRESET;
		return -1;
	}

	return result;
}