1 /**
2 	\file apps/obex_io.c
3 	Some useful disk-IO functions.
4 	OpenOBEX test applications and sample code.
5 
6 	Copyright (c) 1999 Dag Brattli, All Rights Reserved.
7 	Copyright (c) 2000 Pontus Fuchs, All Rights Reserved.
8 
9 	OpenOBEX is free software; you can redistribute it and/or modify
10 	it under the terms of the GNU General Public License as
11 	published by the Free Software Foundation; either version 2 of
12 	the License, or (at your option) any later version.
13 
14 	This program is distributed in the hope that it will be useful,
15 	but WITHOUT ANY WARRANTY; without even the implied warranty of
16 	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17 	GNU General Public License for more details.
18 
19 	You should have received a copy of the GNU General Public
20 	License along with OpenOBEX. If not, see <http://www.gnu.org/>.
21  */
22 
23 #ifdef HAVE_CONFIG_H
24 #include <config.h>
25 #endif
26 
27 #include <openobex/obex.h>
28 
29 #ifdef _WIN32
30 #include <windows.h>
31 #include <io.h>
32 #else
33 #include <sys/stat.h>
34 #include <unistd.h>
35 #endif /*_WIN32 */
36 
37 #include <stdio.h>
38 #include <stdlib.h>
39 #include <fcntl.h>
40 #include <string.h>
41 
42 #include "obex_io.h"
43 
44 extern obex_t *handle;
45 int obex_protocol_type = OBEX_PROTOCOL_GENERIC;
46 
47 //
48 // Get the filesize in a "portable" way
49 //
get_filesize(const char * filename)50 int get_filesize(const char *filename)
51 {
52 #ifdef _WIN32
53 	HANDLE fh;
54 	int size;
55 	fh = CreateFile(filename, 0, 0, NULL, OPEN_EXISTING, 0, NULL);
56 	if(fh == INVALID_HANDLE_VALUE) {
57 		printf("Cannot open %s\n", filename);
58 		return -1;
59 	}
60 	size = GetFileSize(fh, NULL);
61 	printf("fize size was %d\n", size);
62 	CloseHandle(fh);
63 	return size;
64 
65 #else
66 	struct stat stats;
67 	/*  Need to know the file length */
68 	if (stat(filename, &stats) == -1) {
69 		printf("stat() error\n");
70 		return -1;
71 	}
72 	else
73 		return (int) stats.st_size;
74 #endif
75 }
76 
77 
78 //
79 // Read a file and alloc a buffer for it
80 //
easy_readfile(const char * filename,int * file_size)81 uint8_t* easy_readfile(const char *filename, int *file_size)
82 {
83 	int actual;
84 	int fd;
85 	uint8_t *buf;
86 
87 	*file_size = get_filesize(filename);
88 	printf("name=%s, size=%d\n", filename, *file_size);
89 	if (*file_size == -1)
90 		return NULL;
91 
92 #ifdef _WIN32
93 	fd = open(filename, O_RDONLY | O_BINARY, 0);
94 #else
95 	fd = open(filename, O_RDONLY, 0);
96 #endif
97 	if (fd == -1)
98 		return NULL;
99 
100 	buf = malloc(*file_size);
101 	if(!buf) {
102 		close(fd);
103 		return NULL;
104 	}
105 
106 	actual = read(fd, buf, *file_size);
107 	close(fd);
108 
109 #ifdef _WIN32
110 	if(actual != *file_size) {
111 		free(buf);
112 		buf = NULL;
113 	}
114 #else
115 	*file_size = actual;
116 #endif
117 	return buf;
118 }
119 
120 
121 //
122 //
123 //
build_object_from_file(obex_t * handle,const char * filename,uint32_t creator_id)124 obex_object_t *build_object_from_file(obex_t *handle, const char *filename, uint32_t creator_id)
125 {
126 	obex_headerdata_t hdd;
127 	uint8_t unicode_buf[200];
128 	int namebuf_len;
129  	obex_object_t *object;
130 	//uint32_t creator_id;
131 	int file_size;
132 	char *name = NULL;
133 	uint8_t *buf;
134 
135 
136 	buf = easy_readfile(filename, &file_size);
137 	if(buf == NULL)
138 		return NULL;
139 
140 	/* Set Memopad as the default creator ID */
141 	if(creator_id == 0)
142 		creator_id = MEMO_PAD;
143 
144 	/* Find the . in the filename */
145 	name = strchr(filename, '.');
146 	if (name) {
147 		name++;
148 		if (strcmp(name, "vcf") == 0) {
149 			printf( "This is a Address Book file\n");
150 			creator_id = ADDRESS_BOOK;
151 		} else if (strcmp(name, "vcs") == 0) {
152 			printf( "This is a Date Book file\n");
153 			creator_id = DATE_BOOK;
154 		} else if (strcmp(name, "txt") == 0) {
155 			printf("This is a Memo pad file\n");
156 			creator_id = MEMO_PAD;
157 		} else if (strcmp(name, "prc") == 0) {
158 			printf("This is a Pilot resource file\n");
159 			creator_id = PILOT_RESOURCE;
160 		}
161 	}
162 	/* Build object */
163 	object = OBEX_ObjectNew(handle, OBEX_CMD_PUT);
164 
165 	namebuf_len = OBEX_CharToUnicode(unicode_buf, (uint8_t *) filename, sizeof(unicode_buf));
166 
167 	hdd.bs = unicode_buf;
168 	OBEX_ObjectAddHeader(handle, object, OBEX_HDR_NAME,
169 				hdd, namebuf_len, 0);
170 
171 	hdd.bq4 = file_size;
172 	OBEX_ObjectAddHeader(handle, object, OBEX_HDR_LENGTH,
173 				hdd, sizeof(uint32_t), 0);
174 
175 #if 0
176 	/* Optional header for win95 irxfer, allows date to be set on file */
177 	OBEX_ObjectAddHeader(handle, object, OBEX_HDR_TIME2,
178 				(obex_headerdata_t) (uint32_t) stats.st_mtime,
179 				sizeof(uint32_t), 0);
180 #endif
181 	if (obex_protocol_type != 1) {
182 		/* Optional header for Palm Pilot */
183 		/* win95 irxfer does not seem to like this one */
184 		hdd.bq4 = creator_id;
185 		OBEX_ObjectAddHeader(handle, object, HEADER_CREATOR_ID,
186 					hdd, sizeof(uint32_t), 0);
187 	}
188 
189 	hdd.bs = buf;
190 	OBEX_ObjectAddHeader(handle, object, OBEX_HDR_BODY,
191 				hdd, file_size, 0);
192 
193 	free(buf);
194 	return object;
195 }
196 
197 
198 /*
199  * Function safe_save_file ()
200  *
201  *    First remove path and add "/tmp/". Then save.
202  *
203  */
204 #ifndef DEFFILEMODE
205 #define DEFFILEMODE 0
206 #endif
safe_save_file(char * name,const uint8_t * buf,int len)207 int safe_save_file(char *name, const uint8_t *buf, int len)
208 {
209 	char *s = NULL;
210 	char filename[255] = {0,};
211 	int fd;
212 	int actual;
213 
214 
215 	printf("Filename = %s\n", name);
216 
217 	s = strrchr(name, '/');
218 	if (s == NULL)
219 		s = name;
220 	else
221 		s++;
222 
223 	strncat(filename, s, 250);
224 	fd = open(filename, O_RDWR | O_CREAT, DEFFILEMODE);
225 
226 	if ( fd < 0) {
227 		perror( filename);
228 		return -1;
229 	}
230 
231 	actual = write(fd, buf, len);
232 	close(fd);
233 
234 	printf( "Wrote %s (%d bytes)\n", filename, actual);
235 
236 	return actual;
237 }
238 
OBEX_UnicodeToChar(uint8_t * c,const uint8_t * uc,int size)239 int OBEX_UnicodeToChar(uint8_t *c, const uint8_t *uc, int size)
240 {
241 	int n;
242 
243 	if (uc == NULL || c == NULL)
244 		return -1;
245 
246 	/* Make sure buffer is big enough! */
247 	for (n = 0; uc[n*2+1] != 0; n++);
248 
249 	if (n >= size)
250 		return -1;
251 
252 	for (n = 0; uc[n*2+1] != 0; n++)
253 		c[n] = uc[n*2+1];
254 	c[n] = 0;
255 
256 	return 0;
257 }
258 
OBEX_CharToUnicode(uint8_t * uc,const uint8_t * c,int size)259 int OBEX_CharToUnicode(uint8_t *uc, const uint8_t *c, int size)
260 {
261 	int len, n;
262 
263 	if (uc == NULL || c == NULL)
264 		return -1;
265 
266 	len = n = strlen((char *) c);
267 	if (n*2+2 > size)
268 		return -1;
269 
270 	uc[n*2+1] = 0;
271 	uc[n*2] = 0;
272 
273 	while (n--) {
274 		uc[n*2+1] = c[n];
275 		uc[n*2] = 0;
276 	}
277 
278 	return (len * 2) + 2;
279 }
280