예제 #1
0
파일: dsi.c 프로젝트: Sky-git/afpfs-ng-fork
static int dsi_parse_versions(struct afp_server * server, char * msg) 
{
	unsigned char num_versions = msg[0];
	int i,j=0;
	char * p;
	unsigned char len;
	char tmpversionname[33];
	struct afp_versions * tmpversion;	

	memset(server->versions,0, SERVER_MAX_VERSIONS);

	if (num_versions > SERVER_MAX_VERSIONS) num_versions = SERVER_MAX_VERSIONS;
	p=msg+1;
	for (i=0;i<num_versions;i++) {
		len=copy_from_pascal(tmpversionname,p,33)+1;
		for (tmpversion=afp_versions;tmpversion->av_name;tmpversion++) {
			if (strcmp(tmpversion->av_name,tmpversionname)==0) {
				server->versions[j]=tmpversion->av_number;
				j++;
				break;
			}
		}
		p+=len;
	}
	return 0;
}
예제 #2
0
파일: dsi.c 프로젝트: Sky-git/afpfs-ng-fork
static int dsi_parse_uams(struct afp_server * server, char * msg) 
{
	unsigned char num_uams = msg[0];
	unsigned char len;
	int i;
	char * p;
	char ua_name[AFP_UAM_LENGTH+1];

	server->supported_uams= 0;

	memset(ua_name,0,AFP_UAM_LENGTH+1);

	if (num_uams > SERVER_MAX_UAMS) num_uams = SERVER_MAX_UAMS;
	p=msg+1;
	for (i=0;i<num_uams;i++) {
		len=copy_from_pascal(ua_name,p,AFP_UAM_LENGTH)+1;
		server->supported_uams|=uam_string_to_bitmap(ua_name);
		p+=len;
	}
	
	return 0;

}
예제 #3
0
/* FIXME: should do bounds checking */
int parse_reply_block(struct afp_server *server, char * buf, 
	unsigned int size, unsigned char isdir, unsigned int filebitmap, 
	unsigned int dirbitmap, 
	struct afp_file_info * filecur) 
{

	unsigned short bitmap;
	char * p2;

	memset(filecur,0,sizeof(struct afp_file_info));

	filecur->isdir=isdir;
	p2=buf;

	if (isdir) bitmap=dirbitmap ; 
		else bitmap=filebitmap;

	if (bitmap & kFPAttributeBit) {
		unsigned short * attr = (void *) p2;
		filecur->attributes=ntohs(*attr);
		p2+=2;
	}
	if (bitmap & kFPParentDirIDBit) {
		unsigned int * did= (void *) p2;
		filecur->did=ntohl(*did);
		p2+=4;
	}
	if (bitmap & kFPCreateDateBit) {
		unsigned int * date= (void *) p2;
		filecur->creation_date=AD_DATE_TO_UNIX(*date);
		p2+=4;
	}
	if (bitmap & kFPModDateBit) {
		unsigned int * date= (void *) p2;
		filecur->modification_date=AD_DATE_TO_UNIX(*date);
		p2+=4;
	}
	if (bitmap & kFPBackupDateBit) {
		unsigned int * date= (void *) p2;
		filecur->backup_date=AD_DATE_TO_UNIX(*date);
		p2+=4;
	}
	if (bitmap & kFPFinderInfoBit) {
		memcpy(filecur->finderinfo,p2,32);
		p2+=32;
	}
	if (bitmap & kFPLongNameBit) {
		unsigned short *offset = (void *) p2;
		copy_from_pascal(filecur->name,buf+(ntohs(*offset)),AFP_MAX_PATH);
		p2+=2;
	}
	if (bitmap & kFPShortNameBit) {
		p2+=2;
	}
	if (bitmap & kFPNodeIDBit) {
		unsigned int * id = (void *) p2;
		filecur->fileid=ntohl(*id);
		p2+=4;
	}
	if (isdir) {
		if (bitmap & kFPOffspringCountBit) {
			unsigned short *offspring = (void *) p2;
			filecur->offspring=ntohs(*offspring);
			p2+=2;
		}
		if (bitmap & kFPOwnerIDBit) {
			unsigned int * owner= (void *) p2;
			filecur->unixprivs.uid=ntohl(*owner);
			p2+=4;
		}
		if (bitmap & kFPGroupIDBit) {
			unsigned int * group= (void *) p2;
			filecur->unixprivs.gid=ntohl(*group);
			p2+=4;
		}
		if (bitmap & kFPAccessRightsBit) {
			unsigned int * access= (void *) p2;
			filecur->accessrights=ntohl(*access);
			p2+=4;
		}
	} else {
		if (bitmap & kFPDataForkLenBit) {
			unsigned int * len = (void *) p2;
			filecur->size=ntohl(*len);
			p2+=4;
		}
		if (bitmap & kFPRsrcForkLenBit) {
			unsigned int  * size = (void *) p2;
			filecur->resourcesize=ntohl(*size);
			p2+=4;
		}
		if (bitmap & kFPExtDataForkLenBit) {
			unsigned long long * len = (void *) p2;
			filecur->size=ntoh64(*len);
			p2+=8;
		}
		if (bitmap & kFPLaunchLimitBit) {
			p2+=2;
		}
	}
	if (bitmap & kFPUTF8NameBit) {
		unsigned short *offset = (void *) p2;
		copy_from_pascal_two(filecur->name,buf+(ntohs(*offset))+4,
			AFP_MAX_PATH);
		p2+=2;
		p2+=4;
	}
	if (bitmap & kFPExtRsrcForkLenBit) {
			unsigned long long * size = (void *) p2;
			filecur->resourcesize=ntoh64(*size);
			p2+=8;
	}
	if (bitmap & kFPUnixPrivsBit) {
		struct afp_unixprivs *unixpriv = (void *) p2;

		filecur->unixprivs.uid=ntohl(unixpriv->uid);
		filecur->unixprivs.gid=ntohl(unixpriv->gid);
		filecur->unixprivs.permissions=ntohl(unixpriv->permissions);
		filecur->unixprivs.ua_permissions=ntohl(unixpriv->ua_permissions);
		p2+=sizeof(*unixpriv);
	}
		
	return 0;
}
예제 #4
0
파일: dsi.c 프로젝트: Sky-git/afpfs-ng-fork
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);

	}
}