• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /******************************************************************************
2  *
3  *  Copyright (C) 2009-2012 Broadcom Corporation
4  *
5  *  Licensed under the Apache License, Version 2.0 (the "License");
6  *  you may not use this file except in compliance with the License.
7  *  You may obtain a copy of the License at:
8  *
9  *  http://www.apache.org/licenses/LICENSE-2.0
10  *
11  *  Unless required by applicable law or agreed to in writing, software
12  *  distributed under the License is distributed on an "AS IS" BASIS,
13  *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  *  See the License for the specific language governing permissions and
15  *  limitations under the License.
16  *
17  ******************************************************************************/
18 #include <stdio.h>
19 #include <errno.h>
20 #include <fcntl.h>
21 #include <sys/types.h>
22 #include <sys/stat.h>
23 #include <sys/statfs.h>
24 #include <sys/vfs.h>
25 #include <unistd.h>
26 #include <dirent.h>
27 #include <time.h>
28 #include <limits.h>
29 #include "gki.h"
30 #include "bta_fs_co.h"
31 #include "bta_fs_ci.h"
32 #include <inttypes.h>
33 
34 #ifndef AID_SYSTEM
35 #define AID_SYSTEM        1000
36 #define AID_BLUETOOTH     1002
37 #define AID_SDCARD_RW     1015
38 #define AID_MISC          9998
39 #endif
40 
41 #define FAT_FS 0x4d44
42 const unsigned short BT_UID= AID_BLUETOOTH;
43 const unsigned short BT_GID= AID_BLUETOOTH;
44 
45 /* enable additional debugging traces that should be compiled out by default! */
46 #ifndef BTA_FS_DEBUG
47 #define BTA_FS_DEBUG TRUE
48 #define LOG_TAG  "BTA_FS_CO"
49 #define LOGI(format, ...)  fprintf (stdout, LOG_TAG format"\n", ## __VA_ARGS__)
50 #endif
51 
52 #if (defined BTA_PBS_INCLUDED) && (BTA_PBS_INCLUDED == TRUE)
53 extern const tBTA_PBS_CFG bta_pbs_cfg;
54 #endif
55 
56 
57 
del_path(const char * path)58 static int del_path (const char *path)
59 {
60     DIR *dir;
61     struct dirent *de;
62     int ret = 0;
63     char nameBuffer[PATH_MAX] = {0};
64     struct stat statBuffer;
65     BTIF_TRACE_DEBUG1("in del_path for path:%s", path);
66     dir = opendir(path);
67 
68     if (dir == NULL) {
69         BTIF_TRACE_DEBUG1("opendir failed on path:%s", path);
70         return -1;
71     }
72 
73     char *filenameOffset;
74 
75     strncpy(nameBuffer, path, PATH_MAX - 1);
76     strcat(nameBuffer, "/");
77     int nameLen = strlen(nameBuffer);
78     filenameOffset = nameBuffer + nameLen;
79 
80     for (;;) {
81         de = readdir(dir);
82 
83         if (de == NULL) {
84             BTIF_TRACE_DEBUG1("readdir failed for path:%s", path);
85             //ret = -1;
86             break;
87         }
88 
89         if (0 == strcmp(de->d_name, ".") || 0 == strcmp(de->d_name, ".."))
90            continue;
91 
92         if((int)strlen(de->d_name) > PATH_MAX - nameLen) {
93             BTIF_TRACE_DEBUG1("d_name len:%d is too big", strlen(de->d_name));
94             ret = -1;
95             break;
96         }
97 
98         strcpy(filenameOffset, de->d_name);
99 
100         ret = lstat (nameBuffer, &statBuffer);
101 
102         if (ret != 0) {
103             BTIF_TRACE_DEBUG1("lstat failed for path:%s", nameBuffer);
104             break;
105         }
106 
107         if(S_ISDIR(statBuffer.st_mode)) {
108 
109             ret = del_path(nameBuffer);
110             if(ret != 0)
111                 break;
112         } else {
113             ret = unlink(nameBuffer);
114             if (ret != 0) {
115                 BTIF_TRACE_DEBUG1("unlink failed for path:%s", nameBuffer);
116                 break;
117             }
118         }
119     }
120 
121     closedir(dir);
122     if(ret == 0) {
123         ret = rmdir(path);
124         BTIF_TRACE_DEBUG2("rmdir return:%d for path:%s", ret, path);
125     }
126 
127     return ret;
128 
129 }
130 
getAccess(int accType,struct stat * buffer,char * p_path)131 inline int getAccess(int accType, struct stat *buffer, char *p_path)
132 {
133 
134     struct statfs fsbuffer;
135     int idType;
136 
137     if(! buffer)
138 	return BTA_FS_CO_FAIL;
139 
140     //idType= (buffer->st_uid== BT_UID) ? 1 : (buffer->st_uid== BT_GID) ? 2 : 3;
141     if(buffer->st_uid == BT_UID)
142         idType = 1;
143     else if(buffer->st_gid == BT_GID ||
144             buffer->st_gid == AID_SYSTEM ||
145             buffer->st_gid == AID_MISC ||
146             buffer->st_gid == AID_SDCARD_RW)
147         idType = 2;
148     else idType = 3;
149 
150     if(statfs(p_path, &fsbuffer)==0)
151     {
152         if(fsbuffer.f_type == FAT_FS)
153 	    return BTA_FS_CO_OK;
154     }
155     else {
156         return BTA_FS_CO_FAIL;
157     }
158 
159     switch(accType) {
160         case 4:
161 	if(idType== 1) {	//Id is User Id
162 	   if(buffer-> st_mode & S_IRUSR)
163 	       return BTA_FS_CO_OK;
164 	}
165 	else if(idType==2) {   //Id is Group Id
166 	    if(buffer-> st_mode & S_IRGRP)
167 	       return BTA_FS_CO_OK;
168 	}
169 	else {			//Id is Others
170 	    if(buffer-> st_mode & S_IROTH)
171 	       return BTA_FS_CO_OK;
172 	}
173 	break;
174 
175 	case 6:
176 	if(idType== 1) {	//Id is User Id
177 	   if((buffer-> st_mode & S_IRUSR) && (buffer-> st_mode & S_IWUSR))
178 	       return BTA_FS_CO_OK;
179 	}
180 	else if(idType==2) {   //Id is Group Id
181 	    if((buffer-> st_mode & S_IRGRP) && (buffer-> st_mode & S_IWGRP))
182 	       return BTA_FS_CO_OK;
183 	}
184 	else {			//Id is Others
185 	    if((buffer-> st_mode & S_IROTH) && (buffer-> st_mode & S_IWOTH))
186 	       return BTA_FS_CO_OK;
187 	}
188 	break;
189 
190 	default:
191 	return BTA_FS_CO_OK;
192     }
193     BTIF_TRACE_DEBUG0("*************FTP- Access Failed **********");
194     return BTA_FS_CO_EACCES;
195 }
196 
197 
198 /*****************************************************************************
199 **  Function Declarations
200 *****************************************************************************/
201 
202 /*******************************************************************************
203 **
204 ** Function         bta_fs_convert_oflags
205 **
206 ** Description      This function converts the open flags from BTA into MFS.
207 **
208 ** Returns          BTA FS status value.
209 **
210 *******************************************************************************/
bta_fs_convert_bta_oflags(int bta_oflags)211 int bta_fs_convert_bta_oflags(int bta_oflags)
212 {
213     int oflags = 0; /* Initially read only */
214 
215     /* Only one of these can be set: Read Only, Read/Write, or Write Only */
216     if (bta_oflags & BTA_FS_O_RDWR)
217         oflags |= O_RDWR;
218     else if (bta_oflags & BTA_FS_O_WRONLY)
219         oflags |= O_WRONLY;
220 
221     /* OR in any other flags that are set by BTA */
222     if (bta_oflags & BTA_FS_O_CREAT)
223         oflags |= O_CREAT;
224 
225     if (bta_oflags & BTA_FS_O_EXCL)
226         oflags |= O_EXCL;
227 
228     if (bta_oflags & BTA_FS_O_TRUNC)
229         oflags |= O_TRUNC;
230 
231     return (oflags);
232 }
233 
234 
235 
236 /*******************************************************************************
237  **
238  ** Function        btapp_fs_check_space
239  **
240  ** Description     determines access and if there is enough space for given files size on given path
241  **
242  ** Parameters      p_path  - Fully qualified path and file name.
243  **                           WARNING: file name is stripped off! so it must be present!
244  **                 size    - size of file to put (0 if unavailable or not applicable)
245  **                 app_id  - in case application specific treatement is required (e.g opp versus ftp)
246  ** Returns         0 if enough space, otherwise errno failure codes
247  **
248  *******************************************************************************/
btapp_fs_check_space(const char * p_path,const UINT32 size,const UINT8 app_id)249 static int btapp_fs_check_space( const char *p_path, const UINT32 size, const UINT8 app_id )
250 {
251 
252     unsigned long long max_space;
253     struct statfs fs_buffer;
254     int err = 0;
255     char *p_dir;
256     char *p_end;
257 
258     if(size==BTA_FS_LEN_UNKNOWN)
259         return 0;
260     /* fail silently in case of no memory. write will catch if not enough space */
261 
262     if (NULL != (p_dir = (char *) GKI_getbuf(strlen(p_path) + 1)))
263     {
264         strcpy(p_dir, p_path);
265         if (NULL != (p_end = strrchr(p_dir, '/')))
266         {
267 
268             *p_end = '\0';
269             /* get fs info and calculate available space. if not enough, the fs error EFBIG is returned */
270 
271             if (0 == statfs(p_dir, &fs_buffer))
272             {
273 
274                 max_space = fs_buffer.f_bavail * fs_buffer.f_bsize;
275 #if (BTA_FS_DEBUG==TRUE)
276                 BTIF_TRACE_DEBUG2("btapp_fs_enough_space(file size: %d): (uint)max_size: %u", size, (UINT32)max_space);
277 #endif
278                 if (max_space < size)
279                     err = EFBIG;
280             }
281             else
282             {
283                 err = errno;
284                 BTIF_TRACE_WARNING1("btapp_fs_enough_space(): statfs() failed with err: %d", err);
285             }
286         }
287         else
288         {
289             err = ENOENT;
290         }
291         GKI_freebuf(p_dir);
292     }
293     else
294     {
295         err = ENOMEM;
296     }
297     return err;
298 
299 } /* btapp_fs_check_access_space() */
300 
301 
302 /*******************************************************************************
303 **
304 ** Function         bta_fs_co_open
305 **
306 ** Description      This function is executed by BTA when a file is opened.
307 **                  The phone uses this function to open
308 **                  a file for reading or writing.
309 **
310 ** Parameters       p_path  - Fully qualified path and file name.
311 **                  oflags  - permissions and mode (see constants above)
312 **                  size    - size of file to put (0 if unavailable or not applicable)
313 **                  evt     - event that must be passed into the call-in function.
314 **                  app_id  - application ID specified in the enable functions.
315 **                            It can be used to identify which profile is the caller
316 **                            of the call-out function.
317 **
318 ** Returns          void
319 **
320 **                  Note: Upon completion of the request, a file descriptor (int),
321 **                        if successful, and an error code (tBTA_FS_CO_STATUS)
322 **                        are returned in the call-in function, bta_fs_ci_open().
323 **
324 *******************************************************************************/
325 
bta_fs_co_open(const char * p_path,int oflags,UINT32 size,UINT16 evt,UINT8 app_id)326 void bta_fs_co_open(const char *p_path, int oflags, UINT32 size, UINT16 evt,
327                     UINT8 app_id)
328 {
329 
330     tBTA_FS_CO_STATUS  status;
331     UINT32  file_size = 0;
332     struct  stat file_stat;
333     int fd = -1;
334     int err = 0;
335 
336     /* Convert BTA oflags into os specific flags */
337     oflags = bta_fs_convert_bta_oflags(oflags);
338 
339     /* check available space in case of write access. oflags are in OS format! */
340     if (oflags & (O_RDWR|O_WRONLY))
341     {
342         err = btapp_fs_check_space(p_path, size, app_id);
343     }
344 
345     if ( 0==err )
346     {
347         if ((fd = open(p_path, oflags | O_NONBLOCK, 0666)) >= 0)
348         {
349             if (fstat(fd, &file_stat) == 0)
350             {
351                 file_size = file_stat.st_size;
352                 if (oflags & O_CREAT)
353                 {
354                     fchown(fd, BT_UID, BT_GID);
355                     BTIF_TRACE_DEBUG0("\n ******CHANGED OWNERSHIP SUCCESSFULLY**********");
356                 }
357             }
358         }
359 
360         else
361         {
362             err = errno;
363         }
364     }
365 
366     BTIF_TRACE_DEBUG4("[CO] bta_fs_co_open: handle:%d err:%d, flags:%x, app id:%d",
367             fd, err, oflags, app_id);
368     BTIF_TRACE_DEBUG1("file=%s", p_path);
369 
370     /* convert fs error into bta_fs err. erro is set by first call to enough space to a valid value
371      * and needs only updating in case of error. This reports correct failure to remote obex! */
372 
373     switch (err)
374     {
375 
376     case 0:
377         status = BTA_FS_CO_OK;
378         break;
379     case EACCES:
380         status = BTA_FS_CO_EACCES;
381         break;
382     case EFBIG: /* file to big for available fs space */
383         status = BTA_FS_CO_ENOSPACE;
384         break;
385     default:
386         status = BTA_FS_CO_FAIL;
387         break;
388     }
389     bta_fs_ci_open(fd, status, file_size, evt);
390 }
391 
392 /*******************************************************************************
393 **
394 ** Function         bta_fs_co_close
395 **
396 ** Description      This function is called by BTA when a connection to a
397 **                  client is closed.
398 **
399 ** Parameters       fd      - file descriptor of file to close.
400 **                  app_id  - application ID specified in the enable functions.
401 **                            It can be used to identify which profile is the caller
402 **                            of the call-out function.
403 **
404 ** Returns          (tBTA_FS_CO_STATUS) status of the call.
405 **                      [BTA_FS_CO_OK if successful],
406 **                      [BTA_FS_CO_FAIL if failed  ]
407 **
408 *******************************************************************************/
bta_fs_co_close(int fd,UINT8 app_id)409 tBTA_FS_CO_STATUS bta_fs_co_close(int fd, UINT8 app_id)
410 {
411     tBTA_FS_CO_STATUS status = BTA_FS_CO_OK;
412     int err;
413 
414     BTIF_TRACE_DEBUG2("[CO] bta_fs_co_close: handle:%d, app id:%d",
415         fd, app_id);
416     if (close (fd) < 0)
417     {
418         err = errno;
419         status = BTA_FS_CO_FAIL;
420         BTIF_TRACE_WARNING3("[CO] bta_fs_co_close: handle:%d error=%d app_id:%d", fd, err, app_id);
421     }
422 
423     return (status);
424 }
425 
426 /*******************************************************************************
427 **
428 ** Function         bta_fs_co_read
429 **
430 ** Description      This function is called by BTA to read in data from the
431 **                  previously opened file on the phone.
432 **
433 ** Parameters       fd      - file descriptor of file to read from.
434 **                  p_buf   - buffer to read the data into.
435 **                  nbytes  - number of bytes to read into the buffer.
436 **                  evt     - event that must be passed into the call-in function.
437 **                  ssn     - session sequence number. Ignored, if bta_fs_co_open
438 **							  was not called with BTA_FS_CO_RELIABLE.
439 **                  app_id  - application ID specified in the enable functions.
440 **                            It can be used to identify which profile is the caller
441 **                            of the call-out function.
442 **
443 ** Returns          void
444 **
445 **                  Note: Upon completion of the request, bta_fs_ci_read() is
446 **                        called with the buffer of data, along with the number
447 **                        of bytes read into the buffer, and a status.  The
448 **                        call-in function should only be called when ALL requested
449 **                        bytes have been read, the end of file has been detected,
450 **                        or an error has occurred.
451 **
452 *******************************************************************************/
bta_fs_co_read(int fd,UINT8 * p_buf,UINT16 nbytes,UINT16 evt,UINT8 ssn,UINT8 app_id)453 void bta_fs_co_read(int fd, UINT8 *p_buf, UINT16 nbytes, UINT16 evt, UINT8 ssn, UINT8 app_id)
454 {
455     tBTA_FS_CO_STATUS  status = BTA_FS_CO_OK;
456     INT32   num_read;
457     int     err;
458 
459     if ((num_read = read (fd, p_buf, nbytes)) < 0)
460     {
461         err = errno;
462         status = BTA_FS_CO_FAIL;
463         BTIF_TRACE_WARNING3("[CO] bta_fs_co_read: handle:%d error=%d app_id:%d",
464                             fd, err, app_id);
465     }
466     else if (num_read < nbytes)
467         status = BTA_FS_CO_EOF;
468 
469     bta_fs_ci_read(fd, (UINT16)num_read, status, evt);
470 }
471 
472 /*******************************************************************************
473 **
474 ** Function         bta_fs_co_write
475 **
476 ** Description      This function is called by io to send file data to the
477 **                  phone.
478 **
479 ** Parameters       fd      - file descriptor of file to write to.
480 **                  p_buf   - buffer to read the data from.
481 **                  nbytes  - number of bytes to write out to the file.
482 **                  evt     - event that must be passed into the call-in function.
483 **                  ssn     - session sequence number. Ignored, if bta_fs_co_open
484 **							  was not called with BTA_FS_CO_RELIABLE.
485 **                  app_id  - application ID specified in the enable functions.
486 **                            It can be used to identify which profile is the caller
487 **                            of the call-out function.
488 **
489 ** Returns          void
490 **
491 **                  Note: Upon completion of the request, bta_fs_ci_write() is
492 **                        called with the file descriptor and the status.  The
493 **                        call-in function should only be called when ALL requested
494 **                        bytes have been written, or an error has been detected,
495 **
496 *******************************************************************************/
bta_fs_co_write(int fd,const UINT8 * p_buf,UINT16 nbytes,UINT16 evt,UINT8 ssn,UINT8 app_id)497 void bta_fs_co_write(int fd, const UINT8 *p_buf, UINT16 nbytes, UINT16 evt,
498                      UINT8 ssn, UINT8 app_id)
499 {
500     tBTA_FS_CO_STATUS  status = BTA_FS_CO_OK;
501     INT32   num_written;
502     int     err=0;
503 
504     if ((num_written = write (fd, p_buf, nbytes)) < 0)
505     {
506         err = errno;
507         status = BTA_FS_CO_FAIL;
508     }
509 /*    BTIF_TRACE_DEBUG3("[CO] bta_fs_co_write: handle:%d error=%d, num_written:%d", fd, err, num_written);*/
510 
511     bta_fs_ci_write(fd, status, evt);
512 }
513 
514 /*******************************************************************************
515 **
516 ** Function         bta_fs_co_seek
517 **
518 ** Description      This function is called by io to move the file pointer
519 **                  of a previously opened file to the specified location for
520 **                  the next read or write operation.
521 **
522 ** Parameters       fd      - file descriptor of file.
523 **                  offset  - Number of bytes from origin.
524 **                  origin  - Initial position.
525 **
526 ** Returns          void
527 **
528 *******************************************************************************/
bta_fs_co_seek(int fd,INT32 offset,INT16 origin,UINT8 app_id)529 void bta_fs_co_seek (int fd, INT32 offset, INT16 origin, UINT8 app_id)
530 {
531     lseek(fd, offset, origin);
532 }
533 
534 /*******************************************************************************
535 **
536 ** Function         bta_fs_co_access
537 **
538 ** Description      This function is called to check the existence of
539 **                  a file or directory, and return whether or not it is a
540 **                  directory or length of the file.
541 **
542 ** Parameters       p_path   - (input) file or directory to access (fully qualified path).
543 **                  mode     - (input) [BTA_FS_ACC_EXIST, BTA_FS_ACC_READ, or BTA_FS_ACC_RDWR]
544 **                  p_is_dir - (output) returns TRUE if p_path specifies a directory.
545 **                  app_id   - (input) application ID specified in the enable functions.
546 **                                     It can be used to identify which profile is the caller
547 **                                     of the call-out function.
548 **
549 ** Returns          (tBTA_FS_CO_STATUS) status of the call.
550 **                   [BTA_FS_CO_OK if it exists]
551 **                   [BTA_FS_CO_EACCES if permissions are wrong]
552 **                   [BTA_FS_CO_FAIL if it does not exist]
553 **
554 *******************************************************************************/
bta_fs_co_access(const char * p_path,int mode,BOOLEAN * p_is_dir,UINT8 app_id)555 tBTA_FS_CO_STATUS bta_fs_co_access(const char *p_path, int mode, BOOLEAN *p_is_dir,
556                                    UINT8 app_id)
557 {
558     int err;
559     int os_mode = 0;
560     tBTA_FS_CO_STATUS status = BTA_FS_CO_OK;
561     struct stat buffer;
562 
563     #if (TRUE==BTA_FS_DEBUG)
564     LOGI("***********CHECKING ACCESS TO = %s", p_path);
565     #endif
566 
567     #if (defined BTA_PBS_INCLUDED) && (BTA_PBS_INCLUDED == TRUE)
568 
569     if (app_id == UI_PBS_ID)
570     {
571 
572         *p_is_dir = TRUE;
573 
574         #if (TRUE==BTA_FS_DEBUG)
575         LOGI("***********SUPPORTED REPO = %d", bta_pbs_cfg.supported_repositories);
576         #endif
577         //Check if SIM contact requested,  and if so if it's supported.
578         //If not, return error!
579         if (strstr(p_path,"SIM1") && !(bta_pbs_cfg.supported_repositories & 0x2)) {
580             LOGI("***********RETURNING FAIL!");
581             return BTA_FS_CO_FAIL;
582         }
583 
584         #if (TRUE==BTA_FS_DEBUG)
585         LOGI("***********RETURNING success!");
586         #endif
587         return (status);
588     }
589     #endif
590 
591 
592     *p_is_dir = FALSE;
593 
594     if (mode == BTA_FS_ACC_RDWR)
595         os_mode = 6;
596     else if (mode == BTA_FS_ACC_READ)
597         os_mode = 4;
598 
599     if (stat(p_path, &buffer) == 0)
600     {
601 	/* Determine if the object is a file or directory */
602         if (S_ISDIR(buffer.st_mode))
603             *p_is_dir = TRUE;
604     }
605     else
606     {
607 	BTIF_TRACE_DEBUG0("stat() failed! ");
608         return BTA_FS_CO_FAIL;
609     }
610 
611     status=getAccess (os_mode, &buffer, (char*)p_path);
612     return (status);
613 }
614 
615 /*******************************************************************************
616 **
617 ** Function         bta_fs_co_mkdir
618 **
619 ** Description      This function is called to create a directory with
620 **                  the pathname given by path. The pathname is a null terminated
621 **                  string. All components of the path must already exist.
622 **
623 ** Parameters       p_path   - (input) name of directory to create (fully qualified path).
624 **                  app_id   - (input) application ID specified in the enable functions.
625 **                                     It can be used to identify which profile is the caller
626 **                                     of the call-out function.
627 **
628 ** Returns          (tBTA_FS_CO_STATUS) status of the call.
629 **                  [BTA_FS_CO_OK if successful]
630 **                  [BTA_FS_CO_FAIL if unsuccessful]
631 **
632 *******************************************************************************/
bta_fs_co_mkdir(const char * p_path,UINT8 app_id)633 tBTA_FS_CO_STATUS bta_fs_co_mkdir(const char *p_path, UINT8 app_id)
634 {
635     int err;
636     tBTA_FS_CO_STATUS status = BTA_FS_CO_OK;
637 
638     if ((mkdir (p_path, 0666)) != 0)
639     {
640         err = errno;
641         status = BTA_FS_CO_FAIL;
642         BTIF_TRACE_WARNING3("[CO] bta_fs_co_mkdir: error=%d, path [%s] app_id:%d",
643                             err, p_path, app_id);
644     }
645     return (status);
646 }
647 
648 /*******************************************************************************
649 **
650 ** Function         bta_fs_co_rmdir
651 **
652 ** Description      This function is called to remove a directory whose
653 **                  name is given by path. The directory must be empty.
654 **
655 ** Parameters       p_path   - (input) name of directory to remove (fully qualified path).
656 **                  app_id   - (input) application ID specified in the enable functions.
657 **                                     It can be used to identify which profile is the caller
658 **                                     of the call-out function.
659 **
660 ** Returns          (tBTA_FS_CO_STATUS) status of the call.
661 **                      [BTA_FS_CO_OK if successful]
662 **                      [BTA_FS_CO_EACCES if read-only]
663 **                      [BTA_FS_CO_ENOTEMPTY if directory is not empty]
664 **                      [BTA_FS_CO_FAIL otherwise]
665 **
666 *******************************************************************************/
bta_fs_co_rmdir(const char * p_path,UINT8 app_id)667 tBTA_FS_CO_STATUS bta_fs_co_rmdir(const char *p_path, UINT8 app_id)
668 {
669     int err, path_len;
670     tBTA_FS_CO_STATUS status = BTA_FS_CO_OK;
671     struct stat buffer;
672     char *dirName, *tmp = NULL;
673 
674     path_len = strlen( p_path )+1;
675     BTIF_TRACE_DEBUG2( "bta_fs_co_rmdir( app_id: %d ): path_len: %d", app_id, path_len );
676 #if (TRUE==BTA_FS_DEBUG)
677     BTIF_TRACE_DEBUG1( "bta_fs_co_rmdir():path_len: %d, p_path", app_id );
678     BTIF_TRACE_DEBUG0( p_path );
679 #endif
680 
681     /* allocate a temp buffer for path with 0 char. make sure not to crash if path is too big! */
682     dirName = (char*) calloc(1, path_len+1);
683     if ( NULL != dirName )
684     {
685         strcpy( dirName, p_path );
686     }
687     else
688     {
689         BTIF_TRACE_WARNING2( "bta_fs_co_rmdir( app_id: %d ) for path_len: %d::out of memory",
690                              app_id, path_len );
691         return BTA_FS_CO_FAIL;
692     }
693 
694     if (NULL!= (tmp = strrchr(dirName, '/')))
695     {
696         *tmp = '\0';
697     }
698     if (stat(dirName, &buffer) == 0)
699     {
700         status = getAccess(6, &buffer, dirName);
701     }
702     else
703     {
704         free(dirName);
705 #if (TRUE==BTA_FS_DEBUG)
706         BTIF_TRACE_WARNING0( "bta_fs_co_rmdir()::stat(dirName) failed" );
707 #endif
708         return BTA_FS_CO_FAIL;
709     }
710 
711     free(dirName);
712     if (status != BTA_FS_CO_OK)
713     {
714 #if (TRUE==BTA_FS_DEBUG)
715         BTIF_TRACE_WARNING0( "bta_fs_co_rmdir()::getAccess(dirName) FAILED");
716 #endif
717         return status;
718     }
719 
720     if (stat(p_path, &buffer) == 0)
721     {
722         status = getAccess(6, &buffer, (char*)p_path);
723     }
724     else
725     {
726 #if (TRUE==BTA_FS_DEBUG)
727         BTIF_TRACE_WARNING0( "bta_fs_co_rmdir()::stat(p_path) FAILED");
728 #endif
729         return BTA_FS_CO_FAIL;
730     }
731 
732     if (status != BTA_FS_CO_OK)
733     {
734 #if (TRUE==BTA_FS_DEBUG)
735         BTIF_TRACE_DEBUG0( "bta_fs_co_rmdir()::getAccess(p_path) FAILED");
736 #endif
737         return status;
738     }
739     //if ((rmdir (p_path)) != 0)
740     if (del_path(p_path) != 0)
741     {
742         err = errno;
743         BTIF_TRACE_WARNING1( "bta_fs_co_rmdir():rmdir/del_path FAILED with err: %d", err );
744         if (err == EACCES)
745             status = BTA_FS_CO_EACCES;
746         else if (err == ENOTEMPTY)
747             status = BTA_FS_CO_ENOTEMPTY;
748         else
749             status = BTA_FS_CO_FAIL;
750     }
751     return (status);
752 }
753 
754 /*******************************************************************************
755 **
756 ** Function         bta_fs_co_unlink
757 **
758 ** Description      This function is called to remove a file whose name
759 **                  is given by p_path.
760 **
761 ** Parameters       p_path   - (input) name of file to remove (fully qualified path).
762 **                  app_id   - (input) application ID specified in the enable functions.
763 **                                     It can be used to identify which profile is the caller
764 **                                     of the call-out function.
765 **
766 ** Returns          (tBTA_FS_CO_STATUS) status of the call.
767 **                      [BTA_FS_CO_OK if successful]
768 **                      [BTA_FS_CO_EACCES if read-only]
769 **                      [BTA_FS_CO_FAIL otherwise]
770 **
771 *******************************************************************************/
bta_fs_co_unlink(const char * p_path,UINT8 app_id)772 tBTA_FS_CO_STATUS bta_fs_co_unlink(const char *p_path, UINT8 app_id)
773 {
774     BTIF_TRACE_DEBUG0("bta_fs_co_unlink");
775     int err;
776     tBTA_FS_CO_STATUS status = BTA_FS_CO_OK;
777     char *dirName, *tmp=NULL;
778     struct stat buffer;
779 
780     if(! p_path)
781         return BTA_FS_CO_FAIL;
782 
783     /* buffer needs to be NULL terminated - so add one more byte to be zero'd out */
784 #if 0
785     dirName= (char*) calloc(1, strlen(p_path));  /* <--- this can cause problems  */
786 #else
787     dirName= (char*) calloc(1, strlen(p_path) + 1);
788 #endif
789 
790     strncpy(dirName, p_path, strlen(p_path));
791     if((tmp=strrchr(dirName, '/')))
792     {
793 	    *tmp='\0';
794     }
795     if (stat(dirName, &buffer) == 0)
796     {
797         status=getAccess (6, &buffer, dirName);
798         free(dirName);
799     }
800     else
801     {
802         BTIF_TRACE_DEBUG0("stat() failed! ");
803         free(dirName);
804         return BTA_FS_CO_FAIL;
805     }
806 
807     if(status!= BTA_FS_CO_OK)
808 	return status;
809 
810     if ((unlink (p_path)) != 0)
811     {
812         err = errno;
813         if (err == EACCES)
814             status = BTA_FS_CO_EACCES;
815         else
816             status = BTA_FS_CO_FAIL;
817     }
818     return (status);
819 
820 }
821 
822 /*******************************************************************************
823 **
824 ** Function         bta_fs_co_getdirentry
825 **
826 ** Description      This function is called to get a directory entry for the
827 **                  specified p_path.  The first/next directory should be filled
828 **                  into the location specified by p_entry.
829 **
830 ** Parameters       p_path      - directory to search (Fully qualified path)
831 **                  first_item  - TRUE if first search, FALSE if next search
832 **                                      (p_cur contains previous)
833 **                  p_entry (input/output) - Points to last entry data (valid when
834 **                                           first_item is FALSE)
835 **                  evt     - event that must be passed into the call-in function.
836 **                  app_id  - application ID specified in the enable functions.
837 **                            It can be used to identify which profile is the caller
838 **                            of the call-out function.
839 **
840 ** Returns          void
841 **
842 **                  Note: Upon completion of the request, the status is passed
843 **                        in the bta_fs_ci_direntry() call-in function.
844 **                        BTA_FS_CO_OK is returned when p_entry is valid,
845 **                        BTA_FS_CO_EODIR is returned when no more entries [finished]
846 **                        BTA_FS_CO_FAIL is returned if an error occurred
847 **
848 *******************************************************************************/
bta_fs_co_getdirentry(const char * p_path,BOOLEAN first_item,tBTA_FS_DIRENTRY * p_entry,UINT16 evt,UINT8 app_id)849 void bta_fs_co_getdirentry(const char *p_path, BOOLEAN first_item,
850                            tBTA_FS_DIRENTRY *p_entry, UINT16 evt, UINT8 app_id)
851 {
852     tBTA_FS_CO_STATUS    co_status = BTA_FS_CO_FAIL;
853     int                  status = -1;    /* '0' - success, '-1' - fail */
854     struct tm           *p_tm;
855     DIR *dir;
856     struct dirent *dirent;
857     struct stat buf;
858     char fullname[500];
859 
860     BTIF_TRACE_DEBUG0("Entered bta_fs_co_getdirentry");
861 
862     /* First item is to be retrieved */
863     if (first_item)
864     {
865         BTIF_TRACE_DEBUG1("bta_fs_co_getdirentry: path = %s", p_path);
866 
867         dir = opendir(p_path);
868         if(dir == NULL)
869         {
870      	    BTIF_TRACE_DEBUG1("bta_fs_co_getdirentry: dir is NULL so error out with errno=%d", errno);
871             co_status = BTA_FS_CO_EODIR;
872             bta_fs_ci_direntry(co_status, evt);
873             return;
874         }
875 
876         BTIF_TRACE_DEBUG1("bta_fs_co_getdirentry: dir = %p", dir);
877         if((dirent = readdir(dir)) != NULL)
878         {
879             p_entry->refdata = (UINT32) dir;     /* Save this for future searches */
880             status = 0;
881             BTIF_TRACE_DEBUG1("bta_fs_co_getdirentry: dirent = %p", dirent);
882         }
883         else
884         {
885             BTIF_TRACE_DEBUG1("bta_fs_co_getdirentry: dirent = %p", dirent);
886             /* Close the search if there are no more items */
887             closedir( (DIR*) p_entry->refdata);
888             co_status = BTA_FS_CO_EODIR;
889         }
890     }
891     else    /* Get the next entry based on the p_ref data from previous search */
892     {
893         if ((dirent = readdir((DIR*)p_entry->refdata))  == NULL)
894         {
895             /* Close the search if there are no more items */
896             closedir( (DIR*) p_entry->refdata);
897             co_status = BTA_FS_CO_EODIR;
898             BTIF_TRACE_DEBUG1("bta_fs_co_getdirentry: dirent = %p", dirent);
899         }
900         else
901         {
902             BTIF_TRACE_DEBUG1("bta_fs_co_getdirentry: dirent = %p", dirent);
903             status = 0;
904         }
905     }
906 
907     if (status == 0)
908     {
909         BTIF_TRACE_DEBUG0("bta_fs_co_getdirentry: status = 0");
910 
911         sprintf(fullname, "%s/%s", p_path,  dirent->d_name);
912 
913         /* Load new values into the return structure (refdata is left untouched) */
914         if (stat(fullname, &buf) == 0) {
915             p_entry->filesize = buf.st_size;
916             p_entry->mode = 0; /* Default is normal read/write file access */
917 
918             if (S_ISDIR(buf.st_mode))
919                 p_entry->mode |= BTA_FS_A_DIR;
920             else
921                 p_entry->mode |= BTA_FS_A_RDONLY;
922 
923             strcpy(p_entry->p_name, dirent->d_name);
924 #if 0
925             fprintf(stderr, "bta_fs_co_getdirentry(): %s %9d %d\n",
926                             dirent->d_name,
927                             buf.st_size,
928                             p_entry->mode);
929 #endif
930             p_tm = localtime((const time_t*)&buf.st_mtime);
931             if (p_tm != NULL)
932             {
933                 sprintf(p_entry->crtime, "%04d%02d%02dT%02d%02d%02dZ",
934                         p_tm->tm_year + 1900,   /* Base Year ISO 6201 */
935                         p_tm->tm_mon + 1,       /* month starts at 0 */
936                         p_tm->tm_mday,
937                         p_tm->tm_hour,
938                         p_tm->tm_min,
939                         p_tm->tm_sec);
940             }
941             else
942                 p_entry->crtime[0] = '\0';  /* No valid time */
943 #if 0
944             fprintf(stderr, "bta_fs_co_getdirentry(): %s %9d %d %s\n",
945                             dirent->d_name,
946                             p_entry->filesize,
947                             p_entry->mode,
948                             p_entry->crtime);
949 #endif
950             co_status = BTA_FS_CO_OK;
951         } else {
952             BTIF_TRACE_WARNING0("stat() failed! ");
953             co_status = BTA_FS_CO_EACCES;
954         }
955     }
956     BTIF_TRACE_DEBUG0("bta_fs_co_getdirentry: calling bta_fs_ci_getdirentry");
957 
958     bta_fs_ci_direntry(co_status, evt);
959 }
960 
961 
962 
963 
964 /*******************************************************************************
965 **
966 ** Function         bta_fs_co_setdir
967 **
968 ** Description      This function is executed by BTA when the server changes the
969 **                  local path
970 **
971 ** Parameters       p_path  - the new path.
972 **                  app_id  - application ID specified in the enable functions.
973 **                            It can be used to identify which profile is the caller
974 **                            of the call-out function.
975 **
976 ** Returns          void
977 **
978 *******************************************************************************/
bta_fs_co_setdir(const char * p_path,UINT8 app_id)979 void bta_fs_co_setdir(const char *p_path, UINT8 app_id)
980 {
981     BTIF_TRACE_DEBUG2("Entered %s. New path: %s", __FUNCTION__, p_path);
982 }
983 
984 /*******************************************************************************
985 ** OBEX14 Reliable Session not supported. Stub associated callouts.
986 ******************************************************************************/
987 
988 /*******************************************************************************
989 **
990 ** Function         bta_fs_co_resume
991 **
992 ** Description      This function is executed by BTA when resuming a session.
993 **                  This is used to retrieve the session ID and related information
994 **
995 ** Parameters       evt     - event that must be passed into the call-in function.
996 **                  app_id  - application ID specified in the enable functions.
997 **                            It can be used to identify which profile is the caller
998 **                            of the call-out function.
999 **
1000 ** Returns          void
1001 **
1002 **                  Note: Upon completion of the request, the related session information,
1003 **                        if successful, and an error code (tBTA_FS_CO_STATUS)
1004 **                        are returned in the call-in function, bta_fs_ci_resume().
1005 **
1006 *******************************************************************************/
bta_fs_co_resume(UINT16 evt,UINT8 app_id)1007 void bta_fs_co_resume(UINT16 evt, UINT8 app_id)
1008 {
1009     BTIF_TRACE_WARNING0("[CO] bta_fs_co_resume - NOT implemented");
1010 }
1011 
1012 /*******************************************************************************
1013 **
1014 ** Function         bta_fs_co_set_perms
1015 **
1016 ** Description      This function is called to set the permission a file/directory
1017 **                  with name as p_src_path.
1018 **
1019 ** Parameters       p_src_path  - (input) name of file/directory to set permission (fully qualified path).
1020 **                  p_perms     - the permission .
1021 **                  app_id   - (input) application ID specified in the enable functions.
1022 **                                     It can be used to identify which profile is the caller
1023 **                                     of the call-out function.
1024 **
1025 ** Returns          (tBTA_FS_CO_STATUS) status of the call.
1026 **                      [BTA_FS_CO_OK if successful]
1027 **                      [BTA_FS_CO_EACCES if p_dest_path already exists or could not be created (invalid path);
1028 **                                        or p_src_path is a directory and p_dest_path specifies a different path. ]
1029 **                      [BTA_FS_CO_FAIL otherwise]
1030 **
1031 *******************************************************************************/
bta_fs_co_set_perms(const char * p_src_path,UINT8 * p_perms,UINT16 evt,UINT8 app_id)1032 void bta_fs_co_set_perms(const char *p_src_path,  UINT8 *p_perms, UINT16 evt, UINT8 app_id)
1033 {
1034     BTIF_TRACE_WARNING0("[CO] bta_fs_co_set_perms - NOT implemented");
1035 }
1036 
1037 /*******************************************************************************
1038 **
1039 ** Function         bta_fs_co_rename
1040 **
1041 ** Description      This function is called to move a file/directory whose
1042 **                  name is given by p_src_path to p_dest_path.
1043 **
1044 ** Parameters       p_src_path  - (input) name of file/directory to be moved (fully qualified path).
1045 **                  p_dest_path - (input) new name of file/directory(fully qualified path).
1046 **                  p_perms     - the permission of the new object.
1047 **                  app_id   - (input) application ID specified in the enable functions.
1048 **                                     It can be used to identify which profile is the caller
1049 **                                     of the call-out function.
1050 **
1051 ** Returns          (tBTA_FS_CO_STATUS) status of the call.
1052 **                      [BTA_FS_CO_OK if successful]
1053 **                      [BTA_FS_CO_EACCES if p_dest_path already exists or could not be created (invalid path);
1054 **                                        or p_src_path is a directory and p_dest_path specifies a different path. ]
1055 **                      [BTA_FS_CO_FAIL otherwise]
1056 **
1057 *******************************************************************************/
bta_fs_co_rename(const char * p_src_path,const char * p_dest_path,UINT8 * p_perms,UINT16 evt,UINT8 app_id)1058 void bta_fs_co_rename(const char *p_src_path, const char *p_dest_path, UINT8 *p_perms, UINT16 evt, UINT8 app_id)
1059 {
1060     BTIF_TRACE_WARNING0("[CO] bta_fs_co_rename - NOT implemented");
1061 }
1062 
1063 /*******************************************************************************
1064 **
1065 ** Function         bta_fs_co_copy
1066 **
1067 ** Description      This function is called to copy a file/directory whose
1068 **                  name is given by p_src_path to p_dest_path.
1069 **
1070 ** Parameters       p_src_path  - (input) name of file/directory to be copied (fully qualified path).
1071 **                  p_dest_path - (input) new name of file/directory(fully qualified path).
1072 **                  p_perms     - the permission of the new object.
1073 **                  evt     - event that must be passed into the call-in function.
1074 **                  app_id   - (input) application ID specified in the enable functions.
1075 **                                     It can be used to identify which profile is the caller
1076 **                                     of the call-out function.
1077 **
1078 ** Returns          (tBTA_FS_CO_STATUS) status of the call.
1079 **                      [BTA_FS_CO_OK if successful]
1080 **                      [BTA_FS_CO_EIS_DIR if p_src_path is a folder]
1081 **                      [BTA_FS_CO_EACCES if p_dest_path already exists or could not be created (invalid path);
1082 **                                        or p_src_path is a directory and p_dest_path specifies a different path. ]
1083 **                      [BTA_FS_CO_FAIL otherwise]
1084 **
1085 *******************************************************************************/
bta_fs_co_copy(const char * p_src_path,const char * p_dest_path,UINT8 * p_perms,UINT16 evt,UINT8 app_id)1086 void bta_fs_co_copy(const char *p_src_path, const char *p_dest_path, UINT8 *p_perms, UINT16 evt, UINT8 app_id)
1087 {
1088     BTIF_TRACE_WARNING0("[CO] bta_fs_co_copy - NOT implemented");
1089 }
1090 
1091 /*******************************************************************************
1092 **
1093 ** Function         bta_fs_co_resume_op
1094 **
1095 ** Description      This function is executed by BTA when a reliable session is
1096 **                  resumed and there was an interrupted operation.
1097 **
1098 ** Parameters       offset  - the session ID and related information.
1099 **                  evt     - event that must be passed into the call-in function.
1100 **                  app_id  - application ID specified in the enable functions.
1101 **                            It can be used to identify which profile is the caller
1102 **                            of the call-out function.
1103 **
1104 ** Returns          void
1105 **
1106 *******************************************************************************/
bta_fs_co_resume_op(UINT32 offset,UINT16 evt,UINT8 app_id)1107 void bta_fs_co_resume_op(UINT32 offset, UINT16 evt, UINT8 app_id)
1108 {
1109     BTIF_TRACE_WARNING0("[CO] bta_fs_co_resume_op - NOT implemented");
1110 }
1111 
1112 
1113 /*******************************************************************************
1114 **
1115 ** Function         bta_fs_co_session_info
1116 **
1117 ** Description      This function is executed by BTA when a reliable session is
1118 **                  established (p_sess_info != NULL) or ended (p_sess_info == NULL).
1119 **
1120 ** Parameters       bd_addr     - the peer address
1121 **                  p_sess_info - the session ID and related information.
1122 **                  app_id  - application ID specified in the enable functions.
1123 **                            It can be used to identify which profile is the caller
1124 **                            of the call-out function.
1125 **
1126 ** Returns          void
1127 **
1128 *******************************************************************************/
bta_fs_co_session_info(BD_ADDR bd_addr,UINT8 * p_sess_info,UINT8 ssn,tBTA_FS_CO_SESS_ST new_st,char * p_path,UINT8 * p_info,UINT8 app_id)1129 void bta_fs_co_session_info(BD_ADDR bd_addr, UINT8 *p_sess_info, UINT8 ssn,
1130                                            tBTA_FS_CO_SESS_ST new_st, char *p_path, UINT8 *p_info, UINT8 app_id)
1131 {
1132     BTIF_TRACE_WARNING0("[CO] bta_fs_co_session_info - NOT implemented");
1133 }
1134 
1135 
1136 /*******************************************************************************
1137 **
1138 ** Function         bta_fs_co_suspend
1139 **
1140 ** Description      This function is executed by BTA when a reliable session is
1141 **                  suspended.
1142 **
1143 ** Parameters       bd_addr - the peer address
1144 **                  ssn     - the session sequence number.
1145 **                  info    - the BTA specific information (like last active operation).
1146 **                  p_offset- the location to receive object offset of the suspended session
1147 **                  app_id  - application ID specified in the enable functions.
1148 **                            It can be used to identify which profile is the caller
1149 **                            of the call-out function.
1150 **
1151 ** Returns          void
1152 **
1153 *******************************************************************************/
bta_fs_co_suspend(BD_ADDR bd_addr,UINT8 * p_sess_info,UINT8 ssn,UINT32 * p_timeout,UINT32 * p_offset,UINT8 info,UINT8 app_id)1154 void bta_fs_co_suspend(BD_ADDR bd_addr, UINT8 *p_sess_info, UINT8 ssn,
1155                                       UINT32 *p_timeout, UINT32 *p_offset, UINT8 info, UINT8 app_id)
1156 {
1157     BTIF_TRACE_WARNING0("[CO] bta_fs_co_suspend - NOT implemented");
1158 }
1159 
1160 /*******************************************************************************
1161 **
1162 ** Function         bta_fs_co_sess_ssn
1163 **
1164 ** Description      This function is executed by BTA when resuming a session.
1165 **                  This is used to inform call-out module if the ssn/file offset
1166 **                  needs to be adjusted.
1167 **
1168 ** Parameters       ssn     - the session sequence number of the first request
1169 **                            after resume.
1170 **                  app_id  - application ID specified in the enable functions.
1171 **                            It can be used to identify which profile is the caller
1172 **                            of the call-out function.
1173 **
1174 ** Returns          void
1175 **
1176 *******************************************************************************/
bta_fs_co_sess_ssn(int fd,UINT8 ssn,UINT8 app_id)1177 void bta_fs_co_sess_ssn(int fd, UINT8 ssn, UINT8 app_id)
1178 {
1179     BTIF_TRACE_WARNING0("[CO] bta_fs_co_suspend - NOT implemented");
1180 }
1181 
1182