24 #include "fileutils.h"
46 #define MAIN_ERR_PREFIX "GROUP: "
50 #define GROUP_PERM (posix_mode_t) (POSIX_S_IRUSR | 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*) posix_malloc(strlen(aa) + (size_t) 1);
84 y = (
char*) 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(posix_errno) { res = 0; }
97 posix_free((
void*) x);
98 posix_free((
void*) y);
111 static int group_get_pathname(
const char** pathname,
const char* filename)
118 if(NULL != *pathname)
136 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) 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 posix_ssize_t readlen;
305 size_t* inserted = NULL;
311 inserted = (
size_t*) posix_malloc(
sizeof(
size_t) * num);
315 for(i = 0; i < num; ++i) { inserted[i] = 0; }
321 readlen = posix_getline(&line, &len, fs);
324 if (POSIX_ENOMEM == 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 posix_free((
void*) line);
412 posix_free((
void*) inserted);
428 static int group_import_groups(
size_t* num,
435 posix_ssize_t readlen;
447 readlen = posix_getline(&line, &len, fs);
450 posix_free((
void*) line);
451 if (POSIX_ENOMEM == posix_errno)
453 PRINT_ERROR(
"Cannot allocate memory for group file parser");
472 if(0 >= readlen)
break;
479 posix_free((
void*) line);
483 if(strchr(line, (
int)
'!'))
489 c = strchr(line, (
int)
':');
493 posix_free((
void*) line);
500 posix_realloc((
void*) *grouplist,
501 (*num + (size_t) 1) *
sizeof(**grouplist));
504 PRINT_ERROR(
"Cannot allocate memory for group list");
505 posix_free((
void*) line);
511 line[readlen - (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 struct_posix_stat state;
565 printf(
"%s: %sImport external newsrc: %s\n",
568 rv = posix_stat(newsrc, &state);
570 else if(POSIX_S_ISREG(state.st_mode))
572 rv = group_get_pathname(&grouppathname, groupfile_name);
576 rv =
fu_open_file(newsrc, &fd, POSIX_O_RDWR, (posix_mode_t) 0);
588 (
char*) posix_malloc(strlen(grouppathname) + (size_t) 5);
589 if(NULL == oldgrouppathname)
591 PRINT_ERROR(
"Cannot allocate memory for pathname");
595 strcpy(oldgrouppathname, grouppathname);
596 strcat(oldgrouppathname,
".old");
597 rv = posix_rename(grouppathname, oldgrouppathname);
605 POSIX_O_WRONLY | POSIX_O_CREAT,
625 PRINT_ERROR(
"Importing newsrc failed, using local groupfile");
630 posix_free((
void*)
data);
631 posix_free((
void*) oldgrouppathname);
632 posix_free((
void*) grouppathname);
646 const char* grouppathname = NULL;
647 char* tmppathname = NULL;
656 rv = group_get_pathname(&grouppathname, groupfile_name);
674 printf(
"%s: %sExport to external newsrc: %s\n",
677 tmppathname = (
char*) posix_malloc(strlen(newsrc) + (size_t) 5);
678 if(NULL == tmppathname)
680 PRINT_ERROR(
"Cannot allocate memory for pathname");
684 strcpy(tmppathname, newsrc);
685 strcat(tmppathname,
".new");
695 if(rv) { rv =
fu_sync(fd, NULL); }
702 rv = posix_rename(tmppathname, newsrc);
715 if(rv) {
PRINT_ERROR(
"Exporting groupfile data to newsrc failed"); }
719 posix_free((
void*)
data);
720 posix_free((
void*) tmppathname);
721 posix_free((
void*) grouppathname);
748 if (NULL == *range) { res = -1; }
751 (*range)->first = start;
752 (*range)->last = end;
753 (*range)->next =
next;
772 current_element = *list;
773 while(NULL != current_element)
775 tmp_element = current_element->
next;
776 posix_free((
void*) current_element);
777 current_element = tmp_element;
795 if(NULL == grouplist) {
return; }
799 posix_free((
void*) (*grouplist)[*num].name);
804 posix_free((
void*) *grouplist);
829 const char* grouppathname = NULL;
832 res = group_get_pathname(&grouppathname, groupfile_name);
835 res =
fu_open_file(grouppathname, &fd, POSIX_O_RDWR | POSIX_O_CREAT,
842 if(!res) { res = group_import_groups(num, grouplist, fs); }
848 posix_free((
void*) grouppathname);
876 const char* grouppathname = NULL;
877 const char* tmppathname = NULL;
880 res = group_get_pathname(&grouppathname, groupfile_name);
881 if(!res) { res = group_get_pathname(&tmppathname, tmpfile_name); }
886 res =
fu_open_file(grouppathname, &fd, POSIX_O_RDWR | POSIX_O_CREAT,
896 POSIX_O_WRONLY | POSIX_O_CREAT | POSIX_O_TRUNC,
907 if(!res && num) { res = group_export_groups(num, grouplist, fs, fs_tmp); }
910 if(!res) { res =
fu_sync(fd_tmp, fs_tmp); }
913 if(!res) { res = posix_rename(tmppathname, grouppathname); }
929 posix_free((
void*) tmppathname);
930 posix_free((
void*) grouppathname);
951 const char* grouppathname = NULL;
952 const char* tmppathname = NULL;
955 posix_ssize_t readlen;
956 const char** array = NULL;
957 const char** array_tmp;
958 size_t array_len = 0;
963 res = group_get_pathname(&grouppathname, groupfile_name);
964 if(!res) { res = group_get_pathname(&tmppathname, tmpfile_name); }
969 res =
fu_open_file(grouppathname, &fd, POSIX_O_RDWR | POSIX_O_CREAT,
984 POSIX_O_WRONLY | POSIX_O_CREAT | POSIX_O_TRUNC,
996 readlen = posix_getline(&line, &len, fs);
999 posix_free((
void*) line);
1000 if (POSIX_ENOMEM == posix_errno)
1002 PRINT_ERROR(
"Cannot allocate memory for group data");
1016 if(NULL != array) { res = 0; }
1021 if(0 >= readlen)
break;
1025 array_tmp = (
const char**)
1026 posix_realloc(array, (array_len + (
size_t) 1)
1027 * (
sizeof(
const char*)));
1028 if(NULL == array_tmp) { posix_free((
void*) line);
break; }
1032 array[array_len++] = line;
1041 qsort((
void*) array, array_len,
sizeof(
const char*), group_compar);
1042 for(i = 0; i < array_len; ++i)
1045 rv = fprintf(fs_tmp,
"%s", array[i]);
1046 if(0 > rv) { res = -1;
break; }
1051 while(array_len) { posix_free((
void*) array[--array_len]); }
1052 posix_free((
void*) array);
1055 if(!res) { res =
fu_sync(fd_tmp, fs_tmp); }
1058 if(!res) { res = posix_rename(tmppathname, grouppathname); }
1074 posix_free((
void*) tmppathname);
1075 posix_free((
void*) grouppathname);
1097 FILE* fs_tmp = NULL;
1098 const char* grouppathname = NULL;
1099 const char* tmppathname = NULL;
1102 posix_ssize_t readlen;
1109 res = group_get_pathname(&grouppathname, groupfile_name);
1110 if(!res) { res = group_get_pathname(&tmppathname, tmpfile_name); }
1115 res =
fu_open_file(grouppathname, &fd, POSIX_O_RDWR | POSIX_O_CREAT,
1125 POSIX_O_WRONLY | POSIX_O_CREAT | POSIX_O_TRUNC,
1142 readlen = posix_getline(&line, &len, fs);
1145 if (POSIX_ENOMEM == posix_errno)
1147 PRINT_ERROR(
"Cannot assign memory to read group file");
1165 if(0 >= readlen)
break;
1169 nlen = strlen(group->
name);
1170 if(!strncmp(line, group->
name, nlen))
1173 if(
':' == line[nlen] ||
'!' == line[nlen])
1177 p = strchr(line, (
int)
'!');
1186 rv = fprintf(fs_tmp,
"%s", line);
1191 if(!res && !found) { res = group_print_entry(fs_tmp, group); }
1195 if(!res) { res =
fu_sync(fd_tmp, fs_tmp); }
1198 if(!res) { res = posix_rename(tmppathname, grouppathname); }
1214 posix_free((
void*) line);
1215 posix_free((
void*) tmppathname);
1216 posix_free((
void*) grouppathname);