You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
gentoo-overlay/app-misc/tdl/files/tdl-1.5.2-main.c.patch

179 lines
4.9 KiB

--- tdl-1.5.2.orig/main.c
+++ tdl-1.5.2/main.c
@@ -80,7 +80,7 @@
return;
}
/*}}}*/
-static volatile void unlock_and_exit(int code)/*{{{*/
+static void unlock_and_exit(int code)/*{{{*/
{
unlock_database();
exit(code);
@@ -237,22 +237,91 @@
}
/*}}}*/
-static void rename_database(char *path)/*{{{*/
+static mode_t get_mode(const char *path); /* prototype */
+/*}}}*/
+static int copy_file_contents(char *pathsrc, char *pathdest) {
+ int src, dest;
+ ssize_t rdsize = 1;
+ char buf[4096];
+
+ src = open(pathsrc, O_RDONLY);
+ if (src == -1) {
+ perror("warning, couldn't open database");
+ return 0;
+ }
+ dest = open(pathdest, O_WRONLY | O_CREAT, get_mode(pathsrc));
+ if (dest == -1) {
+ perror("warning, couldn't open/create backup database");
+ close(src);
+ return 0;
+ }
+ if (ftruncate(dest,0) != 0) {
+ perror("warning, couldn't truncate backup database");
+ close(src);
+ close(dest);
+ return 0;
+ }
+ lseek(src,0,SEEK_SET);
+ lseek(dest,0,SEEK_SET);
+ while (rdsize > 0) {
+ rdsize = read(src, buf, 4096);
+ if (rdsize == -1) {
+ perror("warning, error reading database");
+ close(src);
+ close(dest);
+ return 0;
+ }
+ if (rdsize > 0) {
+ if (write(dest, buf, rdsize) != rdsize) {
+ perror("warning, error writing to backup database");
+ close(src);
+ close(dest);
+ return 0;
+ }
+ }
+ }
+ close(src);
+ close(dest);
+ return 1;
+}
+/*}}}*/
+static int path_is_symlink(char *path) {
+ int i;
+ struct stat s;
+ i = lstat(path, &s);
+ if ((i == 0) && (S_ISLNK(s.st_mode))) {
+ return 1; /* is a symlink */
+ }
+ return 0; /* not a symlink */
+}
+/*}}}*/
+static int rename_database(char *path)/*{{{*/
{
- int len;
+ /* the rename_database function returns 1 if database or/and
+ * database backup file are symlinks; otherwise returns 0 */
+ int len, symlinks;
char *pathbak;
-
+
len = strlen(path);
pathbak = new_array(char, len + 5);
strcpy(pathbak, path);
strcat(pathbak, ".bak");
- if (rename(path, pathbak) < 0) {
- if (is_noisy) {
- perror("warning, couldn't save backup database:");
+
+ symlinks = path_is_symlink(path) | path_is_symlink(pathbak);
+
+ if (symlinks) {
+ if (access(path,F_OK) == 0) {
+ copy_file_contents(path, pathbak);
+ }
+ } else {
+ if (rename(path, pathbak) < 0) {
+ if (is_noisy) {
+ perror("warning, couldn't save backup database:");
+ }
}
}
free(pathbak);
- return;
+ return symlinks;
}
/*}}}*/
static char *executable_name(char *argv0)/*{{{*/
@@ -315,7 +384,7 @@
/*}}}*/
static void save_database(char *path)/*{{{*/
{
- FILE *out;
+ FILE *out = NULL;
int out_fd;
mode_t database_mode;
if (is_loaded && currently_dirty) {
@@ -324,20 +393,34 @@
/* The next line only used to happen if the command wasn't 'create'.
* However, it should quietly fail for create, where the existing database
* doesn't exist */
- rename_database(path);
-
- /* Open database this way so that the permissions from the existing
- database can be duplicated onto the new one in way free of race
- conditions. */
- out_fd = open(path, O_WRONLY | O_CREAT | O_EXCL, database_mode);
- if (out_fd < 0) {
- fprintf(stderr, "Could not open new database %s for writing : %s\n",
- path, strerror(errno));
- unlock_and_exit(1);
+ if (rename_database(path) == 0) {
+ /* database is a regular file */
+ /* Open database this way so that the permissions from the existing
+ database can be duplicated onto the new one in way free of race
+ conditions. */
+ out_fd = open(path, O_WRONLY | O_CREAT | O_EXCL, database_mode);
+ if (out_fd < 0) {
+ fprintf(stderr, "Could not open new database %s for writing : %s\n",
+ path, strerror(errno));
+ unlock_and_exit(1);
+ }
} else {
- /* Normal case */
- out = fdopen(out_fd, "wb");
+ /* database and/or backup database are symlinks */
+ /* we should truncate existing file and write its contents */
+ out_fd = open(path, O_WRONLY | O_CREAT, database_mode);
+ if (out_fd < 0) {
+ fprintf(stderr, "Could not open database %s for writing : %s\n",
+ path, strerror(errno));
+ unlock_and_exit(1);
+ } else {
+ /* Normal case */
+ if (ftruncate(out_fd, 0) != 0) {
+ perror("warning, couldn't truncate database:");
+ unlock_and_exit(1);
+ }
+ }
}
+ out = fdopen(out_fd, "wb");
if (!out) {
fprintf(stderr, "Cannot open database %s for writing\n", path);
unlock_and_exit(1);
@@ -728,6 +811,11 @@
if (!is_loaded && cmds[index].load_db) {
load_database(current_database_path);
+ if (is_interactive && (!is_loaded)) {
+ fprintf(stderr, "error: could not open database. please create a "
+ "database with 'tdl create' before using this tdl command\n");
+ unlock_and_exit(-1);
+ }
}
pp = is_tdl ? (p + 1) : p;