Exemple #1
0
int afp_volopen_reply(struct afp_server *server, char * buf, unsigned int size, void *other)
{
	struct {
		struct dsi_header header __attribute__((__packed__));
		uint16_t bitmap;
	}  __attribute__((__packed__)) * afp_volopen_reply_packet = (void *) buf;
	unsigned short bitmap;
	struct afp_volume **v_p = (void *) other;
	struct afp_volume * volume=*v_p;
	
	if (size < sizeof (*afp_volopen_reply_packet))
		return -1;

	bitmap=ntohs(afp_volopen_reply_packet->bitmap);

	if (parse_volbitmap_reply(server,volume,
		bitmap, buf+sizeof(*afp_volopen_reply_packet), 
			size-sizeof(*afp_volopen_reply_packet))!=0) 
		return -1;

	if (volume->attributes & kSupportsUTF8Names) {
		convert_utf8dec_to_utf8pre(volume->volume_name, 
			strlen(volume->volume_name),
			volume->volume_name_printable,
			AFP_VOLUME_NAME_UTF8_LEN);
	} else {
		memcpy(volume->volume_name_printable,
			volume->volume_name,AFP_VOLUME_NAME_LEN);
	}

	return 0;
}
Exemple #2
0
void dsi_getstatus_reply(struct afp_server * server) 
{
	/* Todo: check for buffer overruns */

	char * data, *p, *p2;
	int len;
	uint16_t * offset;

	/* This is the fixed portion */
	struct dsi_getstatus_header {
		struct dsi_header dsi __attribute__((__packed__));
		uint16_t machine_offset;
		uint16_t version_offset;
		uint16_t uams_offset;
		uint16_t icon_offset;
		uint16_t flags ;
	} __attribute__((__packed__)) * reply1 = (void *) server->incoming_buffer;

	struct reply2 {
		uint16_t signature_offset;
		uint16_t networkaddress_offset;
		uint16_t directoryservices_offset;
		uint16_t utf8servername_offset;
	} __attribute__((__packed__)) * reply2;

	if (server->data_read < (sizeof(*reply1) + sizeof(*reply2))) {
		log_for_client(NULL,AFPFSD,LOG_ERR,
			"Got incomplete data for getstatus\n");
		return ;
	}

	data = (char * ) server->incoming_buffer + sizeof(struct dsi_header);

	/* First, get the fixed portion */
	p=data + ntohs(reply1->machine_offset);
	copy_from_pascal(server->machine_type,p,AFP_MACHINETYPE_LEN);

	p=data + ntohs(reply1->version_offset);
	dsi_parse_versions(server, p);

	p=data + ntohs(reply1->uams_offset);
	dsi_parse_uams(server, p);

	if (ntohs(reply1->icon_offset)>0) {
		/* The icon and mask are optional */
		p=data + ntohs(reply1->icon_offset);
		memcpy(server->icon,p,256);
	}
	server->flags=ntohs(reply1->flags);

	p=(void *)((unsigned int) server->incoming_buffer + sizeof(*reply1));
	p+=copy_from_pascal(server->server_name,p,AFP_SERVER_NAME_LEN)+1;

	/* Now work our way through the variable bits */

        /* First, make sure we're on an even boundary */
        if (((uint64_t) p) & 0x1) p++;

	/* Get the signature */

	offset = (uint16_t *) p;
	memcpy(server->signature,
        	((void *) data)+ntohs(*offset),
		AFP_SIGNATURE_LEN);
	p+=2;

	/* The network addresses */
	if (server->flags & kSupportsTCP) {
		offset = (uint16_t *) p;
		/* We don't actually do anything with the network addresses,
		 * but if we did, it'd go here */
		p+=2;
	}
	/* The directory names */
	if (server->flags & kSupportsDirServices) {
		offset = (uint16_t *) p;
		/* We don't actually do anything with the directory names,
		 * but if we did, it'd go here */
		p+=2;
	}
	if (server->flags & kSupportsUTF8SrvrName) {

		/* And now the UTF8 server name */
		offset = (uint16_t *) p;

		p2=((void *) data)+ntohs(*offset);

		/* Skip the hint character */
		p2+=1;
		len=copy_from_pascal(server->server_name_utf8,p2,
			AFP_SERVER_NAME_UTF8_LEN);

		/* This is a workaround.  There's a bug in netatalk that in some
		 * circumstances puts the UTF8 servername off by one character */
		if (len==0) {
			p2++;
			len=copy_from_pascal(server->server_name_utf8,p2,
				AFP_SERVER_NAME_UTF8_LEN);
		}

		convert_utf8dec_to_utf8pre(server->server_name_utf8,
			strlen(server->server_name_utf8),
			server->server_name_printable, AFP_SERVER_NAME_UTF8_LEN);
	} else {
		/* We don't have a UTF8 servername, so let's make one */

		iconv_t cd;
		size_t inbytesleft = strlen(server->server_name);
		size_t outbytesleft = AFP_SERVER_NAME_UTF8_LEN;
		char * inbuf = server->server_name;
		char * outbuf = server->server_name_printable;

		if ((cd  = iconv_open("MACINTOSH","UTF-8")) == (iconv_t) -1)
			return;

		iconv(cd,&inbuf,&inbytesleft,
			&outbuf, &outbytesleft);
		iconv_close(cd);

	}
}