diff -dur mine-0.24/install.c mine-0.24-patch/install.c --- mine-0.24/install.c 2006-04-27 20:14:38.000000000 +0200 +++ mine-0.24-patch/install.c 2006-04-27 20:15:52.000000000 +0200 @@ -54,16 +54,19 @@ int gem2bunzip[2] = { -1, -1 }; int bunzip2tar[2] = { -1, -1 }; - char * pname = NULL; + char *pname = NULL, *pbasename = NULL; int gem_fd = -1; struct cdb c; int pos, len; int rc; - char *filename; + char *filename = 0; char buffer[1024]; char buffer2[1024]; char buffer3[1024]; + char buffer4[1024]; + char cksums_buf[1024]; + char md5sums_buf[1024]; TAR *t = NULL; BZFILE *b = NULL; @@ -77,8 +80,18 @@ if ( rc <= 0 ) goto error; pos = cdb_datapos(&c); len = cdb_datalen(&c); pname = malloc(len+1); pname[len] = 0; + if (cdb_read(&c, pname, len, pos) == -1) goto error; + if ((pbasename = strchr(pname, ':')) != NULL) + { + int baselen = (pbasename - pname); + pbasename = malloc(baselen+1); + snprintf (pbasename, baselen+1, pname); + pbasename[baselen] = 0; + } else + pbasename = pname; + pipe(gem2bunzip); pipe(bunzip2tar); @@ -152,10 +165,88 @@ } } + snprintf(buffer, sizeof(buffer), "%s/var/adm/flists/%s", root, pname); + FILE *old_flist = fopen(buffer, "r"); + snprintf(buffer, sizeof(buffer), "%s/var/adm/cksums/%s", root, pname); + FILE *old_cksums = fopen(buffer, "r"); + snprintf(buffer, sizeof(buffer), "%s/var/adm/md5sums/%s", root, pname); + FILE *old_md5sums = fopen(buffer, "r"); + + FILE *purgme_flist = 0, *purgme_cksums = 0, *purgme_md5sums = 0; filename = 0; + char *old_filename = 0; + int old_file_printed = 0; while (th_read(t) == 0) { filename = th_get_pathname(t); + + /* Here we check for 'obsolete' files, which are in the old + package version, but not in the new one. Obsolete files are + added to *:legacy packages for easy removal. */ + if (old_flist != NULL && old_filename == NULL && fgets(buffer4, 1024, old_flist) != NULL) + { + fgets(cksums_buf, 1024, old_cksums); + fgets(md5sums_buf, 1024, old_md5sums); + + strtok(buffer4, " \t\n"); + old_filename = strtok(NULL, "\n"); + old_file_printed = 0; + } + if (old_filename != NULL) + { + while (strcmp(old_filename, filename) < 0) + { + snprintf(buffer, sizeof(buffer), "%s/%s", root, old_filename); + struct stat statbuf; + if (stat (buffer, &statbuf) != 0) { /* Ignore */ } + if (! S_ISDIR(statbuf.st_mode)) + { + if (old_file_printed == 0 && purgme_flist == NULL) + { + snprintf(buffer, sizeof(buffer), "%s/var/adm/flists/%s:legacy", root, pbasename); + purgme_flist = fopen(buffer, "a"); + snprintf(buffer, sizeof(buffer), "%s/var/adm/cksums/%s:legacy", root, pbasename); + purgme_cksums = fopen(buffer, "a"); + snprintf(buffer, sizeof(buffer), "%s/var/adm/md5sums/%s:legacy", root, pbasename); + purgme_md5sums = fopen(buffer, "a"); + snprintf(buffer, sizeof(buffer), "%s/var/adm/packages/%s:legacy", root, pbasename); + FILE *purgme_packages = fopen(buffer, "w"); + snprintf(buffer, sizeof(buffer), "%s/var/adm/packages/%s", root, pname); + FILE *old_packages = fopen(buffer, "r"); + + snprintf(buffer, sizeof(buffer), "Package Name and Version: %s:legacy 0000 0\n", pbasename); + fputs(buffer, purgme_packages); + + fgets(buffer, 1024, old_packages); + while (fgets(buffer, 1024, old_packages)) { + if (fputs(buffer, purgme_packages) == EOF) goto error_errno; + } + + fclose(old_packages); + fclose(purgme_packages); + } + + if (old_file_printed == 0) + { + fprintf(purgme_flist, "%s:legacy: %s\n", pbasename, old_filename); + fprintf(purgme_cksums, "%s", cksums_buf); + fprintf(purgme_md5sums, "%s", md5sums_buf); + old_file_printed = 1; + } + } /* ! (S_ISDIR(statbuf.st_mode)) */ + + if (fgets(buffer4, 1024, old_flist) == NULL) break; + + fgets(cksums_buf, 1024, old_cksums); + fgets(md5sums_buf, 1024, old_md5sums); + + strtok(buffer4, " \t\n"); + old_filename = strtok(NULL, "\n"); + old_file_printed = 0; + } + if (strcmp(old_filename, filename) == 0) old_file_printed = 1; + } + snprintf(buffer, sizeof(buffer), "%s/%s", root, filename); snprintf(buffer2, sizeof(buffer), "%s.GEMnew", buffer); snprintf(buffer3, sizeof(buffer), "%s.GEMold", buffer); @@ -221,10 +312,83 @@ } } + if (filename != NULL && old_filename != NULL && + strcmp(old_filename, filename) > 0) + { + if (purgme_flist == NULL) + { + snprintf(buffer, sizeof(buffer), "%s/var/adm/flists/%s:legacy", root, pbasename); + purgme_flist = fopen(buffer, "a"); + snprintf(buffer, sizeof(buffer), "%s/var/adm/cksums/%s:legacy", root, pbasename); + purgme_cksums = fopen(buffer, "a"); + snprintf(buffer, sizeof(buffer), "%s/var/adm/md5sums/%s:legacy", root, pbasename); + purgme_md5sums = fopen(buffer, "a"); + snprintf(buffer, sizeof(buffer), "%s/var/adm/packages/%s:legacy", root, pbasename); + FILE *purgme_packages = fopen(buffer, "w"); + snprintf(buffer, sizeof(buffer), "%s/var/adm/packages/%s", root, pname); + FILE *old_packages = fopen(buffer, "r"); + + snprintf(buffer, sizeof(buffer), "Package Name and Version: %s:legacy 0000 0\n", pbasename); + fputs(buffer, purgme_packages); + + fgets(buffer, 1024, old_packages); + while (fgets(buffer, 1024, old_packages)) { + if (fputs(buffer, purgme_packages) == EOF) goto error_errno; + } + + fclose(old_packages); + fclose(purgme_packages); + } + while (1) { + snprintf(buffer, sizeof(buffer), "%s/%s", root, old_filename); + struct stat statbuf; + if (stat (buffer, &statbuf) != 0) { /* Ignore */ } + if (! S_ISDIR(statbuf.st_mode)) + { + fprintf(purgme_flist, "%s:legacy: %s\n", pbasename, old_filename); + fprintf(purgme_cksums, "%s", cksums_buf); + fprintf(purgme_md5sums, "%s", md5sums_buf); + } + + if (fgets(buffer4, 1024, old_flist) == NULL) break; + + fgets(cksums_buf, 1024, old_cksums); + fgets(md5sums_buf, 1024, old_md5sums); + + strtok(buffer4, " \t\n"); + old_filename = strtok(NULL, "\n"); + old_file_printed = 0; + }; + } + + /* Finish *:legacy package, if existent */ + if (purgme_flist != NULL) + { + fclose(purgme_cksums); + snprintf(buffer, sizeof(buffer), "%s:legacy: var/adm/cksums/%s:legacy\n", pbasename, pbasename); + fprintf(purgme_flist, buffer); + snprintf(buffer, sizeof(buffer), "%s:legacy: var/adm/flists/%s:legacy\n", pbasename, pbasename); + fprintf(purgme_flist, buffer); + snprintf(buffer, sizeof(buffer), "%s:legacy: var/adm/md5sums/%s:legacy\n", pbasename, pbasename); + fprintf(purgme_flist, buffer); + snprintf(buffer, sizeof(buffer), "%s:legacy: var/adm/packages/%s:legacy\n", pbasename, pbasename); + fprintf(purgme_flist, buffer); + fclose(purgme_flist); + + snprintf(buffer2, sizeof(buffer2), "var/adm/flists/%s:legacy", pbasename); + snprintf(buffer, sizeof(buffer), "%s %s\n", md5sum_create(root, buffer2), buffer2); + fprintf(purgme_md5sums, buffer); + fclose(purgme_md5sums); + } + tar_close(t); close(bunzip2tar[0]); cdb_free(&c); close(gem_fd); if ( logfile != NULL ) fclose(logfile); + if ( old_flist != NULL ) fclose(old_flist); + + if (pname != pbasename) free(pbasename); + free(pname); return 0; @@ -233,7 +397,7 @@ error_errno: fprintf(stderr, "While installing GEM file %s%s%s%s: %s\n", package, - filename?" (":"", filename?filename:"", filename?"(":"", + filename?" (":"", filename?filename:"", filename?")":"", errno ? strerror(errno) : "Unknown error"); if ( t != NULL) tar_close(t); if ( gem_fd != -1 ) { cdb_free(&c); close(gem_fd); } diff -dur mine-0.24/TODO mine-0.24-patch/TODO --- mine-0.24/TODO 2006-04-27 20:14:30.000000000 +0200 +++ mine-0.24-patch/TODO 2006-04-27 20:15:56.000000000 +0200 @@ -1,5 +1,7 @@ Todos: - - Remove old files when updating a package (?) + - When mine adds files to a legacy package, it does not remove possible + duplicate entries in var/adm/{flists,cksums,md5sums} resulting in + bogus shared files.