Richard Hughes wrote:
Legend, thanks. Any chance of a Argyll_dev_src.zip code drop at some point please? Thanks.
Hi, attached is a patch for V1.1.1 Graeme Gill.
--- i1pro_imp.old.c 2010-04-29 16:42:19.000000000 +1000 +++ i1pro_imp.c 2010-04-29 16:50:49.000000000 +1000 @@ -42,6 +42,8 @@ See the Munki implementation for an approach to fix this ?? */ +#include <sys/types.h> +#include <sys/stat.h> #include <stdio.h> #include <stdlib.h> #include <ctype.h> @@ -108,6 +110,8 @@ #define HIGHRES_LONG 750 #define HIGHRES_WIDTH (10.0/3.0) /* (The 3.3333 spacing and lanczos2 seems a good combination) */ +#define CALIBRATION_DIR "argyll" /* Directory the instrument calibration files get stored */ + #include "i1pro.h" #include "i1pro_imp.h" @@ -2237,14 +2241,118 @@ } +/* NOTE!! these two routines should be consolidates with the */ +/* very similar ones in munki_imp.c !! */ + +/* Return the path to the calibration save/restore file. */ +/* Return NULL on error. */ +/* Free after used */ +static char *i1pro_cal_name(i1pro *p) { + i1proimp *m = (i1proimp *)p->m; + char *cal_dir3 = NULL; /* Directory */ + char *cal_dir2 = NULL; /* Directory */ + char *cal_dir1 = NULL; /* Directory */ + char cal_name[20+1]; /* Name */ + char *cal_path = NULL; /* Allocated overal path */ + int cpl = 0; /* cal path length */ + + /* Create the file name */ + sprintf(cal_name, ".i1p_%d.cal", m->serno); + + if ((cal_dir3 = getenv("XDG_CACHE_HOME")) != NULL && cal_dir3[0] != '\000') { + cal_dir1 = CALIBRATION_DIR; + } else { + if ((cal_dir3 = getenv("HOME")) != NULL && cal_dir3[0] != '\000') { + cal_dir2 = ".cache"; + cal_dir1 = CALIBRATION_DIR; + } else { + cal_dir3 = NULL; + } + } + cpl += (cal_dir3 != NULL) ? strlen(cal_dir3) + 1 : 0; + cpl += (cal_dir2 != NULL) ? strlen(cal_dir2) + 1 : 0; + cpl += (cal_dir1 != NULL) ? strlen(cal_dir1) + 1 : 0; + cpl += strlen(cal_name) + 1; + + if ((cal_path = malloc(cpl)) == NULL) + return NULL; + + cal_path[0] = '\000'; + if (cal_dir3 != NULL) + strcat(cal_path, cal_dir3); + if (cal_dir2 != NULL) { + if (strlen(cal_path) > 0 && cal_path[strlen(cal_path)-1] != '/') + strcat(cal_path, "/"); + strcat(cal_path, cal_dir2); + } + if (cal_dir1 != NULL) { + if (strlen(cal_path) > 0 && cal_path[strlen(cal_path)-1] != '/') + strcat(cal_path, "/"); + strcat(cal_path, cal_dir1); + } + if (strlen(cal_path) > 0 && cal_path[strlen(cal_path)-1] != '/') + strcat(cal_path, "/"); + strcat(cal_path, cal_name); + + return cal_path; +} + +/* Given the path to a file, ensure that all the parent directories */ +/* are created. return nz on error */ +static int i1pro_mkpdirs(char *path) { + char *pp = path; +#if defined (UNIX) + struct stat sbuf; + mode_t mode = 0700; /* Default directory mode */ +#else + struct _stat sbuf; +#endif + +#if !defined (UNIX) + if (*pp != '\000' /* Skip drive number */ + && ((*pp >= 'a' && *pp <= 'z') || (*pp >= 'A' && *pp <= 'Z')) + && pp[1] == ':') + pp += 2; +#endif + if (*pp == '/') + pp++; /* Skip root directory */ + for (;pp != NULL && *pp != '\000';) { + if ((pp = strchr(pp, '/')) != NULL) { + *pp = '\000'; +#if defined (UNIX) + if (stat(path,&sbuf) != 0) +#else + if (_stat(path,&sbuf) != 0) +#endif + { +#if defined (UNIX) + if (mkdir(path, mode) != 0) +#else + if (_mkdir(path) != 0) +#endif + { + return 1; + } + } +#if defined (UNIX) + else + mode = sbuf.st_mode; +#endif + *pp = '/'; + pp++; + } + } + return 0; +} + + i1pro_code i1pro_save_calibration(i1pro *p) { i1proimp *m = (i1proimp *)p->m; i1pro_code ev = I1PRO_OK; i1pro_state *s; int i, j; - char fname[MAXNAMEL+1]; char nmode[10]; - char *path; + char *cal_path; FILE *fp; i1pnonv x; int ss; @@ -2254,18 +2362,19 @@ #if defined(O_BINARY) || defined(_O_BINARY) strcat(nmode, "b"); #endif - /* Use global exe_path setup by set_exe_path(argv[0]) */ - /* to locate file in same directory as the executable. */ - if ((strlen(exe_path) + 15) > MAXNAMEL) { - DBG((dbgo,"i1pro_save_calibration can't open cal file because path is too long\n")); + + if ((cal_path = i1pro_cal_name(p)) == NULL) return I1PRO_INT_CAL_SAVE; - } - sprintf(fname, "%s.i1p_%d.cal", exe_path, m->serno); - DBG((dbgo,"i1pro_save_calibration saving to file '%s'\n",fname)); + DBG((dbgo,"i1pro_save_calibration saving to file '%s'\n",cal_path)); + + if (i1pro_mkpdirs(cal_path)) { + return I1PRO_INT_CAL_SAVE; + } - if ((fp = fopen(fname, nmode)) == NULL) { + if ((fp = fopen(cal_path, nmode)) == NULL) { DBG((dbgo,"i1pro_save_calibration failed to open file for writing\n")); + free(cal_path); return I1PRO_INT_CAL_SAVE; } @@ -2333,12 +2442,14 @@ if (x.ef != 0) { DBG((dbgo,"Writing calibration file failed\n")) + return I1PRO_INT_CAL_SAVE; fclose(fp); - delete_file(fname); + delete_file(cal_path); } else { fclose(fp); DBG((dbgo,"Writing calibration file done\n")) } + free(cal_path); return ev; } @@ -2349,9 +2460,8 @@ i1pro_code ev = I1PRO_OK; i1pro_state *s, ts; int i, j; - char fname[MAXNAMEL+1]; char nmode[10]; - char *path; + char *cal_path; FILE *fp; i1pnonv x; int argyllversion; @@ -2361,21 +2471,17 @@ #if defined(O_BINARY) || defined(_O_BINARY) strcat(nmode, "b"); #endif - /* Use global exe_path setup by set_exe_path(argv[0]) */ - /* to locate file in same directory as the executable. */ - if ((strlen(exe_path) + 15) > MAXNAMEL) { - DBG((dbgo,"i1pro_restore_calibration can't open cal file because path is too long\n")); + if ((cal_path = i1pro_cal_name(p)) == NULL) return I1PRO_INT_CAL_RESTORE; - } - sprintf(fname, "%s.i1p_%d.cal", exe_path, m->serno); DBG((dbgo,"i1pro_restore_calibration restoring from file '%s'\n",fname)); - if ((fp = fopen(fname, nmode)) == NULL) { + if ((fp = fopen(cal_path, nmode)) == NULL) { DBG((dbgo,"i1pro_restore_calibration failed to open file for reading\n")); + free(cal_path); return I1PRO_INT_CAL_RESTORE; } - + x.ef = 0; x.chsum = 0; @@ -2628,6 +2734,7 @@ reserr:; fclose(fp); + free(cal_path); return ev; } --- munki_imp.old.c 2010-04-29 16:42:40.000000000 +1000 +++ munki_imp.c 2010-04-29 16:51:42.000000000 +1000 @@ -38,6 +38,8 @@ */ +#include <sys/types.h> +#include <sys/stat.h> #include <stdio.h> #include <stdlib.h> #include <ctype.h> @@ -120,6 +122,8 @@ #define HIGHRES_LONG 750 #define HIGHRES_WIDTH (10.0/3.0) /* (The 3.3333 spacing and lanczos2 seems a good combination) */ +#define CALIBRATION_DIR "argyll" /* Directory the instrument calibration files get stored */ + #include "munki.h" #include "munki_imp.h" @@ -1967,15 +1971,115 @@ } } +/* NOTE!! these two routines should be consolidates with the */ +/* very similar ones in i1pro_imp.c !! */ + +/* Return the path to the calibration save/restore file. */ +/* Return NULL on error. */ +/* Free after used */ +static char *munki_cal_name(munki *p) { + munkiimp *m = (munkiimp *)p->m; + char *cal_dir3 = NULL; /* Directory */ + char *cal_dir2 = NULL; /* Directory */ + char *cal_dir1 = NULL; /* Directory */ + char cal_name[20+1]; /* Name */ + char *cal_path = NULL; /* Allocated overal path */ + int cpl = 0; /* cal path length */ + + /* Create the file name */ + sprintf(cal_name, ".mk_%s.cal", m->serno); + + if ((cal_dir3 = getenv("XDG_CACHE_HOME")) != NULL && cal_dir3[0] != '\000') { + cal_dir1 = CALIBRATION_DIR; + } else { + if ((cal_dir3 = getenv("HOME")) != NULL && cal_dir3[0] != '\000') { + cal_dir2 = ".cache"; + cal_dir1 = CALIBRATION_DIR; + } else { + cal_dir3 = NULL; + } + } + cpl += (cal_dir3 != NULL) ? strlen(cal_dir3) + 1 : 0; + cpl += (cal_dir2 != NULL) ? strlen(cal_dir2) + 1 : 0; + cpl += (cal_dir1 != NULL) ? strlen(cal_dir1) + 1 : 0; + cpl += strlen(cal_name) + 1; + + if ((cal_path = malloc(cpl)) == NULL) + return NULL; + + cal_path[0] = '\000'; + if (cal_dir3 != NULL) + strcat(cal_path, cal_dir3); + if (cal_dir2 != NULL) { + if (strlen(cal_path) > 0 && cal_path[strlen(cal_path)-1] != '/') + strcat(cal_path, "/"); + strcat(cal_path, cal_dir2); + } + if (cal_dir1 != NULL) { + if (strlen(cal_path) > 0 && cal_path[strlen(cal_path)-1] != '/') + strcat(cal_path, "/"); + strcat(cal_path, cal_dir1); + } + if (strlen(cal_path) > 0 && cal_path[strlen(cal_path)-1] != '/') + strcat(cal_path, "/"); + strcat(cal_path, cal_name); + + return cal_path; +} + +/* Given the path to a file, ensure that all the parent directories */ +/* are created. return nz on error */ +static int munki_mkpdirs(char *path) { + char *pp = path; +#if defined (UNIX) + struct stat sbuf; + mode_t mode = 0700; /* Default directory mode */ +#else + struct _stat sbuf; +#endif + +#if !defined (UNIX) + if (*pp != '\000' /* Skip drive number */ + && ((*pp >= 'a' && *pp <= 'z') || (*pp >= 'A' && *pp <= 'Z')) + && pp[1] == ':') + pp += 2; +#endif + if (*pp == '/') + pp++; /* Skip root directory */ + for (;pp != NULL && *pp != '\000';) { + if ((pp = strchr(pp, '/')) != NULL) { + *pp = '\000'; +#if defined (UNIX) + if (stat(path,&sbuf) != 0) +#else + if (_stat(path,&sbuf) != 0) +#endif + { +#if defined (UNIX) + if (mkdir(path, mode) != 0) +#else + if (_mkdir(path) != 0) +#endif + return 1; + } +#if defined (UNIX) + else + mode = sbuf.st_mode; +#endif + *pp = '/'; + pp++; + } + } + return 0; +} munki_code munki_save_calibration(munki *p) { munkiimp *m = (munkiimp *)p->m; munki_code ev = MUNKI_OK; munki_state *s; int i, j; - char fname[MAXNAMEL+1]; char nmode[10]; - char *path; + char *cal_path = NULL; /* Allocated overal path */ FILE *fp; i1pnonv x; int ss; @@ -1985,18 +2089,18 @@ #if defined(O_BINARY) || defined(_O_BINARY) strcat(nmode, "b"); #endif - /* Use global exe_path setup by set_exe_path(argv[0]) */ - /* to locate file in same directory as the executable. */ - if ((strlen(exe_path) + 15) > MAXNAMEL) { - DBG((dbgo,"munki_save_calibration can't open cal file because path is too long\n")); + + if ((cal_path = munki_cal_name(p)) == NULL) return MUNKI_INT_CAL_SAVE; - } - sprintf(fname, "%s.mk_%s.cal", exe_path, m->serno); - DBG((dbgo,"munki_save_calibration saving to file '%s'\n",fname)); + DBG((dbgo,"munki_save_calibration saving to file '%s'\n",cal_path)); - if ((fp = fopen(fname, nmode)) == NULL) { + if (munki_mkpdirs(cal_path)) + return MUNKI_INT_CAL_SAVE; + + if ((fp = fopen(cal_path, nmode)) == NULL) { DBG((dbgo,"munki_save_calibration failed to open file for writing\n")); + free(cal_path); return MUNKI_INT_CAL_SAVE; } @@ -2069,11 +2173,12 @@ if (x.ef != 0) { DBG((dbgo,"Writing calibration file failed\n")) fclose(fp); - delete_file(fname); + delete_file(cal_path); } else { fclose(fp); DBG((dbgo,"Writing calibration file done\n")) } + free(cal_path); return ev; } @@ -2084,9 +2189,8 @@ munki_code ev = MUNKI_OK; munki_state *s, ts; int i, j; - char fname[MAXNAMEL+1]; char nmode[10]; - char *path; + char *cal_path; FILE *fp; i1pnonv x; int argyllversion; @@ -2097,20 +2201,18 @@ #if defined(O_BINARY) || defined(_O_BINARY) strcat(nmode, "b"); #endif - /* Use global exe_path setup by set_exe_path(argv[0]) */ - /* to locate file in same directory as the executable. */ - if ((strlen(exe_path) + 15) > MAXNAMEL) { - DBG((dbgo,"munki_restore_calibration can't open cal file because path is too long\n")); + + if ((cal_path = munki_cal_name(p)) == NULL) return MUNKI_INT_CAL_RESTORE; - } - sprintf(fname, "%s.mk_%s.cal", exe_path, m->serno); - DBG((dbgo,"munki_restore_calibration restoring from file '%s'\n",fname)); + DBG((dbgo,"munki_restore_calibration restoring from file '%s'\n",cal_path)); - if ((fp = fopen(fname, nmode)) == NULL) { + if ((fp = fopen(cal_path, nmode)) == NULL) { DBG((dbgo,"munki_restore_calibration failed to open file for reading\n")); + free(cal_path); return MUNKI_INT_CAL_RESTORE; } + free(cal_path); x.ef = 0; x.chsum = 0;