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 __attribute__((unused)), char *pSTagString, 468 char *pETagString, char *pValueStringBuff, int stringBuffLength) 469 { 470 int result = 0; 471 int fd; 472 off_t sz_file; 473 char *pReadBuff = NULL; 474 char *pSPointer = NULL, *pETagPointer = NULL, *pSValuePointer = NULL; 475 476 fd = open( pFileName, O_RDONLY ); 477 478 if( fd >= 0 ) { 479 /* 480 * calcurate file size 481 */ 482 sz_file = lseek( fd, 0, SEEK_END ); 483 484 /* 485 * prefare the buffer to read file 486 */ 487 if (sz_file > 0) // skip when value is 0 488 pReadBuff = malloc(sz_file + 1); 489 490 if( NULL != pReadBuff ) { 491 /* 492 * read file 493 */ 494 memset( pReadBuff, 0, sz_file + 1); 495 if(lseek(fd, 0, SEEK_SET) != 0) { 496 wfc_util_log_error("lseek failure"); 497 } 498 read( fd, pReadBuff, sz_file ); 499 500 /* WBT fix, make sure it is terminated with \0 */ 501 pReadBuff[sz_file] = '\0'; 502 503 /* 504 * find TAG string 505 */ 506 pSPointer = strstr( pReadBuff, pSTagString ); 507 508 if( NULL != pSPointer ) { 509 /* 510 * find END OF LINE string 511 */ 512 pETagPointer = strstr(pSPointer, pETagString); 513 514 if( NULL != pETagPointer ) { 515 /* 516 * read the string value 517 */ 518 pSValuePointer = pSPointer+strlen(pSTagString); 519 if( stringBuffLength >= (int)(pETagPointer-pSValuePointer) ) { 520 memset( pValueStringBuff, 0, stringBuffLength ); 521 memcpy( pValueStringBuff, pSValuePointer, (int)(pETagPointer-pSValuePointer) ); 522 result = (int)(pETagPointer-pSValuePointer); 523 } else { 524 wfc_util_log_error("wfc_util_fget_string : not enough string value buffer(%d)", (int)(pETagPointer-pSValuePointer)); 525 } 526 } else { 527 wfc_util_log_error("wfc_util_fget_string : can not find End TAG"); 528 } 529 } else { 530 wfc_util_log_error("wfc_util_fget_string : can not find Start TAG"); 531 } 532 free(pReadBuff); 533 } else { 534 wfc_util_log_error("wfc_util_fget_string : can not malloc(%d)", (int)sz_file); 535 } 536 close( fd ); 537 } else { 538 wfc_util_log_error("wfc_util_fget_string : can not open file"); 539 } 540 541 return result; 542 } 543 544 /* 545 * wfc_util_ffile_check 546 * 547 * check whether pDestFName file exist or not 548 * 549 * pFileName : file name and path 550 * access_mode : R_OK | W_OK | X_OK | F_OK 551 * 552 * return : it will return 0 if the file exist 553 * or will return -1 if not. 554 */ 555 int wfc_util_ffile_check(char *pDestFName, int access_mode) 556 { 557 struct stat st; 558 559 if (access(pDestFName, access_mode) == 0) { 560 if( stat( pDestFName, &st ) < 0 ) { 561 wfc_util_log_error("Cannot stat the file \"%s\": %s", pDestFName, strerror(errno)); 562 return -1; 563 } 564 //check if config file has some data or is it empty due to previous errors 565 if( st.st_size ) { 566 return 0; 567 } 568 } else { 569 wfc_util_log_error("Cannot access \"%s\": %s", pDestFName, strerror(errno)); 570 } 571 572 return -1; 573 } 574 575 /* 576 * wfc_util_ffile_check_copy 577 * 578 * check whether pDestFName file exist if not it will copy from pSourceFName file 579 * 580 * return : it will return 0 if procedure is success 581 * or will return -1 if not. 582 */ 583 int wfc_util_ffile_check_copy(char *pDestFName, char *pSourceFName, mode_t mode, uid_t uID, gid_t gID) 584 { 585 #define WFC_BUFFER_SIZE 2048 586 char buf[WFC_BUFFER_SIZE] = {0}; // Null terminated 587 int srcfd, destfd; 588 int nread; 589 struct stat st; 590 591 if (access(pDestFName, R_OK|W_OK) == 0) { 592 if( stat( pDestFName, &st ) < 0 ) { 593 wfc_util_log_error("Cannot stat the file \"%s\": %s", pDestFName, strerror(errno)); 594 return -1; 595 } 596 //check if config file has some data or is it empty due to previous errors 597 if( st.st_size ) { 598 return 0; 599 } 600 //else continue to write the config from default template. 601 } else if (errno != ENOENT) { 602 wfc_util_log_error("Cannot access \"%s\": %s", pDestFName, strerror(errno)); 603 return -1; 604 } 605 606 srcfd = open(pSourceFName, O_RDONLY); 607 if (srcfd < 0) { 608 wfc_util_log_error("Cannot open \"%s\": %s", pSourceFName, strerror(errno)); 609 return -1; 610 } 611 612 destfd = open(pDestFName, O_CREAT|O_WRONLY, mode); 613 if (destfd < 0) { 614 close(srcfd); 615 wfc_util_log_error("Cannot create \"%s\": %s", pDestFName, strerror(errno)); 616 return -1; 617 } 618 619 while ((nread = read(srcfd, buf, WFC_BUFFER_SIZE-1)) != 0) { 620 if (nread < 0) { 621 wfc_util_log_error("Error reading \"%s\": %s", pSourceFName, strerror(errno)); 622 close(srcfd); 623 close(destfd); 624 unlink(pDestFName); 625 return -1; 626 } 627 // 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. 628 if (nread < WFC_BUFFER_SIZE) 629 buf[nread] = '\0'; 630 else { 631 buf[WFC_BUFFER_SIZE-1] = '\0'; 632 nread = WFC_BUFFER_SIZE-1; 633 } 634 write(destfd, buf, nread); 635 } 636 637 close(destfd); 638 close(srcfd); 639 640 /* remove this code because of permission problem when it is accessed from "atd" having system permission. */ 641 { 642 #ifndef CONFIG_LGE_WLAN_WIFI_PATCH 643 uid_t uid = getuid(); 644 gid_t gid = getgid(); 645 wfc_util_log_error("Error changing group ownership (%d) of %s to %d: %s", gid, pDestFName, gID, strerror(errno)); 646 if (0 == uid) { 647 #endif /* CONFIG_LGE_WLAN_WIFI_PATCH */ 648 if (chown(pDestFName, uID, gID) < 0) { 649 wfc_util_log_error("Error changing group ownership of %s to %d: %s", pDestFName, gID, strerror(errno)); 650 unlink(pDestFName); 651 return -1; 652 } 653 #ifndef CONFIG_LGE_WLAN_WIFI_PATCH 654 } else { 655 wfc_util_log_error("wfc_util_ffile_check_copy : we can not excute chown[uid = %d, gid = %d]", uid, getgid()); 656 } 657 #endif /* CONFIG_LGE_WLAN_WIFI_PATCH */ 658 } 659 660 return 0; 661 } 662 663