deborphan -R: Fix keep file corruption

parent 5d8097c8
......@@ -160,70 +160,83 @@ int addkeep(const char* kfile, char** add) {
* memory.
*/
int delkeep(const char* kfile, char** del) {
int fd, i, cnt, j, tmp = 0, shrunk = 0;
int fd, cnt;
struct stat sbuf;
char *fcont, *tok, *pt, *orig;
ssize_t len;
char *fcont, *orig, *end;
if ((fd = open(kfile, O_RDONLY | O_CREAT, 0666 /* let umask handle -w */)) <
0)
return -1;
if (fstat(fd, &sbuf) < 0)
if (fstat(fd, &sbuf) < 0) {
close(fd);
return -1;
}
for (cnt = 0; del[cnt]; cnt++)
;
orig = fcont = malloc((size_t)(sbuf.st_size + 1));
orig = fcont = (char*)malloc(sbuf.st_size + 1);
if (read(fd, fcont, (size_t)sbuf.st_size) < sbuf.st_size) {
ssize_t actually_read = read(fd, fcont, sbuf.st_size);
if (actually_read < 0 || (size_t)actually_read != sbuf.st_size) {
free(fcont);
close(fd);
return -1;
}
end = fcont + sbuf.st_size;
*end = '\0';
if (fcont[strlen(fcont) - 1] != '\n') {
fcont[strlen(fcont)] = '\n';
tmp = 1;
}
char* tok;
while ((tok = strsep(&fcont, "\n"))) {
char* substr = tok;
size_t substrlen;
substr += strspn(substr, " \t");
substrlen = strcspn(substr, " \t\r\n:#");
if (substrlen == 0)
continue;
for (i = 0; i < cnt; i++) {
if (strlen(del[i]) != substrlen)
continue;
if (strncmp(del[i], substr, substrlen) == 0) {
pt = fcont - (strlen(tok) + 1);
shrunk += (strlen(tok) + 1);
for (j = 0; *(fcont + j); j++)
*(pt + j) = *(fcont + j);
if (substrlen > 0) {
for (int i = 0; i < cnt; i++) {
if (strlen(del[i]) != substrlen)
continue;
if (strncmp(del[i], substr, substrlen) == 0) {
// found package to remove from keeplist.
memmove(tok, fcont, end - fcont + 1);
end -= fcont - tok;
fcont = tok;
break;
}
}
}
free(tok);
}
close(fd);
len = sbuf.st_size - shrunk;
if (tmp != 0)
len += 1;
// undo what strsep() did.
fcont = orig;
while (1) {
size_t len = strlen(fcont);
if (fcont + len < end) {
fcont[len] = '\n';
fcont += len;
} else {
break;
}
}
if ((fd = open(kfile, O_WRONLY | O_TRUNC)) < 0) {
free(orig);
return -1;
}
if (write(fd, orig, len) < len) {
ssize_t actually_wrote = write(fd, orig, end - orig);
if (actually_wrote < 0 || (size_t)actually_wrote != (end - orig)) {
error(EXIT_FAILURE, errno,
"Writing keep file failed and may be corrupt now");
free(orig);
close(fd);
return -1;
}
free(orig);
close(fd);
return 0;
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment