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