Changeset 946058b


Ignore:
Timestamp:
Oct 15, 2009, 8:00:07 PM (15 years ago)
Author:
Karl Ramm <kcr@1ts.org>
Branches:
master, release-1.10, release-1.5, release-1.6, release-1.7, release-1.8, release-1.9
Children:
050d25e
Parents:
6ace255
git-author:
Karl Ramm <kcr@1ts.org> (09/25/09 10:50:17)
git-committer:
Karl Ramm <kcr@1ts.org> (10/15/09 20:00:07)
Message:
rewrite owl_util_file_deleteline

Rewrite owl_util_file_deleteline to be more efficient, use getline, and have
no fixed buffers.
File:
1 edited

Legend:

Unmodified
Added
Removed
  • util.c

    r6ace255 r946058b  
    552552}
    553553
    554 /* Delete the line matching "line" from the named file.  If no such
    555  * line is found the file is left intact.  If backup==1 then create a
    556  * backupfile containing the original contents.  This is an
    557  * inefficient impelementation which reads the entire file into
    558  * memory.
     554/* Delete all lines matching "line" from the named file.  If no such
     555 * line is found the file is left intact.  If backup==1 then leave a
     556 * backup file containing the original contents.  The match is
     557 * case-insensitive.
    559558 *
    560559 * Returns the number of lines removed
     
    562561int owl_util_file_deleteline(const char *filename, const char *line, int backup)
    563562{
    564   char buff[LINE], *text;
    565   char *backupfilename=NULL;
    566   FILE *file, *backupfile=NULL;
    567   int size, newline;
     563  char *backupfile, *newfile, *buf = NULL;
     564  FILE *old, *new;
     565  struct stat st;
    568566  int numremoved = 0;
    569567
    570   /* open the file for reading */
    571   file=fopen(filename, "r");
    572   if (!file) {
    573     owl_function_error("Error opening file %s", filename);
     568  if ((old = fopen(filename, "r")) == NULL) {
     569    owl_function_error("Cannot open %s (for reading): %s",
     570                       filename, strerror(errno));
    574571    return 0;
    575572  }
    576573
    577   /* open the backup file for writing */
     574  if (fstat(fileno(old), &st) != 0) {
     575    owl_function_error("Cannot stat %s: %s", filename, strerror(errno));
     576    return 0;
     577  }
     578
     579  newfile = owl_sprintf("%s.new", filename);
     580  if ((new = fopen(newfile, "w")) == NULL) {
     581    owl_function_error("Cannot open %s (for writing): %s",
     582                       filename, strerror(errno));
     583    free(newfile);
     584    fclose(old);
     585    return 0;
     586  }
     587
     588  if (fchmod(fileno(new), st.st_mode & 0777) != 0) {
     589    owl_function_error("Cannot set permissions on %s: %s",
     590                       filename, strerror(errno));
     591    unlink(newfile);
     592    fclose(new);
     593    free(newfile);
     594    fclose(old);
     595    return 0;
     596  }
     597
     598  while (owl_getline_chomp(&buf, old))
     599    if (strcasecmp(buf, line) != 0)
     600      fprintf(new, "%s\n", buf);
     601    else
     602      numremoved++;
     603
     604  fclose(new);
     605  fclose(old);
     606
    578607  if (backup) {
    579     backupfilename=owl_sprintf("%s.backup", filename);
    580     backupfile=fopen(backupfilename, "w");
    581     if (!backupfile) {
    582       owl_function_error("Error opening file %s for writing", backupfilename);
    583       owl_free(backupfilename);
    584       fclose(file);
     608    backupfile = owl_sprintf("%s.backup", filename);
     609    unlink(backupfile);
     610    if (link(filename, backupfile) != 0) {
     611      owl_function_error("Cannot link %s: %s", backupfile, strerror(errno));
     612      owl_free(backupfile);
     613      unlink(newfile);
     614      owl_free(newfile);
    585615      return 0;
    586616    }
    587   }
    588 
    589   /* we'll read the entire file into memory, minus the line we don't want and
    590    * and at the same time create the backup file if necessary
    591    */
    592   text=owl_malloc(LINE);
    593   strcpy(text, "");
    594   size=LINE;
    595   while (fgets(buff, LINE, file)!=NULL) {
    596     /* strip the newline */
    597     newline=0;
    598     if (buff[0] != '\0' && buff[strlen(buff) - 1] == '\n') {
    599       buff[strlen(buff)-1]='\0';
    600       newline=1;
    601     }
    602    
    603     /* if we don't match the line, add to saved text in memory */
    604     if (strcasecmp(buff, line)) {
    605       size+=LINE;
    606       text=owl_realloc(text, size);
    607       strcat(text, buff);
    608       if (newline) strcat(text, "\n");
    609     } else {
    610       numremoved++;
    611     }
    612 
    613     /* write to backupfile if necessary */
    614     if (backup) {
    615       fputs(buff, backupfile);
    616       if (newline) fputs("\n", backupfile);
    617     }
    618   }
    619   if (backup) fclose(backupfile);
    620   fclose(file);
    621 
    622   /* now rewrite the original file from memory */
    623   file=fopen(filename, "w");
    624   if (!file) {
    625     owl_function_error("WARNING: Error opening %s for writing.  Use %s to restore.", filename, backupfilename);
    626     owl_function_beep();
    627   } else {
    628     fputs(text, file);
    629     fclose(file);
    630   }
    631 
    632   if (backup)
    633     owl_free(backupfilename);
    634   owl_free(text);
     617    owl_free(backupfile);
     618  }
     619
     620  if (rename(newfile, filename) != 0) {
     621    owl_function_error("Cannot move %s to %s: %s",
     622                       newfile, filename, strerror(errno));
     623    numremoved = 0;
     624  }
     625
     626  unlink(newfile);
     627  owl_free(newfile);
    635628
    636629  return numremoved;
Note: See TracChangeset for help on using the changeset viewer.