Index: config.c
===================================================================
RCS file: /home/lindes/src/cvs/src/otherware/redhat/logrotate/config.c,v
retrieving revision 1.1.1.1
retrieving revision 1.2
diff -c -r1.1.1.1 -r1.2
*** /tmp/T00oS92v	Fri Apr  9 19:31:43 1999
--- /tmp/T13nwJu_	Fri Apr  9 19:31:43 1999
***************
*** 357,362 ****
--- 357,370 ----
  		newlog->oldDir = NULL;
  
  		*endtag = oldchar, start = endtag;
+ 	    } else if (!strcmp(start, "mailfirst")) {
+ 		newlog->flags |= LOG_FLAG_MAILFIRST;
+ 
+ 		*endtag = oldchar, start = endtag;
+ 	    } else if (!strcmp(start, "maillast")) {
+ 		newlog->flags &= ~LOG_FLAG_MAILFIRST;
+ 
+ 		*endtag = oldchar, start = endtag;
  	    } else if (!strcmp(start, "create")) {
  		*endtag = oldchar, start = endtag;
  
Index: logrotate.8
===================================================================
RCS file: /home/lindes/src/cvs/src/otherware/redhat/logrotate/logrotate.8,v
retrieving revision 1.1.1.1
retrieving revision 1.2
diff -c -r1.1.1.1 -r1.2
*** /tmp/T0CGcus_	Fri Apr  9 19:31:43 1999
--- /tmp/T1L4y3X_	Fri Apr  9 19:31:43 1999
***************
*** 98,104 ****
  The next section defines the parameters for \fI/var/log/httpd/access.log\fR.
  It is rotated whenever is grows over 100k is size, and the old logs
  files are mailed (uncompressed) to www@my.org after going through 5
! rotations, rather then being removed. Likewise, any errors that occur
  while processing the log file are also mailed to www@my.org (overriding
  the global \fIerrors\fR directive). 
  
--- 98,104 ----
  The next section defines the parameters for \fI/var/log/httpd/access.log\fR.
  It is rotated whenever is grows over 100k is size, and the old logs
  files are mailed (uncompressed) to www@my.org after going through 5
! rotations, rather than being removed. Likewise, any errors that occur
  while processing the log file are also mailed to www@my.org (overriding
  the global \fIerrors\fR directive). 
  
***************
*** 163,173 ****
  
  .TP
  \fBmail \fIaddress\fR
! When a log is rotated out-of-existence, it is mailed to \fIaddress\fR. If
! no mail should be generated by a particular log, the \fBnomail\fR directive
! may be used.
  
  .TP
  \fBmonthly\fR
  Log files are rotated the first time \fBlogrotate\fR is run in a month 
  (this is normally on the first day of the month).
--- 163,184 ----
  
  .TP
  \fBmail \fIaddress\fR
! When a log is rotated out-of-existence (or earlier, see
! \fBmailfirst\fR and \fBmaillast\fR), it is mailed to \fIaddress\fR.
! If no mail should be generated by a particular log, the \fBnomail\fR
! directive may be used.
  
  .TP
+ \fBmailfirst\fR
+ When using the \fBmail\fR command, mail the about-to-be-rotated file,
+ instead of the about-to-expire file.
+ 
+ .TP
+ \fBmaillast\fR
+ When using the \fBmail\fR command, mail the about-to-expire file,
+ instead of the about-to-be-rotated file (this is the default).
+ 
+ .TP
  \fBmonthly\fR
  Log files are rotated the first time \fBlogrotate\fR is run in a month 
  (this is normally on the first day of the month).
***************
*** 257,259 ****
--- 268,274 ----
  .nf
  Erik Troan <ewt@redhat.com>
  .fi
+ 
+ .SH BUGS
+ when \fBmailfirst\fR is in use, we should really rotate the log file
+ before sending the mail.
Index: logrotate.c
===================================================================
RCS file: /home/lindes/src/cvs/src/otherware/redhat/logrotate/logrotate.c,v
retrieving revision 1.1.1.1
retrieving revision 1.3
diff -c -r1.1.1.1 -r1.3
*** /tmp/T00c33lq	Fri Apr  9 19:31:43 1999
--- /tmp/T1dNzp9_	Fri Apr  9 19:31:43 1999
***************
*** 26,32 ****
  
  int debug = 0;
  
! static logState * findState(char * fn, logState ** statesPtr, 
  			    int * numStatesPtr) {
      int i;
      logState * states = *statesPtr;
--- 26,32 ----
  
  int debug = 0;
  
! static logState * findState(char * fn, logState ** statesPtr,
  			    int * numStatesPtr) {
      int i;
      logState * states = *statesPtr;
***************
*** 35,41 ****
      struct tm now = *localtime(&nowSecs);
      time_t lr_time;
  
!     for (i = 0; i < numStates; i++) 
  	if (!strcmp(fn, states[i].fn)) break;
  
      if (i == numStates) {
--- 35,41 ----
      struct tm now = *localtime(&nowSecs);
      time_t lr_time;
  
!     for (i = 0; i < numStates; i++)
  	if (!strcmp(fn, states[i].fn)) break;
  
      if (i == numStates) {
***************
*** 67,73 ****
      struct stat sb;
  
      if (debug) {
! 	message(MESS_DEBUG, "running script with arg %s: \"%s\"\n", 
  		logfn, script);
  	return 0;
      }
--- 67,73 ----
      struct stat sb;
  
      if (debug) {
! 	message(MESS_DEBUG, "running script with arg %s: \"%s\"\n",
  		logfn, script);
  	return 0;
      }
***************
*** 115,121 ****
      return rc;
  }
  
! int rotateSingleLog(logInfo * log, int logNum, logState ** statesPtr, 
  		    int * numStatesPtr, FILE * errorFile) {
      struct stat sb;
      time_t nowSecs = time(NULL);
--- 115,121 ----
      return rc;
  }
  
! int rotateSingleLog(logInfo * log, int logNum, logState ** statesPtr,
  		    int * numStatesPtr, FILE * errorFile) {
      struct stat sb;
      time_t nowSecs = time(NULL);
***************
*** 139,145 ****
      message(MESS_DEBUG, "rotating file %s\n", log->files[logNum]);
  
      if (log->flags & LOG_FLAG_COMPRESS) ext = COMPRESS_EXT;
!     
      if (stat(log->files[logNum], &sb)) {
  	fprintf(errorFile, "stat of %s failed: %s\n", log->files[logNum],
  		strerror(errno));
--- 139,145 ----
      message(MESS_DEBUG, "rotating file %s\n", log->files[logNum]);
  
      if (log->flags & LOG_FLAG_COMPRESS) ext = COMPRESS_EXT;
! 
      if (stat(log->files[logNum], &sb)) {
  	fprintf(errorFile, "stat of %s failed: %s\n", log->files[logNum],
  		strerror(errno));
***************
*** 151,157 ****
  
  	if (log->criterium == ROT_SIZE) {
  	    doRotate = (sb.st_size >= log->threshhold);
! 	} else if (state->lastRotated.tm_year != now.tm_year || 
  		   state->lastRotated.tm_mon != now.tm_mon ||
  		   state->lastRotated.tm_mday != now.tm_mday) {
  	    switch (log->criterium) {
--- 151,157 ----
  
  	if (log->criterium == ROT_SIZE) {
  	    doRotate = (sb.st_size >= log->threshhold);
! 	} else if (state->lastRotated.tm_year != now.tm_year ||
  		   state->lastRotated.tm_mon != now.tm_mon ||
  		   state->lastRotated.tm_mday != now.tm_mday) {
  	    switch (log->criterium) {
***************
*** 160,166 ****
  		      1) the current weekday is before the weekday of the
  			 last rotation
  		      2) more then a week has passed since the last
! 			 rotation 
  		*/
  		doRotate = ((now.tm_wday < state->lastRotated.tm_wday) ||
  			    ((mktime(&now) - mktime(&state->lastRotated)) >
--- 160,166 ----
  		      1) the current weekday is before the weekday of the
  			 last rotation
  		      2) more then a week has passed since the last
! 			 rotation
  		*/
  		doRotate = ((now.tm_wday < state->lastRotated.tm_wday) ||
  			    ((mktime(&now) - mktime(&state->lastRotated)) >
***************
*** 205,215 ****
  		dirName = ourDirName(log->files[logNum]);
  	    baseName = ourBaseName(log->files[logNum]);
  
! 	    oldName = alloca(strlen(dirName) + strlen(baseName) + 
  				strlen(log->files[logNum]) + 10);
! 	    newName = alloca(strlen(dirName) + strlen(baseName) + 
  				strlen(log->files[logNum]) + 10);
! 	    disposeName = alloca(strlen(dirName) + strlen(baseName) + 
  				strlen(log->files[logNum]) + 10);
  
  	    /* First compress the previous log when necessary */
--- 205,215 ----
  		dirName = ourDirName(log->files[logNum]);
  	    baseName = ourBaseName(log->files[logNum]);
  
! 	    oldName = alloca(strlen(dirName) + strlen(baseName) +
  				strlen(log->files[logNum]) + 10);
! 	    newName = alloca(strlen(dirName) + strlen(baseName) +
  				strlen(log->files[logNum]) + 10);
! 	    disposeName = alloca(strlen(dirName) + strlen(baseName) +
  				strlen(log->files[logNum]) + 10);
  
  	    /* First compress the previous log when necessary */
***************
*** 272,278 ****
  		message(MESS_DEBUG, "file %s doesn't exist -- won't try "
  			"dispose of it\n", disposeName);
  		disposeName = NULL;
! 	    } 
  
  	    free(dirName);
  	}
--- 272,278 ----
  		message(MESS_DEBUG, "file %s doesn't exist -- won't try "
  			"dispose of it\n", disposeName);
  		disposeName = NULL;
! 	    }
  
  	    free(dirName);
  	}
***************
*** 279,295 ****
  
  	if (!hasErrors && log->logAddress && disposeName) {
  	    char * command;
  
! 	    command = alloca(strlen(disposeName) + 100 + 
  			     strlen(UNCOMPRESS_PIPE));
  
! 	    if (log->flags & LOG_FLAG_COMPRESS)
! 		sprintf(command, "%s < %s | /bin/mail -s '%s' %s", 
! 			    UNCOMPRESS_PIPE, disposeName, log->files[logNum],
! 			    log->logAddress);
  	    else
! 		sprintf(command, "/bin/mail -s '%s' %s < %s", disposeName, 
! 			    log->logAddress, disposeName);
  
  	    message(MESS_DEBUG, "executing: \"%s\"\n", command);
  
--- 279,306 ----
  
  	if (!hasErrors && log->logAddress && disposeName) {
  	    char * command;
+ 	    char * mailfile;
  
! 	    if(log->flags & LOG_FLAG_MAILFIRST)
! 		/* Note, this means we're mailing an active log...  So
! 		 * it's possible that we might send incomplete mail.
! 		 * This should probably all be moved to right before the
! 		 * disposal of the last file. */
! 	    	mailfile	= log->files[logNum];
! 	    else
! 	    	mailfile	= disposeName;
! 
! 	    command = alloca(strlen(mailfile) + 100 +
  			     strlen(UNCOMPRESS_PIPE));
  
! 	    if (log->flags & LOG_FLAG_COMPRESS &&
! 		    !(log->flags & LOG_FLAG_MAILFIRST))
! 		sprintf(command, "%s < %s | /bin/mail -s '%s' %s",
! 			    UNCOMPRESS_PIPE, mailfile,
! 			    mailfile, log->logAddress);
  	    else
! 		sprintf(command, "/bin/mail -s '%s' %s < %s",
! 			    mailfile, log->logAddress, mailfile);
  
  	    message(MESS_DEBUG, "executing: \"%s\"\n", command);
  
***************
*** 296,305 ****
  	    if (!debug && system(command)) {
  		sprintf(newName, "%s.%d", log->files[logNum], getpid());
  		fprintf(errorFile, "Failed to mail %s to %s!\n",
! 			disposeName, log->logAddress);
  
  		hasErrors = 1;
! 	    } 
  	}
  
  	if (!hasErrors && disposeName) {
--- 307,316 ----
  	    if (!debug && system(command)) {
  		sprintf(newName, "%s.%d", log->files[logNum], getpid());
  		fprintf(errorFile, "Failed to mail %s to %s!\n",
! 			mailfile, log->logAddress);
  
  		hasErrors = 1;
! 	    }
  	}
  
  	if (!hasErrors && disposeName) {
***************
*** 316,328 ****
  	    if (log->pre) {
  		message(MESS_DEBUG, "running prerotate script\n");
  		if (runScript(log->files[logNum], log->pre)) {
! 		    fprintf(errorFile, "error running prerotate script -- 
  				leaving old log in place\n");
  		    hasErrors = 1;
  		}
  	    }
  
! 	    message(MESS_DEBUG, "renaming %s to %s\n", log->files[logNum], 
  		    finalName);
  
  	    if (!debug && !hasErrors && rename(log->files[logNum], finalName)) {
--- 327,339 ----
  	    if (log->pre) {
  		message(MESS_DEBUG, "running prerotate script\n");
  		if (runScript(log->files[logNum], log->pre)) {
! 		    fprintf(errorFile, "error running prerotate script --
  				leaving old log in place\n");
  		    hasErrors = 1;
  		}
  	    }
  
! 	    message(MESS_DEBUG, "renaming %s to %s\n", log->files[logNum],
  		    finalName);
  
  	    if (!debug && !hasErrors && rename(log->files[logNum], finalName)) {
***************
*** 335,351 ****
  		    createUid = sb.st_uid;
  		else
  		    createUid = log->createUid;
! 	    
  		if (log->createGid == NO_GID)
  		    createGid = sb.st_gid;
  		else
  		    createGid = log->createGid;
! 	    
  		if (log->createMode == NO_MODE)
  		    createMode = sb.st_mode & 0777;
  		else
  		    createMode = log->createMode;
! 	    
  		message(MESS_DEBUG, "creating new log mode = 0%o uid = %d "
  			"gid = %d\n", createMode, createUid, createGid);
  
--- 346,362 ----
  		    createUid = sb.st_uid;
  		else
  		    createUid = log->createUid;
! 
  		if (log->createGid == NO_GID)
  		    createGid = sb.st_gid;
  		else
  		    createGid = log->createGid;
! 
  		if (log->createMode == NO_MODE)
  		    createMode = sb.st_mode & 0777;
  		else
  		    createMode = log->createMode;
! 
  		message(MESS_DEBUG, "creating new log mode = 0%o uid = %d "
  			"gid = %d\n", createMode, createUid, createGid);
  
***************
*** 352,364 ****
  		if (!debug) {
  		    fd = open(log->files[logNum], O_CREAT | O_RDWR, createMode);
  		    if (fd < 0) {
! 			message(MESS_ERROR, "error creating %s: %s\n", 
  				log->files[logNum], strerror(errno));
  			hasErrors = 1;
  		    } else {
  			if (fchown(fd, createUid, createGid)) {
  			    message(MESS_ERROR, "error setting owner of "
! 				    "%s: %s\n", log->files[logNum], 
  				     strerror(errno));
  			    hasErrors = 1;
  			}
--- 363,375 ----
  		if (!debug) {
  		    fd = open(log->files[logNum], O_CREAT | O_RDWR, createMode);
  		    if (fd < 0) {
! 			message(MESS_ERROR, "error creating %s: %s\n",
  				log->files[logNum], strerror(errno));
  			hasErrors = 1;
  		    } else {
  			if (fchown(fd, createUid, createGid)) {
  			    message(MESS_ERROR, "error setting owner of "
! 				    "%s: %s\n", log->files[logNum],
  				     strerror(errno));
  			    hasErrors = 1;
  			}
***************
*** 386,392 ****
  		sprintf(command, "%s %s", COMPRESS_COMMAND, finalName);
  		message(MESS_DEBUG, "compressing new log with: %s\n", command);
  		if (!debug && system(command)) {
! 		    fprintf(errorFile, "failed to compress log %s\n", 
  				finalName);
  		    hasErrors = 1;
  		}
--- 397,403 ----
  		sprintf(command, "%s %s", COMPRESS_COMMAND, finalName);
  		message(MESS_DEBUG, "compressing new log with: %s\n", command);
  		if (!debug && system(command)) {
! 		    fprintf(errorFile, "failed to compress log %s\n",
  				finalName);
  		    hasErrors = 1;
  		}
***************
*** 422,436 ****
  	break;
      }
  
!     if (log->rotateCount) 
  	message(MESS_DEBUG, "(%d rotations)\n", log->rotateCount);
      else
  	message(MESS_DEBUG, "(no old logs will be kept)\n");
  
!     if (log->oldDir) 
  	message(MESS_DEBUG, "olddir is %s ", log->oldDir);
  
!     if (log->flags & LOG_FLAG_IFEMPTY) 
  	message(MESS_DEBUG, "empty log files are rotated ");
      else
  	message(MESS_DEBUG, "empty log files are not rotated ");
--- 433,447 ----
  	break;
      }
  
!     if (log->rotateCount)
  	message(MESS_DEBUG, "(%d rotations)\n", log->rotateCount);
      else
  	message(MESS_DEBUG, "(no old logs will be kept)\n");
  
!     if (log->oldDir)
  	message(MESS_DEBUG, "olddir is %s ", log->oldDir);
  
!     if (log->flags & LOG_FLAG_IFEMPTY)
  	message(MESS_DEBUG, "empty log files are rotated ");
      else
  	message(MESS_DEBUG, "empty log files are not rotated ");
***************
*** 452,458 ****
  			errorFileName);
  	    return 1;
  	}
! 	
  	if (!debug) {
  	    oldstderr = dup(2);
  	    dup2(newerr, 2);
--- 463,469 ----
  			errorFileName);
  	    return 1;
  	}
! 
  	if (!debug) {
  	    oldstderr = dup(2);
  	    dup2(newerr, 2);
***************
*** 473,479 ****
      }
  
      for (i = 0; i < log->numFiles; i++)
! 	hasErrors |= rotateSingleLog(log, i, statesPtr, numStatesPtr, 
  					errorFile);
  
      if (log->errAddress && !debug) {
--- 484,490 ----
      }
  
      for (i = 0; i < log->numFiles; i++)
! 	hasErrors |= rotateSingleLog(log, i, statesPtr, numStatesPtr,
  					errorFile);
  
      if (log->errAddress && !debug) {
***************
*** 502,508 ****
      return hasErrors;
  }
  
! static int writeState(char * stateFilename, logState * states, 
  		      int numStates) {
      FILE * f;
      int i;
--- 513,519 ----
      return hasErrors;
  }
  
! static int writeState(char * stateFilename, logState * states,
  		      int numStates) {
      FILE * f;
      int i;
***************
*** 509,515 ****
  
      f = fopen(stateFilename, "w");
      if (!f) {
! 	message(MESS_ERROR, "error creating state file %s: %s\n", 
  		    stateFilename, strerror(errno));
  	return 1;
      }
--- 520,526 ----
  
      f = fopen(stateFilename, "w");
      if (!f) {
! 	message(MESS_ERROR, "error creating state file %s: %s\n",
  		    stateFilename, strerror(errno));
  	return 1;
      }
***************
*** 517,523 ****
      fprintf(f, "logrotate state -- version 1\n");
  
      for (i = 0; i < numStates; i++) {
! 	fprintf(f, "%s %d-%d-%d\n", states[i].fn, 
  		states[i].lastRotated.tm_year + 1900,
  		states[i].lastRotated.tm_mon + 1,
  		states[i].lastRotated.tm_mday);
--- 528,534 ----
      fprintf(f, "logrotate state -- version 1\n");
  
      for (i = 0; i < numStates; i++) {
! 	fprintf(f, "%s %d-%d-%d\n", states[i].fn,
  		states[i].lastRotated.tm_year + 1900,
  		states[i].lastRotated.tm_mon + 1,
  		states[i].lastRotated.tm_mday);
***************
*** 528,534 ****
      return 0;
  }
  
! static int readState(char * stateFilename, logState ** statesPtr, 
  		     int * numStatesPtr) {
      FILE * f;
      char buf[1024];
--- 539,545 ----
      return 0;
  }
  
! static int readState(char * stateFilename, logState ** statesPtr,
  		     int * numStatesPtr) {
      FILE * f;
      char buf[1024];
***************
*** 546,552 ****
  	   access to the file */
  	f = fopen(stateFilename, "w");
  	if (!f) {
! 	    message(MESS_ERROR, "error creating state file %s: %s\n", 
  			stateFilename, strerror(errno));
  	    return 1;
  	}
--- 557,563 ----
  	   access to the file */
  	f = fopen(stateFilename, "w");
  	if (!f) {
! 	    message(MESS_ERROR, "error creating state file %s: %s\n",
  			stateFilename, strerror(errno));
  	    return 1;
  	}
***************
*** 554,560 ****
  	fclose(f);
  	return 0;
      } else if (!f) {
! 	message(MESS_ERROR, "error creating state file %s: %s\n", 
  		    stateFilename, strerror(errno));
  	return 1;
      }
--- 565,571 ----
  	fclose(f);
  	return 0;
      } else if (!f) {
! 	message(MESS_ERROR, "error creating state file %s: %s\n",
  		    stateFilename, strerror(errno));
  	return 1;
      }
***************
*** 577,583 ****
  	line++;
  	i = strlen(buf);
  	if (buf[i - 1] != '\n') {
! 	    message(MESS_ERROR, "line too long in state file %s\n", 
  			stateFilename);
  	    fclose(f);
  	    return 1;
--- 588,594 ----
  	line++;
  	i = strlen(buf);
  	if (buf[i - 1] != '\n') {
! 	    message(MESS_ERROR, "line too long in state file %s\n",
  			stateFilename);
  	    fclose(f);
  	    return 1;
***************
*** 586,592 ****
  	if (i == 1) continue;
  
  	if (sscanf(buf, "%s %d-%d-%d\n", buf2, &year, &month, &day) != 4) {
! 	    message(MESS_ERROR, "bad line %d in state file %s\n", 
  		    stateFilename);
  	    fclose(f);
  	    return 1;
--- 597,603 ----
  	if (i == 1) continue;
  
  	if (sscanf(buf, "%s %d-%d-%d\n", buf2, &year, &month, &day) != 4) {
! 	    message(MESS_ERROR, "bad line %d in state file %s\n",
  		    stateFilename);
  	    fclose(f);
  	    return 1;
***************
*** 635,641 ****
  }
  
  void usage(void) {
!     fprintf(stderr, "logrotate " VERSION 
  		" - Copyright (C) 1995 - Red Hat Software\n");
      fprintf(stderr, "This may be freely redistributed under the terms of "
  		"the GNU Public License\n\n");
--- 646,652 ----
  }
  
  void usage(void) {
!     fprintf(stderr, "logrotate " VERSION
  		" - Copyright (C) 1995 - Red Hat Software\n");
      fprintf(stderr, "This may be freely redistributed under the terms of "
  		"the GNU Public License\n\n");
***************
*** 644,650 ****
  }
  
  int main(int argc, char ** argv) {
!     logInfo defConfig = { NULL, NULL, 0, NULL, ROT_SIZE, 1024 * 1024, 0, 0, 
  			  NULL, NULL, NULL, LOG_FLAG_IFEMPTY,
  			  NO_MODE, NO_UID, NO_GID };
      int numLogs = 0, numStates = 0;
--- 655,661 ----
  }
  
  int main(int argc, char ** argv) {
!     logInfo defConfig = { NULL, NULL, 0, NULL, ROT_SIZE, 1024 * 1024, 0, 0,
  			  NULL, NULL, NULL, LOG_FLAG_IFEMPTY,
  			  NO_MODE, NO_UID, NO_GID };
      int numLogs = 0, numStates = 0;
***************
*** 658,664 ****
  	{ "debug", 0, 0, 'd' },
  	{ "state", 1, 0, 's' },
  	{ "verbose", 0, 0, 'v' },
! 	{ 0, 0, 0, 0 } 
      };
  
      logSetLevel(MESS_NORMAL);
--- 669,675 ----
  	{ "debug", 0, 0, 'd' },
  	{ "state", 1, 0, 's' },
  	{ "verbose", 0, 0, 'v' },
! 	{ 0, 0, 0, 0 }
      };
  
      logSetLevel(MESS_NORMAL);
Index: logrotate.h
===================================================================
RCS file: /home/lindes/src/cvs/src/otherware/redhat/logrotate/logrotate.h,v
retrieving revision 1.1.1.1
retrieving revision 1.2
diff -c -r1.1.1.1 -r1.2
*** /tmp/T00tVbo_	Fri Apr  9 19:31:43 1999
--- /tmp/T10vg.ao	Fri Apr  9 19:31:43 1999
***************
*** 8,13 ****
--- 8,14 ----
  #define LOG_FLAG_CREATE		(1 << 1)
  #define LOG_FLAG_IFEMPTY	(1 << 2)
  #define LOG_FLAG_DELAYCOMPRESS	(1 << 3)
+ #define LOG_FLAG_MAILFIRST	(1 << 4)
  
  #define COMPRESS_COMMAND "gzip -9"
  #define COMPRESS_EXT ".gz"
