1 
2 /*
3  *  utils.c
4  *
5  *  Copyright (C) 2006 Alex deVries
6  *
7  */
8 #include <stdio.h>
9 #include <string.h>
10 #include <stdlib.h>
11 #include "afpfs-ng/afp.h"
12 #include "afpfs-ng/utils.h"
13 #include "afp_internal.h"
14 #include "afpfs-ng/afp_protocol.h"
15 
16 struct afp_path_header_long {
17 	unsigned char type;
18 	unsigned char len;
19 }  __attribute__((__packed__)) ;
20 
21 struct afp_path_header_unicode {
22 	uint8_t type;
23 	uint32_t hint;
24 	uint16_t unicode;
25 }  __attribute__((__packed__)) ;
26 
translate_path(struct afp_volume * volume,char * incoming,char * outgoing)27 int translate_path(struct afp_volume * volume,
28 	char *incoming, char * outgoing)
29 {
30 	return 0;
31 }
32 
utf8_to_string(char * dest,char * buf,unsigned short maxlen)33 unsigned short utf8_to_string(char * dest, char * buf, unsigned short maxlen)
34 {
35 	return copy_from_pascal_two(dest,buf+4,maxlen);
36 }
37 
unixpath_to_afppath(struct afp_server * server,char * buf)38 unsigned char unixpath_to_afppath(
39 	struct afp_server * server,
40 	char * buf)
41 {
42 	unsigned char encoding = server->path_encoding;
43 	char *p =NULL, *end;
44 	unsigned short len;
45 
46 	switch (encoding) {
47 	case kFPUTF8Name: {
48 			unsigned short *len_p = NULL;
49 			len_p = (void *) buf + 5;
50 			p=buf+7;
51 			len=ntohs(*len_p);
52 		}
53 		break;
54 	case kFPLongName: {
55 			unsigned char *len_p = NULL;
56 			len_p = (void *) buf + 1;
57 			p=buf+2;
58 			len=(*len_p);
59 		}
60 	}
61 	end=p+len;
62 
63 	while (p<end) {
64 		if (*p=='/') *p='\0';
65 		p++;
66 	}
67 	return 0;
68 }
69 
afp_unixpriv_to_stat(struct afp_file_info * fp,struct stat * stat)70 void afp_unixpriv_to_stat(struct afp_file_info *fp,
71 	struct stat *stat)
72 {
73 	memset(stat,0,sizeof(*stat));
74 	if (fp->unixprivs.permissions)
75 		stat->st_mode=fp->unixprivs.permissions;
76 	else
77 		stat->st_mode=fp->unixprivs.ua_permissions;
78 	stat->st_uid=fp->unixprivs.uid;
79 	stat->st_gid=fp->unixprivs.gid;
80 }
81 
82 
copy_from_pascal(char * dest,char * pascal,unsigned int max_len)83 unsigned char copy_from_pascal(char *dest, char *pascal,unsigned int max_len)
84 {
85 
86 	unsigned char len;
87 
88 	if (!pascal) return 0;
89 	len=*pascal;
90 
91 	if (max_len<len) len=max_len;
92 
93 	memset(dest,0,max_len);
94 	memcpy(dest,pascal+1,len);
95 	return len;
96 }
97 
copy_from_pascal_two(char * dest,char * pascal,unsigned int max_len)98 unsigned short copy_from_pascal_two(char *dest, char *pascal,unsigned int max_len)
99 {
100 
101 	unsigned short * len_p = (unsigned short *) pascal;
102 	unsigned short len = ntohs(*len_p);
103 
104 	if (max_len<len) len=max_len;
105 	if (len==0) return 0;
106 	memset(dest,0,max_len);
107 	memcpy(dest,pascal+2,len);
108 	return len;
109 }
110 
copy_to_pascal(char * dest,const char * src)111 unsigned char copy_to_pascal(char *dest, const char *src)
112 {
113 	unsigned char len = (unsigned char) strlen(src);
114 	dest[0]=len;
115 
116 	memcpy(dest+1,src,len);
117 	return len;
118 }
119 
copy_to_pascal_two(char * dest,const char * src)120 unsigned short copy_to_pascal_two(char *dest, const char *src)
121 {
122 	unsigned short * sendlen = (void *) dest;
123 	char * data = dest + 2;
124 
125 	unsigned short len ;
126 	if (!src) {
127 		dest[0]=0;
128 		dest[1]=0;
129 		return 2;
130 	}
131 	len = (unsigned short) strlen(src);
132 	*sendlen=htons(len);
133 	memcpy(data,src,len);
134 	return len;
135 }
136 
sizeof_path_header(struct afp_server * server)137 unsigned char sizeof_path_header(struct afp_server * server)
138 {
139 	switch (server->path_encoding) {
140 	case kFPUTF8Name:
141 		return(sizeof(struct afp_path_header_unicode));
142 	case kFPLongName:
143 		return(sizeof(struct afp_path_header_long));
144 	}
145 	return 0;
146 }
147 
148 
copy_path(struct afp_server * server,char * dest,const char * pathname,unsigned char len)149 void copy_path(struct afp_server * server, char * dest, const char * pathname, unsigned char len)
150 {
151 
152 	char tmppathname[255];
153 	unsigned char encoding = server->path_encoding;
154 	struct afp_path_header_unicode * header_unicode = (void *) dest;
155 	struct afp_path_header_long * header_long = (void *) dest;
156 	unsigned char offset, header_len, namelen;
157 
158 	switch (encoding) {
159 	case kFPUTF8Name:
160 		header_unicode->type=encoding;
161 		header_unicode->hint=htonl(0x08000103);
162 		offset = 5;
163 		header_len = sizeof(struct afp_path_header_unicode);
164 		namelen=copy_to_pascal_two(tmppathname,pathname);
165 		memcpy(dest+offset,tmppathname,namelen+2);
166 		break;
167 	case kFPLongName:
168 		header_long->type=encoding;
169 		offset = 1;
170 		header_len = sizeof(struct afp_path_header_long);
171 		namelen=copy_to_pascal(tmppathname,pathname) ;
172 		memcpy(dest+offset,tmppathname,namelen+1);
173 	}
174 }
175 
invalid_filename(struct afp_server * server,const char * filename)176 int invalid_filename(struct afp_server * server, const char * filename)
177 {
178 
179 	unsigned int maxlen=0;
180 	int len;
181 	char * p, *q;
182 
183 	len = strlen(filename);
184 
185 	if ((len==1) && (*filename=='/')) return 0;
186 
187 	/* From p.34, each individual file can be 255 chars for > 30
188 	   for Long or short names.  UTF8 is "virtually unlimited" */
189 
190 	if (server->using_version->av_number < 30)
191 		maxlen=31;
192 	else
193 		if (server->path_encoding==kFPUTF8Name)
194 			maxlen=1024;
195 		else
196 			maxlen=255;
197 
198 
199 	p=(char *)filename+1;
200 	while ((q=strchr(p,'/'))) {
201 		if (q>p+maxlen)
202 			return 1;
203 		p=q+1;
204 		if (p>filename+len)
205 			return 0;
206 	}
207 
208 	if (strlen(filename)-(p-filename)>maxlen)
209 		return 1;
210 
211 	return 0;
212 
213 }
214 
215