#ifdef DEBUG
/*----------------------------------------------------------------------
     Initialize debugging - open the debug log file

  Args: none

 Result: opens the debug logfile for dprints

   Opens the file "~/.pine-debug1. Also maintains .pine-debug[2-4]
   by renaming them each time so the last 4 sessions are saved.
  ----*/
void
init_debug()
{
    char nbuf[5];
    char newfname[MAXPATH+1], filename[MAXPATH+1];
    int i, fd;

    if(!(debug || ps_global->debug_imap))
      return;

    for(i = NUMDEBUGFILES - 1; i > 0; i--){
        build_path(filename, ps_global->home_dir, DEBUGFILE);
        strcpy(newfname, filename);
        sprintf(nbuf, "%d", i);
        strcat(filename, nbuf);
        sprintf(nbuf, "%d", i+1);
        strcat(newfname, nbuf);
        (void)rename_file(filename, newfname);
    }

    build_path(filename, ps_global->home_dir, DEBUGFILE);
    strcat(filename, "1");

    debugfile = NULL;
    if((fd = open(filename, O_TRUNC|O_RDWR|O_CREAT, 0600)) >= 0)
      debugfile = fdopen(fd, "w+");

    if(debugfile != NULL){
	time_t now = time((time_t *)0);
	if(ps_global->debug_flush)
	  setbuf(debugfile, NULL);

	if(NUMDEBUGFILES == 0){
	    /*
	     * If no debug files are asked for, make filename a tempfile
	     * to be used for a record should pine later crash...
	     */
	    if(debug < 9 && !ps_global->debug_flush && ps_global->debug_imap<4)
	      unlink(filename);
	}

	dprint(0, (debugfile,
  "Debug output of the Pine program (debug=%d debug_imap=%d). Version %s\n%s\n",
	       debug, ps_global->debug_imap, pine_version, ctime(&now)));
    }
}


/*----------------------------------------------------------------------
     Try to save the debug file if we crash in a controlled way

  Args: dfile:  pointer to open debug file

 Result: tries to move the appropriate .pine-debugx file to .pine-crash

   Looks through the four .pine-debug files hunting for the one that is
   associated with this pine, and then renames it.
  ----*/
void
save_debug_on_crash(dfile)
FILE *dfile;
{
    char nbuf[5], crashfile[MAXPATH+1], filename[MAXPATH+1];
    int i;
    struct stat dbuf, tbuf;
    time_t now = time((time_t *)0);

    if(!(dfile && fstat(fileno(dfile), &dbuf) != 0))
      return;

    fprintf(dfile, "\nsave_debug_on_crash: Version %s: debug level %d\n",
	pine_version, debug);
    fprintf(dfile, "\n                   : %s\n", ctime(&now));

    build_path(crashfile, ps_global->home_dir, ".pine-crash");

    fprintf(dfile, "\nAttempting to save debug file to %s\n", crashfile);
    fprintf(stderr,
	"\n\n       Attempting to save debug file to %s\n\n", crashfile);

    /* Blat out last n keystrokes */
    fputs("========== Latest keystrokes ==========\n", dfile);
    while((i = key_playback(0)) != -1)
      fprintf(dfile, "\t%s\t(0x%04.4x)\n", pretty_command(i), i);

    /* look for existing debug file */
    for(i = 1; i <= NUMDEBUGFILES; i++){
	build_path(filename, ps_global->home_dir, DEBUGFILE);
	sprintf(nbuf, "%d", i);
	strcat(filename, nbuf);
	if(stat(filename, &tbuf) != 0)
	  continue;

	/* This must be the current debug file */
	if(tbuf.st_dev == dbuf.st_dev && tbuf.st_ino == dbuf.st_ino){
	    rename_file(filename, crashfile);
	    break;
	}
    }

    /* if current debug file name not found, write it by hand */
    if(i > NUMDEBUGFILES){
	FILE *cfp;
	char  buf[1025];

	/*
	 * Copy the debug temp file into the 
	 */
	if(cfp = fopen(crashfile, "w")){
	    buf[1024] = '\0';
	    fseek(dfile, 0L, 0);
	    while(fgets(buf, 1025, dfile) && fputs(buf, cfp) != EOF)
	      ;

	    fclose(cfp);
	}
    }

    fclose(dfile);
}


#define CHECK_EVERY_N_TIMES 100
#define MAX_DEBUG_FILE_SIZE 200000L
/*
 * This is just to catch runaway Pines that are looping spewing out
 * debugging (and filling up a file system).  The stop doesn't have to be
 * at all precise, just soon enough to hopefully prevent filling the
 * file system.  If the debugging level is high (9 for now), then we're
 * presumably looking for some problem, so don't truncate.
 */
int
do_debug(debug_fp)
FILE *debug_fp;
{
    static int counter = CHECK_EVERY_N_TIMES;
    static int ok = 1;
    long filesize;

    if(debug == DEFAULT_DEBUG
       && !ps_global->debug_flush
       && !ps_global->debug_timestamp
       && ps_global->debug_imap < 2
       && ok
       && --counter <= 0){
	if((filesize = fp_file_size(debug_fp)) != -1L)
	  ok = (unsigned long)filesize < (unsigned long)MAX_DEBUG_FILE_SIZE;

	counter = CHECK_EVERY_N_TIMES;
	if(!ok){
	    fprintf(debug_fp, "\n\n --- No more debugging ---\n");
	    fprintf(debug_fp,
		"     (debug file growing too large - over %ld bytes)\n\n",
		MAX_DEBUG_FILE_SIZE);
	    fflush(debug_fp);
	}
    }

    if(ok && ps_global->debug_timestamp)
      fprintf(debug_fp, "\n%s\n", debug_time(0));

    return(ok);
}


/*
 * Returns a pointer to static string for a timestamp.
 *
 * If include_date is set the date is appended.
 */
char *
debug_time(include_date)
    int include_date;
{
    time_t          t;
    struct tm      *tm_now;
    static char     timestring[23];
    char            datestr[7];

    timestring[0] = '\0';
    t = time((time_t *)0);
    if(include_date){
	tm_now = localtime(&t);
	sprintf(datestr, " %d/%d", tm_now->tm_mon+1, tm_now->tm_mday);
    }
    else
      datestr[0] = '\0';

    sprintf(timestring, "%.8s%s", ctime(&t)+11, datestr);

    return(timestring);
}
#endif /* DEBUG */


/*
 * This version just returns -1 because this system doesn't have gettimeofday.
 *
 * Returns 0 if ok
 *        -1 if can't do it
 */
int
get_time(our_time_val)
    TIMEVAL_S *our_time_val;
{
    return -1;
}


/*
 * Returns the difference between the two values, in microseconds.
 * Value returned is first - second.
 */
long
time_diff(first, second)
    TIMEVAL_S *first,
              *second;
{
    return(1000000L*(first->sec - second->sec) + (first->usec - second->usec));
}


