#include "conf-update.h" char *get_real_filename(const char *update) { char *file = (char *)calloc(strlen(update) + 1 - strlen("._cfg????_"), sizeof(char)); strncpy(file, update, strrchr(update, '/') - update + 1); strcat(file, strrchr(update, '/') + strlen("._cfg????_") + 1); return file; } char *get_highest_update(char **index, char *update) { // update is just any update of the real file we want to get the highest update for char *real_file = get_real_filename(update); char *my_real_file; char *highest_update = update; int i; for (i=0;!is_last_entry(index[i]);i++) { if (is_valid_entry(index[i])) { my_real_file = get_real_filename(index[i]); if (!strcmp(my_real_file, real_file)) { if (strcmp(index[i], highest_update) > 0) { highest_update = index[i]; } } free(my_real_file); } } free(real_file); return highest_update; } bool is_last_entry(const char *entry) { if (entry == LAST_ENTRY) { return TRUE; } else { return FALSE; } } bool is_valid_entry(const char *entry) { if (entry == LAST_ENTRY || entry == SKIP_ENTRY) { return FALSE; } else { return TRUE; } } void merge(char *update, char **index) { char *real_file = get_real_filename(update); char *my_real_file; int i; exit_error(!rename(update, real_file), update); for (i=0;!is_last_entry(index[i]);i++) { if (is_valid_entry(index[i])) { my_real_file = get_real_filename(index[i]); if (!strcmp(my_real_file, real_file)) { if (strcmp(update, index[i])) { exit_error(!unlink(index[i]), index[i]); } free(index[i]); index[i] = SKIP_ENTRY; } free(my_real_file); } } free(real_file); } int show_diff(char *update) { extern struct configuration config; char *realfile = get_real_filename(update); char *esc_realfile = g_shell_quote(realfile); char *esc_update = g_shell_quote(update); char *cmd = (char *)calloc(strlen(config.diff_tool) + strlen(" % % | ") + strlen(esc_update) + strlen(esc_realfile) + strlen(config.pager) + 1, sizeof(char)); int ret; strcpy(cmd, config.diff_tool); strcat(cmd, " "); strcat(cmd, esc_realfile); strcat(cmd, " "); strcat(cmd, esc_update); if (strcmp(config.pager, "")) { strcat(cmd, " | "); strcat(cmd, config.pager); } ret = system(cmd); free(realfile); g_free(esc_realfile); g_free(esc_update); free(cmd); return ret; } int edit_update(char *update) { extern struct configuration config; char *esc_update = g_shell_quote(update); char *cmd = calloc(strlen(config.edit_tool) + strlen(" ") + strlen(esc_update), sizeof(char)); int ret; strcpy(cmd, config.edit_tool); strcat(cmd, " "); strcat(cmd, esc_update); ret = system(cmd); g_free(esc_update); free(cmd); return ret; } char **merge_interactively(char *update, char **index) { // customized versions are ._cfg????- with a minus instead of a underscore // that way get_real_filename() works without modification extern struct configuration config; char *realfile = get_real_filename(update); char *esc_realfile = g_shell_quote(realfile); char *esc_update = g_shell_quote(update); char *cmd = calloc(strlen("clear ; ") + strlen(config.merge_tool) + 2 * strlen(esc_update) + strlen(esc_realfile) + strlen(" % % %"), sizeof(char)); char *merged, *esc_merged; char **new_index = index; int retval, ct; // interactively merge an interactively merged file? naah. if (*(strstr(update, "._cfg") + strlen("._cfg????")) == '_') { merged = strdup(update); *(strstr(merged, "._cfg") + strlen("._cfg????")) = '-'; esc_merged = g_shell_quote(merged); strcpy(cmd, "clear ; "); strcat(cmd, config.merge_tool); strcat(cmd, " "); strcat(cmd, esc_merged); strcat(cmd, " "); strcat(cmd, esc_realfile); strcat(cmd, " "); strcat(cmd, esc_update); retval = WEXITSTATUS(system(cmd)); if (retval == 0 || retval == 1) { for (ct=0;!is_last_entry(index[ct]);ct++) {} new_index = realloc(index, (ct + 2) * sizeof(char *)); new_index[ct] = strdup(merged); new_index[ct+1] = LAST_ENTRY; } else { // user aborted or error unlink(merged); } free(merged); g_free(esc_merged); } free(cmd); free(realfile); g_free(esc_realfile); g_free(esc_update); return new_index; } void display_help() { char *str = \ "Usage: " PROG_NAME " [options] [location1] [locationN] ...\n\n" "Options:\n" "\t--help (-h) Show this message\n" "\n" "Locations: absolute path to a directory to search through\n" " instead of CONFIG_PROTECT\n" "\n" "Shortcuts: \n" "\tSelecting a directory will select all its updates\n"; fprintf(stderr, "%s", str); exit(EXIT_SUCCESS); }