diff --git a/src/tint2conf/properties_rw.c b/src/tint2conf/properties_rw.c index 59a9f9b..30bb3ec 100644 --- a/src/tint2conf/properties_rw.c +++ b/src/tint2conf/properties_rw.c @@ -86,7 +86,7 @@ void config_write_color(FILE *fp, char *name, GdkColor color, int opacity) void config_write_backgrounds(FILE *fp) { - fprintf(fp, "#--------------------------------\n"); + fprintf(fp, "#-------------------------------------\n"); fprintf(fp, "# Backgrounds\n"); int index; @@ -128,7 +128,7 @@ void config_write_backgrounds(FILE *fp) void config_write_panel(FILE *fp) { - fprintf(fp, "#--------------------------------\n"); + fprintf(fp, "#-------------------------------------\n"); fprintf(fp, "# Panel\n"); char *items = get_panel_items(); fprintf(fp, "panel_items = %s\n", items); @@ -219,7 +219,7 @@ void config_write_panel(FILE *fp) void config_write_taskbar(FILE *fp) { - fprintf(fp, "#--------------------------------\n"); + fprintf(fp, "#-------------------------------------\n"); fprintf(fp, "# Taskbar\n"); fprintf(fp, @@ -309,7 +309,7 @@ void config_write_task_background(FILE *fp, char *name, GtkWidget *task_backgrou void config_write_task(FILE *fp) { - fprintf(fp, "#--------------------------------\n"); + fprintf(fp, "#-------------------------------------\n"); fprintf(fp, "# Task\n"); fprintf(fp, "task_text = %d\n", gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(task_show_text)) ? 1 : 0); @@ -398,7 +398,7 @@ void config_write_task(FILE *fp) void config_write_systray(FILE *fp) { - fprintf(fp, "#--------------------------------\n"); + fprintf(fp, "#-------------------------------------\n"); fprintf(fp, "# System tray (notification area)\n"); fprintf(fp, @@ -436,7 +436,7 @@ void config_write_systray(FILE *fp) void config_write_launcher(FILE *fp) { - fprintf(fp, "#--------------------------------\n"); + fprintf(fp, "#-------------------------------------\n"); fprintf(fp, "# Launcher\n"); fprintf(fp, @@ -495,7 +495,7 @@ void config_write_launcher(FILE *fp) void config_write_clock(FILE *fp) { - fprintf(fp, "#--------------------------------\n"); + fprintf(fp, "#-------------------------------------\n"); fprintf(fp, "# Clock\n"); fprintf(fp, "time1_format = %s\n", gtk_entry_get_text(GTK_ENTRY(clock_format_line1))); @@ -527,7 +527,7 @@ void config_write_clock(FILE *fp) void config_write_battery(FILE *fp) { - fprintf(fp, "#--------------------------------\n"); + fprintf(fp, "#-------------------------------------\n"); fprintf(fp, "# Battery\n"); fprintf(fp, "battery_low_status = %g\n", gtk_spin_button_get_value(GTK_SPIN_BUTTON(battery_alert_if_lower))); @@ -552,7 +552,7 @@ void config_write_battery(FILE *fp) void config_write_tooltip(FILE *fp) { - fprintf(fp, "#--------------------------------\n"); + fprintf(fp, "#-------------------------------------\n"); fprintf(fp, "# Tooltip\n"); fprintf(fp, "tooltip_show_timeout = %g\n", gtk_spin_button_get_value(GTK_SPIN_BUTTON(tooltip_show_after))); @@ -575,14 +575,38 @@ void config_write_tooltip(FILE *fp) fprintf(fp, "\n"); } +// Similar to BSD checksum, except we skip the first line (metadata) +unsigned short checksum_txt(FILE *f) +{ + unsigned int checksum = 0; + fseek(f, 0, SEEK_SET); + + // Skip the first line + int c; + do { + c = getc(f); + } while (c != EOF && c != '\n'); + + while ((c = getc(f)) != EOF) { + // Rotate right + checksum = (checksum >> 1) + ((checksum & 1) << 15); + // Update checksum + checksum += c; + // Truncate to 16 bits + checksum &= 0xffff; + } + return checksum; +} + void config_save_file(const char *path) { printf("config_save_file : %s\n", path); FILE *fp; - if ((fp = fopen(path, "wt")) == NULL) + if ((fp = fopen(path, "w+t")) == NULL) return; - fprintf(fp, "#---- Generated by tint2conf ----\n"); + unsigned short checksum = 0; + fprintf(fp, "#---- Generated by tint2conf %04x ----\n", checksum); config_write_backgrounds(fp); config_write_panel(fp); @@ -594,6 +618,11 @@ void config_save_file(const char *path) { config_write_battery(fp); config_write_tooltip(fp); + checksum = checksum_txt(fp); + fseek(fp, 0, SEEK_SET); + fflush(fp); + fprintf(fp, "#---- Generated by tint2conf %04x ----\n", checksum); + fclose(fp); } @@ -608,8 +637,16 @@ gboolean config_is_manual(const char *path) result = TRUE; if (fgets(line, sizeof(line), fp) != NULL) { - if (g_str_equal(line, "#---- Generated by tint2conf ----\n")) { - result = FALSE; + if (!g_regex_match_simple("^#---- Generated by tint2conf [0-9a-f][0-9a-f][0-9a-f][0-9a-f] ----\n$", line, 0, 0)) { + result = TRUE; + } else { + unsigned short checksum1 = checksum_txt(fp); + unsigned short checksum2 = 0; + if (sscanf(line, "#---- Generated by tint2conf %hxu", &checksum2) == 1) { + result = checksum1 != checksum2; + } else { + result = TRUE; + } } } fclose(fp);