blob: cd532a917bc05a76d935838ea6bbcd8f3b87af06 [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 */
synergydevcea91082013-10-13 00:47:20 -0700467int wfc_util_fget_string(char *pFileName, char *pEndOfCfg __attribute__((unused)), char *pSTagString,
468 char *pETagString, char *pValueStringBuff, int stringBuffLength)
Sungmin Choi5fd819d2012-07-18 01:49:40 -0700469{
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
Sungmin Choi5fd819d2012-07-18 01:49:40 -0700476 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 */
555int 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 */
583int 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