#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include "myc_fortran.h"
#include "myc_mem.h"
#include "myc_err.h"
#include "myc_str.h"

int MycTmpName(char *result, const char *name, int reslen) {
  char tmp[128];
  char *u;
  
  if (strlen(name)+64 > sizeof(tmp))
    ERR_MSG("destination string too short"); /* do not accept too long names */
  u=getenv("USER");
  if (u==NULL)
    ERR_MSG("USER undefined");
  sprintf(tmp, "/tmp/%s_%s.%d", name, u, getpid());
  ERR_I(str_ncpy(result, tmp, reslen));
  return 0;
  OnError:
    return -1;
}

int MycCleanTmp(void) {
  time_t tim;
  static time_t last=0;
  char file[128], line[1024], fullid[16];
  char *sess=NULL, *files=NULL;
  char *list, *id, *nxt, *nextline;
  int i;
  
  time(&tim);
  if (tim < last+3600) return 0; /* do not clean up before an hour after last time */
  last=tim;
  file[0]='\0';
  ERR_I(MycTmpName(file, ".cleanup", sizeof(file)));
  unlink(file);
  /* make a list of used session and process id's */
  sprintf(line, "ps -U $USER -o pid,sess > %s", file);
  system(line);
  ERR_P(sess=str_read_file(file));
  unlink(file);
  for (i=0; i<2; i++) {
    if (i==0) {
      sprintf(line,
      "find /tmp/. ! -name . -prune -name \".*_$USER.*\" > %s", file);
    } else {
      sprintf(line,
      "find /tmp/. ! -name . -prune -name \"*_$USER.*\" -mtime +7 > %s", file);
    }
    system(line);
    ERR_P(files=str_read_file(file));
    unlink(file);
    str_replace_char(sess, '\n', ' ');
    list=files;
    while (*list != '\0') {
      nextline=str_split1(list, '\n');
      id=NULL;
      nxt=list;
      while (nxt != NULL) { /* find last dot */
        id=nxt+1;
        nxt=strchr(nxt+1, '.');
      }
      if (id!=NULL) { /* file contains a dot */
        sprintf(fullid, " %.12s ", id);
        if (strstr(sess, fullid)==NULL) {
          unlink(list);
        }
      }
      list=nextline;
    }
    FREE(files); files=NULL;
  }
  FREE(sess); sess=NULL;
  return 0;
  OnError:
    if (file[0] != '\0') unlink(file);
    if (sess!=NULL) FREE(sess);
    if (files!=NULL) FREE(files);
    return -1;
}

void F_FUN(sys_temp_name) ( F_CHAR(name), F_CHAR(path) F_CLEN(name) F_CLEN(path)) {
  char nam[128];
  char pat[1024];

  STR_TO_C(nam, name);
  MycTmpName(pat, nam, sizeof(pat));
  STR_TO_F(path, pat);
}

void F_FUN(sys_clean_tmp) (void) {
  MycCleanTmp();
}
