blob: 13a82f1a308ed20305aa72e0e487fd03d0c4b5b3 [file] [log] [blame]
Sungmin Choi5fd819d2012-07-18 01:49:40 -07001/*
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/*
29static 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
55static 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
132static 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 */
202void 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 */
263int 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 */
343void 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 */
467int 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 */
557int 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 */
585int 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