24 #include "fileutils.h"
46 #define MAIN_ERR_PREFIX "GROUP: "
50 #define GROUP_PERM (api_posix_mode_t) (API_POSIX_S_IRUSR | API_POSIX_S_IWUSR)
56 static const char groupfile_name[] =
"groupfile";
57 static const char tmpfile_name[] =
"groupfile.new";
74 static int group_compar(
const void* a,
const void* b)
77 const char* aa = *(
const char**) a;
78 const char* bb = *(
const char**) b;
83 x = (
char*) api_posix_malloc(strlen(aa) + (size_t) 1);
84 y = (
char*) api_posix_malloc(strlen(bb) + (size_t) 1);
85 if(NULL != x && NULL != y)
89 p = strchr(x, (
int)
':');
if(NULL != p) { *p = 0; }
90 p = strchr(x, (
int)
'!');
if(NULL != p) { *p = 0; }
91 p = strchr(y, (
int)
':');
if(NULL != p) { *p = 0; }
92 p = strchr(y, (
int)
'!');
if(NULL != p) { *p = 0; }
95 if(api_posix_errno) { res = 0; }
97 api_posix_free((
void*) x);
98 api_posix_free((
void*) y);
111 static int group_get_pathname(
const char** pathname,
const char* filename)
118 if(NULL != *pathname)
120 rv =
fu_create_path(*pathname, (api_posix_mode_t) API_POSIX_S_IRWXU);
136 api_posix_free((
void*) *pathname);
159 static int group_extract_ranges(
struct core_range** list,
const char* s)
176 while(
' ' == *s || (
char) 0x09 == *s ) { ++s; }
178 while(
',' == *s) { ++s; }
180 while(
' ' == *s || (
char) 0x09 == *s ) { ++s; }
187 len = (size_t) (s - p);
188 if((
size_t) API_POSIX_INT_MAX < len) { res = -1;
break; }
190 if(rv) { res = -1;
break; }
192 while(
' ' == *s || (
char) 0x09 == *s ) { ++s; }
195 start = tmp; range_start = 0;
197 if(
'-' != *s) { end = start; range_start = 1; }
else { ++s; }
209 if(0 > res) {
break; }
210 if(NULL == current_element) { list_start = list_element; }
211 else { current_element->
next = list_element; }
212 current_element = list_element;
218 PRINT_ERROR(
"Parsing article ranges in group file failed");
246 rv = fprintf(fs,
"%s: ", group->
name);
247 if(0 > rv) { res = -1; }
254 PRINT_ERROR(
"Value of CORE_ANUM_T_MAX is too large");
263 if(a) { rv = fprintf(fs,
", "); }
264 if(0 > rv) { res = -1;
break; }
265 a = (
unsigned long int) cr->
first;
266 rv = fprintf(fs,
"%lu", a);
267 if(0 > rv) { res = -1;
break; }
270 a = (
unsigned long int) cr->
last;
271 rv = fprintf(fs,
"-%lu", a);
272 if(0 > rv) { res = -1;
break; }
295 static int group_export_groups(
size_t num,
struct core_groupstate* grouplist,
296 FILE* fs, FILE* fs_tmp)
302 api_posix_ssize_t readlen;
305 size_t* inserted = NULL;
311 inserted = (
size_t*) api_posix_malloc(
sizeof(
size_t) * num);
315 for(i = 0; i < num; ++i) { inserted[i] = 0; }
321 readlen = api_posix_getline(&line, &len, fs);
324 if (API_POSIX_ENOMEM == api_posix_errno)
326 PRINT_ERROR(
"Cannot assign memory for group file parser");
345 if(0 >= readlen)
break;
349 for(i = 0; i < (size_t) readlen; ++i)
351 if(0x0D == (
int) line[i]) { line[i] =
' '; }
356 for(i = 0; i < num; ++i)
358 nlen = strlen(grouplist[i].name);
359 if(!inserted[i] && !strncmp(line, grouplist[i].name, nlen))
362 if(
':' != line[nlen] &&
'!' != line[nlen]) {
continue; }
364 p = strchr(line, (
int)
'!');
370 rv = fprintf(fs_tmp,
"%s", line);
371 if(0 > rv) { error = 1;
break; }
376 res = group_print_entry(fs_tmp, &grouplist[i]);
377 if(res) { error = 1;
break; }
388 p = strchr(line, (
int)
':');
389 if(NULL != p) { *p =
'!'; }
390 rv = fprintf(fs_tmp,
"%s", line);
399 for(i = 0; i < num; ++i)
403 res = group_print_entry(fs_tmp, &grouplist[i]);
411 api_posix_free((
void*) line);
412 api_posix_free((
void*) inserted);
428 static int group_import_groups(
size_t* num,
435 api_posix_ssize_t readlen;
447 readlen = api_posix_getline(&line, &len, fs);
450 api_posix_free((
void*) line);
451 if (API_POSIX_ENOMEM == api_posix_errno)
453 PRINT_ERROR(
"Cannot allocate memory for group file parser");
472 if(0 >= readlen)
break;
479 api_posix_free((
void*) line);
483 if(strchr(line, (
int)
'!'))
486 api_posix_free(line);
489 c = strchr(line, (
int)
':');
493 api_posix_free((
void*) line);
500 api_posix_realloc((
void*) *grouplist,
501 (*num + (size_t) 1) *
sizeof(**grouplist));
504 PRINT_ERROR(
"Cannot allocate memory for group list");
505 api_posix_free((
void*) line);
511 line[readlen - (api_posix_ssize_t) 1] = 0;
512 (*grouplist)[(*num)].
name = line;
513 (*grouplist)[(*num)].info = NULL;
514 (*grouplist)[(*num)].last_viewed = 0;
517 if(!group_extract_ranges(&rp, ++c))
520 (*grouplist)[(*num)].info = rp;
553 const char* grouppathname = NULL;
554 char* oldgrouppathname = NULL;
556 api_posix_struct_stat state;
565 printf(
"%s: %sImport external newsrc: %s\n",
568 rv = api_posix_stat(newsrc, &state);
570 else if(API_POSIX_S_ISREG(state.st_mode))
572 rv = group_get_pathname(&grouppathname, groupfile_name);
577 (api_posix_mode_t) 0);
589 (
char*) api_posix_malloc(strlen(grouppathname)
591 if(NULL == oldgrouppathname)
593 PRINT_ERROR(
"Cannot allocate memory for pathname");
597 strcpy(oldgrouppathname, grouppathname);
598 strcat(oldgrouppathname,
".old");
599 rv = api_posix_rename(grouppathname, oldgrouppathname);
628 PRINT_ERROR(
"Importing newsrc failed, using local groupfile");
633 api_posix_free((
void*)
data);
634 api_posix_free((
void*) oldgrouppathname);
635 api_posix_free((
void*) grouppathname);
649 const char* grouppathname = NULL;
650 char* tmppathname = NULL;
659 rv = group_get_pathname(&grouppathname, groupfile_name);
663 (api_posix_mode_t) 0);
677 printf(
"%s: %sExport to external newsrc: %s\n",
680 tmppathname = (
char*) api_posix_malloc(strlen(newsrc)
682 if(NULL == tmppathname)
684 PRINT_ERROR(
"Cannot allocate memory for pathname");
688 strcpy(tmppathname, newsrc);
689 strcat(tmppathname,
".new");
691 API_POSIX_O_WRONLY | API_POSIX_O_CREAT,
700 if(rv) { rv =
fu_sync(fd, NULL); }
707 rv = api_posix_rename(tmppathname, newsrc);
720 if(rv) {
PRINT_ERROR(
"Exporting groupfile data to newsrc failed"); }
724 api_posix_free((
void*)
data);
725 api_posix_free((
void*) tmppathname);
726 api_posix_free((
void*) grouppathname);
753 if (NULL == *range) { res = -1; }
756 (*range)->first = start;
757 (*range)->last = end;
758 (*range)->next =
next;
777 current_element = *list;
778 while(NULL != current_element)
780 tmp_element = current_element->
next;
781 api_posix_free((
void*) current_element);
782 current_element = tmp_element;
800 if(NULL == grouplist) {
return; }
804 api_posix_free((
void*) (*grouplist)[*num].name);
809 api_posix_free((
void*) *grouplist);
834 const char* grouppathname = NULL;
837 res = group_get_pathname(&grouppathname, groupfile_name);
841 API_POSIX_O_RDWR | API_POSIX_O_CREAT,
848 if(!res) { res = group_import_groups(num, grouplist, fs); }
854 api_posix_free((
void*) grouppathname);
882 const char* grouppathname = NULL;
883 const char* tmppathname = NULL;
886 res = group_get_pathname(&grouppathname, groupfile_name);
887 if(!res) { res = group_get_pathname(&tmppathname, tmpfile_name); }
893 API_POSIX_O_RDWR | API_POSIX_O_CREAT,
903 API_POSIX_O_WRONLY | API_POSIX_O_CREAT
915 if(!res && num) { res = group_export_groups(num, grouplist, fs, fs_tmp); }
918 if(!res) { res =
fu_sync(fd_tmp, fs_tmp); }
921 if(!res) { res = api_posix_rename(tmppathname, grouppathname); }
937 api_posix_free((
void*) tmppathname);
938 api_posix_free((
void*) grouppathname);
959 const char* grouppathname = NULL;
960 const char* tmppathname = NULL;
963 api_posix_ssize_t readlen;
964 const char** array = NULL;
965 const char** array_tmp;
966 size_t array_len = 0;
971 res = group_get_pathname(&grouppathname, groupfile_name);
972 if(!res) { res = group_get_pathname(&tmppathname, tmpfile_name); }
978 API_POSIX_O_RDWR | API_POSIX_O_CREAT,
993 API_POSIX_O_WRONLY | API_POSIX_O_CREAT
1006 readlen = api_posix_getline(&line, &len, fs);
1009 api_posix_free((
void*) line);
1010 if (API_POSIX_ENOMEM == api_posix_errno)
1012 PRINT_ERROR(
"Cannot allocate memory for group data");
1026 if(NULL != array) { res = 0; }
1031 if(0 >= readlen)
break;
1035 array_tmp = (
const char**)
1036 api_posix_realloc(array, (array_len + (
size_t) 1)
1037 * (
sizeof(
const char*)));
1038 if(NULL == array_tmp) { api_posix_free((
void*) line);
break; }
1042 array[array_len++] = line;
1051 qsort((
void*) array, array_len,
sizeof(
const char*), group_compar);
1052 for(i = 0; i < array_len; ++i)
1055 rv = fprintf(fs_tmp,
"%s", array[i]);
1056 if(0 > rv) { res = -1;
break; }
1061 while(array_len) { api_posix_free((
void*) array[--array_len]); }
1062 api_posix_free((
void*) array);
1065 if(!res) { res =
fu_sync(fd_tmp, fs_tmp); }
1068 if(!res) { res = api_posix_rename(tmppathname, grouppathname); }
1084 api_posix_free((
void*) tmppathname);
1085 api_posix_free((
void*) grouppathname);
1107 FILE* fs_tmp = NULL;
1108 const char* grouppathname = NULL;
1109 const char* tmppathname = NULL;
1112 api_posix_ssize_t readlen;
1119 res = group_get_pathname(&grouppathname, groupfile_name);
1120 if(!res) { res = group_get_pathname(&tmppathname, tmpfile_name); }
1126 API_POSIX_O_RDWR | API_POSIX_O_CREAT,
1136 API_POSIX_O_WRONLY | API_POSIX_O_CREAT
1137 | API_POSIX_O_TRUNC,
1154 readlen = api_posix_getline(&line, &len, fs);
1157 if (API_POSIX_ENOMEM == api_posix_errno)
1159 PRINT_ERROR(
"Cannot assign memory to read group file");
1177 if(0 >= readlen)
break;
1181 nlen = strlen(group->
name);
1182 if(!strncmp(line, group->
name, nlen))
1185 if(
':' == line[nlen] ||
'!' == line[nlen])
1189 p = strchr(line, (
int)
'!');
1198 rv = fprintf(fs_tmp,
"%s", line);
1203 if(!res && !found) { res = group_print_entry(fs_tmp, group); }
1207 if(!res) { res =
fu_sync(fd_tmp, fs_tmp); }
1210 if(!res) { res = api_posix_rename(tmppathname, grouppathname); }
1226 api_posix_free((
void*) line);
1227 api_posix_free((
void*) tmppathname);
1228 api_posix_free((
void*) grouppathname);