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