1 /* 2 * Copyright 2012 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 #include <stdio.h> 18 #include <stdlib.h> 19 #include <string.h> 20 #include <fcntl.h> 21 #include <unistd.h> 22 #include <errno.h> 23 #include <sys/stat.h> 24 #include <sys/types.h> 25 26 #include "wfc_util_log.h" 27 28 /* 29 static void wfc_util_printf(char *pSPointer, int length) 30 { 31 char *pPrintBuff = NULL; 32 33 if( NULL == pSPointer || 0 >= length ) { 34 wfc_util_log_error("wfc_util_printf : unvalid parameters"); 35 return; 36 } 37 38 wfc_util_log_error("wfc_util_printf : lenght is (%d)", length); 39 pPrintBuff = malloc(length+1); 40 41 if( NULL != pPrintBuff ) { 42 memset( pPrintBuff, 0, (length+1) ); 43 memcpy(pPrintBuff, pSPointer, length); 44 45 wfc_util_log_error("wfc_util_printf : %s", pPrintBuff); 46 47 free(pPrintBuff); 48 } else { 49 wfc_util_log_error("wfc_util_printf : can not malloc(%d)", (length+1)); 50 } 51 return; 52 } 53 */ 54 55 static void wfc_util_finsert_new_string(int fd, char **ppReadedBuff, char *pNewStringValue, char *pEndOfCfg) 56 { 57 off_t sz_file; 58 int sz_backupBuff = 0; 59 char *pReadBuff = NULL, *pBackupBuff = NULL; 60 char *pSPointer = NULL, *pETagPointer = NULL; 61 62 if( 0 == fd || NULL == pNewStringValue || 0 == strlen(pNewStringValue) ) { 63 wfc_util_log_error("wfc_util_finsert_new_string : unvalid parameters"); 64 return; 65 } 66 67 if( NULL == ppReadedBuff) { 68 // TODO: 69 return; 70 } else { 71 pReadBuff = *ppReadedBuff; 72 } 73 74 /* 75 * find END TAG string 76 */ 77 pETagPointer = strstr(pReadBuff, pEndOfCfg); 78 pSPointer = pETagPointer - 1; 79 80 /* 81 * calcurate file size and size of the tail of file 82 */ 83 sz_file = lseek( fd, 0, SEEK_END ); 84 sz_backupBuff = (int)sz_file - (pETagPointer - pReadBuff); 85 86 /* 87 * prefare the buffer to store the tail of file 88 */ 89 pBackupBuff = malloc(sz_backupBuff); 90 91 if( NULL != pBackupBuff ) { 92 /* 93 * copy the tail of file. 94 */ 95 memset( pBackupBuff, 0, sz_backupBuff ); 96 memcpy( pBackupBuff, pETagPointer, sz_backupBuff ); 97 98 /* 99 * write new string. 100 */ 101 lseek( fd, (int)(pSPointer-pReadBuff), SEEK_SET ); 102 write( fd, pNewStringValue, strlen(pNewStringValue)); 103 104 /* 105 * update pETagPointer. 106 */ 107 pETagPointer = pSPointer + strlen(pNewStringValue); 108 109 /* 110 * write the tail of file. 111 */ 112 lseek( fd, (int)(pETagPointer-pReadBuff), SEEK_SET ); 113 write( fd, pBackupBuff, sz_backupBuff ); 114 115 ftruncate(fd, sz_file + strlen(pNewStringValue) - 1); /* we use "-1" becasue of "pSPointer = pETagPointer - 1"*/ 116 117 free(pBackupBuff); 118 119 /* 120 * make new *ppReadedBuff 121 */ 122 if( NULL != ppReadedBuff) { 123 // TODO: 124 } 125 } else { 126 wfc_util_log_error("wfc_util_finsert_new_string : can not malloc(%d)", sz_backupBuff); 127 } 128 129 return; 130 } 131 132 static void wfc_util_fupdate_string(int fd, char **ppReadedBuff, 133 char *pETagPointer, char *pSValuePointer, char *pNewValueString) 134 { 135 off_t sz_file; 136 int sz_newReadBuff = 0; 137 char *pReadBuff = NULL, *pNewReadBuff = NULL, *pCurReadBuff = NULL; 138 139 if( 0 == fd ) { 140 wfc_util_log_error("wfc_util_fupdate_string : unvalid parameters"); 141 return; 142 } 143 144 if( NULL == ppReadedBuff) { 145 // TODO: 146 return; 147 } else { 148 pReadBuff = *ppReadedBuff; 149 } 150 151 /* 152 * calcurate file size and new file size 153 */ 154 sz_file = lseek( fd, 0, SEEK_END ); 155 sz_newReadBuff = (int)sz_file - (int)(pETagPointer - pSValuePointer) + strlen(pNewValueString); 156 157 /* 158 * prefare the buffer to read file 159 */ 160 pNewReadBuff = malloc(sz_newReadBuff); 161 162 if( NULL != pNewReadBuff ) { 163 /* 164 * copy buffer 165 */ 166 memset( pNewReadBuff, 0, sz_file ); 167 pCurReadBuff = pNewReadBuff; 168 memcpy( pNewReadBuff, pReadBuff, (int)(pSValuePointer-pReadBuff) ); 169 pCurReadBuff += (int)(pSValuePointer-pReadBuff); 170 171 /* 172 * copy new value string 173 */ 174 memcpy( pCurReadBuff, pNewValueString, strlen(pNewValueString)); 175 pCurReadBuff += strlen(pNewValueString); 176 177 /* 178 * copy the remained buffer 179 */ 180 memcpy( pCurReadBuff, pETagPointer, ((int)(sz_file) - (int)(pETagPointer - pReadBuff) + 1)); 181 182 /* 183 * write file and update the file size 184 */ 185 lseek( fd, 0, SEEK_SET ); 186 write( fd, pNewReadBuff, sz_newReadBuff); 187 ftruncate(fd, sz_newReadBuff); 188 189 free(pNewReadBuff); 190 } else { 191 wfc_util_log_error("wfc_util_fupdate_string : can not malloc(%d)", (int)sz_newReadBuff); 192 } 193 194 return; 195 } 196 197 /* 198 * wfc_util_fset_buffer 199 * 200 * return : void 201 */ 202 void wfc_util_fset_buffer(char *pFileName, int positionStart, unsigned char *pNewValue, int newValueLength) 203 { 204 int fd; 205 off_t sz_file; 206 char *pReadBuff = NULL; 207 208 fd = open( pFileName, O_RDWR ); 209 210 if( fd >= 0 ) { 211 /* 212 * calcurate file size 213 */ 214 sz_file = lseek( fd, 0, SEEK_END ); 215 216 /* 217 * prefare the buffer to read file 218 */ 219 pReadBuff = malloc(sz_file + 1); // null terminated 220 221 if( NULL != pReadBuff ) { 222 /* 223 * read file 224 */ 225 memset( pReadBuff, 0, sz_file + 1); 226 lseek( fd, 0, SEEK_SET ); 227 read( fd, pReadBuff, sz_file ); 228 229 if(sz_file >= (positionStart+newValueLength)) { 230 lseek( fd, positionStart, SEEK_SET ); 231 write( fd, pNewValue, newValueLength ); 232 } else { 233 /* 234 * insert with new length value buffer 235 */ 236 wfc_util_log_error("wfc_util_fset_buffer : file size(%d) is less than to write position(%d)", (int)sz_file, (positionStart+newValueLength)); 237 // TODO: 238 } 239 240 free(pReadBuff); 241 } else { 242 wfc_util_log_error("wfc_util_fset_buffer : can not malloc(%d)", (int)sz_file); 243 } 244 245 if ( -1 == fsync( fd ) ) { 246 wfc_util_log_error("wfc_util_fset_buffer : fail to fsync()"); 247 } 248 249 close( fd ); 250 } else { 251 wfc_util_log_error("wfc_util_fset_buffer : can not open file"); 252 } 253 254 return; 255 } 256 257 /* 258 * wfc_util_fget_buffer 259 * 260 * return : it will return the length of the stored buffer value if procedure is success 261 * or will return 0 if not. 262 */ 263 int wfc_util_fget_buffer(char *pFileName, int positionStart, int lengthToRead, unsigned char *pValueBuff, int buffLength) 264 { 265 int result = 0; 266 int fd; 267 off_t sz_file; 268 char *pReadBuff = NULL; 269 char *pSValuePointer = NULL, *pETagPointer = NULL; 270 271 fd = open( pFileName, O_RDONLY ); 272 273 if( fd >= 0 ) { 274 /* 275 * calcurate file size 276 */ 277 sz_file = lseek( fd, 0, SEEK_END ); 278 279 if(sz_file >= (positionStart+lengthToRead)) { 280 /* 281 * prefare the buffer to read file 282 */ 283 pReadBuff = malloc(sz_file + 1); // null terminated 284 285 if( NULL != pReadBuff ) { 286 /* 287 * read file 288 */ 289 memset( pReadBuff, 0, sz_file + 1 ); 290 lseek( fd, 0, SEEK_SET ); 291 read( fd, pReadBuff, sz_file ); 292 293 /* 294 * calculate the start buffer pointer 295 */ 296 pSValuePointer = pReadBuff + positionStart; 297 298 /* 299 * calculate the end buffer pointer 300 */ 301 pETagPointer = pSValuePointer + lengthToRead; 302 303 /* 304 * read the string value 305 */ 306 if( buffLength >= (int)(pETagPointer-pSValuePointer) ) { 307 memset( pValueBuff, 0, buffLength ); 308 memcpy( pValueBuff, pSValuePointer, (int)(pETagPointer-pSValuePointer) ); 309 result = (int)(pETagPointer-pSValuePointer); 310 } else { 311 wfc_util_log_error("wfc_util_fget_buffer : not enough string value buffer(%d)", (int)(pETagPointer-pSValuePointer)); 312 } 313 314 free(pReadBuff); 315 } else { 316 wfc_util_log_error("wfc_util_fget_buffer : can not malloc(%d)", (int)sz_file); 317 } 318 } else { 319 wfc_util_log_error("wfc_util_fget_buffer : file size(%d) is less than to read position(%d)", (int)sz_file, (positionStart+lengthToRead)); 320 } 321 close( fd ); 322 } else { 323 wfc_util_log_error("wfc_util_fget_buffer : can not open file"); 324 } 325 326 return result; 327 } 328 329 /* 330 * wfc_util_fset_string 331 * 332 * The following format string will be added or updated to the file pFileName. 333 * [pSTagString][pNewValueString][pETagString] 334 * 335 * pFileName : file name and path 336 * pEndOfCfg : tag string to notify the end of configuration file 337 * pSTagString : tag string to notify purpose of the value 338 * pETagString : tag string to notify the end of the value 339 * pNewValueString : string to set for pSTagString 340 * 341 * return : void 342 */ 343 void wfc_util_fset_string(char *pFileName, char *pEndOfCfg, char *pSTagString, char *pETagString, char *pNewValueString) 344 { 345 int fd; 346 off_t sz_file; 347 int sz_NewValueBuff = 0; 348 char *pReadBuff = NULL, *pNewValueBuff = NULL; 349 char *pSPointer = NULL, *pETagPointer = NULL, *pSValuePointer = NULL; 350 351 fd = open( pFileName, O_RDWR ); 352 353 if( fd >= 0 ) { 354 /* 355 * calcurate file size 356 */ 357 sz_file = lseek( fd, 0, SEEK_END ); 358 359 /* 360 * prefare the buffer to read file 361 */ 362 if (sz_file > 0) 363 pReadBuff = malloc(sz_file + 1); // null terminated 364 365 if( NULL != pReadBuff ) { 366 /* 367 * read file 368 */ 369 memset( pReadBuff, 0x00, sz_file + 1); 370 if(lseek(fd, 0, SEEK_SET) != 0) { 371 wfc_util_log_error("lseek failure"); 372 } 373 read( fd, pReadBuff, sz_file ); 374 375 /* WBT fix, make sure it is terminated with \0 */ 376 pReadBuff[sz_file] = '\0'; 377 378 /* 379 * find TAG string 380 */ 381 pSPointer = strstr(pReadBuff, pSTagString); 382 383 if(NULL != pSPointer) { 384 /* 385 * find END OF LINE string 386 */ 387 pETagPointer = strstr(pSPointer, pETagString); 388 389 if(NULL != pETagPointer) { 390 /* 391 * write the new string value 392 */ 393 pSValuePointer = pSPointer+strlen(pSTagString); 394 if(strlen(pNewValueString) == (unsigned int)(pETagPointer-pSValuePointer)) { 395 lseek( fd, (int)(pSValuePointer-pReadBuff), SEEK_SET ); 396 write( fd, pNewValueString, strlen(pNewValueString)); 397 } else { 398 /* 399 * insert with new length value string 400 */ 401 wfc_util_fupdate_string(fd, &pReadBuff, pETagPointer, pSValuePointer, pNewValueString); 402 } 403 } else { 404 wfc_util_log_error("wfc_util_fset_string : can not find End TAG"); 405 } 406 } else { 407 /* 408 * "\n""[Start TAG][String Value][End TAG]""\n" 409 */ 410 sz_NewValueBuff = strlen(pSTagString) + 411 strlen(pNewValueString) + 412 strlen(pETagString) + 413 2 + 1; 414 pNewValueBuff = malloc( sz_NewValueBuff); 415 416 if( NULL != pNewValueBuff ) { 417 /* 418 * prefare the new string to insert 419 */ 420 memset( pNewValueBuff, 0, sz_NewValueBuff ); 421 sprintf( pNewValueBuff, "%c%s%s%s%c", '\n', pSTagString, pNewValueString, pETagString,'\n' ); 422 423 /* 424 * insert new string to the file 425 */ 426 wfc_util_finsert_new_string(fd, &pReadBuff, pNewValueBuff, pEndOfCfg); 427 428 free( pNewValueBuff ); 429 } else { 430 wfc_util_log_error("wfc_util_fset_string : can not malloc(%d)", (int)sz_file); 431 } 432 } 433 434 free(pReadBuff); 435 } else { 436 wfc_util_log_error("wfc_util_fset_string : can not malloc(%d)", (int)sz_file); 437 } 438 439 if ( -1 == fsync( fd ) ) { 440 wfc_util_log_error("wfc_util_fset_string : fail to fsync()"); 441 } 442 443 close( fd ); 444 } else { 445 wfc_util_log_error("wfc_util_fset_string : can not open file"); 446 } 447 448 return; 449 } 450 451 /* 452 * wfc_util_fget_string 453 * 454 * Read value from the following format string in the file pFileName. 455 * [pSTagString][string value to read][pETagString] 456 * 457 * pFileName : file name and path 458 * pEndOfCfg : tag string to notify the end of configuration file 459 * pSTagString : tag string to notify purpose of the value 460 * pETagString : tag string to notify the end of the value 461 * pValueStringBuff : string buffer to get string value 462 * stringBuffLength : the length of pValueStringBuff 463 * 464 * return : it will return the length of the stored string value if procedure is success 465 * or will return 0 if not. 466 */ 467 int wfc_util_fget_string(char *pFileName, char *pEndOfCfg, char *pSTagString, char *pETagString, char *pValueStringBuff, int stringBuffLength) 468 { 469 int result = 0; 470 int fd; 471 off_t sz_file; 472 char *pReadBuff = NULL; 473 char *pSPointer = NULL, *pETagPointer = NULL, *pSValuePointer = NULL; 474 475 /* unused parameter*/ 476 pEndOfCfg = pEndOfCfg; 477 478 fd = open( pFileName, O_RDONLY ); 479 480 if( fd >= 0 ) { 481 /* 482 * calcurate file size 483 */ 484 sz_file = lseek( fd, 0, SEEK_END ); 485 486 /* 487 * prefare the buffer to read file 488 */ 489 if (sz_file > 0) // skip when value is 0 490 pReadBuff = malloc(sz_file + 1); 491 492 if( NULL != pReadBuff ) { 493 /* 494 * read file 495 */ 496 memset( pReadBuff, 0, sz_file + 1); 497 if(lseek(fd, 0, SEEK_SET) != 0) { 498 wfc_util_log_error("lseek failure"); 499 } 500 read( fd, pReadBuff, sz_file ); 501 502 /* WBT fix, make sure it is terminated with \0 */ 503 pReadBuff[sz_file] = '\0'; 504 505 /* 506 * find TAG string 507 */ 508 pSPointer = strstr( pReadBuff, pSTagString ); 509 510 if( NULL != pSPointer ) { 511 /* 512 * find END OF LINE string 513 */ 514 pETagPointer = strstr(pSPointer, pETagString); 515 516 if( NULL != pETagPointer ) { 517 /* 518 * read the string value 519 */ 520 pSValuePointer = pSPointer+strlen(pSTagString); 521 if( stringBuffLength >= (int)(pETagPointer-pSValuePointer) ) { 522 memset( pValueStringBuff, 0, stringBuffLength ); 523 memcpy( pValueStringBuff, pSValuePointer, (int)(pETagPointer-pSValuePointer) ); 524 result = (int)(pETagPointer-pSValuePointer); 525 } else { 526 wfc_util_log_error("wfc_util_fget_string : not enough string value buffer(%d)", (int)(pETagPointer-pSValuePointer)); 527 } 528 } else { 529 wfc_util_log_error("wfc_util_fget_string : can not find End TAG"); 530 } 531 } else { 532 wfc_util_log_error("wfc_util_fget_string : can not find Start TAG"); 533 } 534 free(pReadBuff); 535 } else { 536 wfc_util_log_error("wfc_util_fget_string : can not malloc(%d)", (int)sz_file); 537 } 538 close( fd ); 539 } else { 540 wfc_util_log_error("wfc_util_fget_string : can not open file"); 541 } 542 543 return result; 544 } 545 546 /* 547 * wfc_util_ffile_check 548 * 549 * check whether pDestFName file exist or not 550 * 551 * pFileName : file name and path 552 * access_mode : R_OK | W_OK | X_OK | F_OK 553 * 554 * return : it will return 0 if the file exist 555 * or will return -1 if not. 556 */ 557 int wfc_util_ffile_check(char *pDestFName, int access_mode) 558 { 559 struct stat st; 560 561 if (access(pDestFName, access_mode) == 0) { 562 if( stat( pDestFName, &st ) < 0 ) { 563 wfc_util_log_error("Cannot stat the file \"%s\": %s", pDestFName, strerror(errno)); 564 return -1; 565 } 566 //check if config file has some data or is it empty due to previous errors 567 if( st.st_size ) { 568 return 0; 569 } 570 } else { 571 wfc_util_log_error("Cannot access \"%s\": %s", pDestFName, strerror(errno)); 572 } 573 574 return -1; 575 } 576 577 /* 578 * wfc_util_ffile_check_copy 579 * 580 * check whether pDestFName file exist if not it will copy from pSourceFName file 581 * 582 * return : it will return 0 if procedure is success 583 * or will return -1 if not. 584 */ 585 int wfc_util_ffile_check_copy(char *pDestFName, char *pSourceFName, mode_t mode, uid_t uID, gid_t gID) 586 { 587 #define WFC_BUFFER_SIZE 2048 588 char buf[WFC_BUFFER_SIZE] = {0}; // Null terminated 589 int srcfd, destfd; 590 int nread; 591 struct stat st; 592 593 if (access(pDestFName, R_OK|W_OK) == 0) { 594 if( stat( pDestFName, &st ) < 0 ) { 595 wfc_util_log_error("Cannot stat the file \"%s\": %s", pDestFName, strerror(errno)); 596 return -1; 597 } 598 //check if config file has some data or is it empty due to previous errors 599 if( st.st_size ) { 600 return 0; 601 } 602 //else continue to write the config from default template. 603 } else if (errno != ENOENT) { 604 wfc_util_log_error("Cannot access \"%s\": %s", pDestFName, strerror(errno)); 605 return -1; 606 } 607 608 srcfd = open(pSourceFName, O_RDONLY); 609 if (srcfd < 0) { 610 wfc_util_log_error("Cannot open \"%s\": %s", pSourceFName, strerror(errno)); 611 return -1; 612 } 613 614 destfd = open(pDestFName, O_CREAT|O_WRONLY, mode); 615 if (destfd < 0) { 616 close(srcfd); 617 wfc_util_log_error("Cannot create \"%s\": %s", pDestFName, strerror(errno)); 618 return -1; 619 } 620 621 while ((nread = read(srcfd, buf, WFC_BUFFER_SIZE-1)) != 0) { 622 if (nread < 0) { 623 wfc_util_log_error("Error reading \"%s\": %s", pSourceFName, strerror(errno)); 624 close(srcfd); 625 close(destfd); 626 unlink(pDestFName); 627 return -1; 628 } 629 // WBT fix, according to manual, the number of bytes read can't be bigger than read_size. I don't know why WBT complains for this. 630 if (nread < WFC_BUFFER_SIZE) 631 buf[nread] = '\0'; 632 else { 633 buf[WFC_BUFFER_SIZE-1] = '\0'; 634 nread = WFC_BUFFER_SIZE-1; 635 } 636 write(destfd, buf, nread); 637 } 638 639 close(destfd); 640 close(srcfd); 641 642 /* remove this code because of permission problem when it is accessed from "atd" having system permission. */ 643 { 644 #ifndef CONFIG_LGE_WLAN_WIFI_PATCH 645 uid_t uid = getuid(); 646 gid_t gid = getgid(); 647 wfc_util_log_error("Error changing group ownership (%d) of %s to %d: %s", gid, pDestFName, gID, strerror(errno)); 648 if (0 == uid) { 649 #endif /* CONFIG_LGE_WLAN_WIFI_PATCH */ 650 if (chown(pDestFName, uID, gID) < 0) { 651 wfc_util_log_error("Error changing group ownership of %s to %d: %s", pDestFName, gID, strerror(errno)); 652 unlink(pDestFName); 653 return -1; 654 } 655 #ifndef CONFIG_LGE_WLAN_WIFI_PATCH 656 } else { 657 wfc_util_log_error("wfc_util_ffile_check_copy : we can not excute chown[uid = %d, gid = %d]", uid, getgid()); 658 } 659 #endif /* CONFIG_LGE_WLAN_WIFI_PATCH */ 660 } 661 662 return 0; 663 } 664 665