Logo Search packages:      
Sourcecode: fdclone version File versions  Download package

apply.c

/*
 *    apply.c
 *
 *    Apply Function to Files
 */

#include <fcntl.h>
#include "fd.h"
#include "func.h"
#include "kanji.h"

#define     MAXTIMESTR  8

typedef struct _attrib_t {
      u_int mode;
#ifdef      HAVEFLAGS
      u_long flags;
#endif
      char timestr[2][MAXTIMESTR + 1];
} attrib_t;

extern reg_t *findregexp;
extern int subwindow;
extern int win_x;
extern int win_y;
extern int lcmdline;
extern int tradlayout;
extern int sizeinfo;
extern int mark;
#ifdef      HAVEFLAGS
extern u_long fflaglist[];
#endif
#if   !defined (_USEDOSCOPY) && !defined (_NOEXTRACOPY)
extern int inheritcopy;
#endif

#ifndef     EISDIR
#define     EISDIR      EACCES
#endif

#ifdef      _NOEXTRACOPY
#define     MAXCOPYITEM 4
#define     FLAG_SAMEDIR      0
#else
#define     MAXCOPYITEM 5
#define     FLAG_SAMEDIR      8
#endif

static int NEAR issamedir __P_((char *, char *));
static int NEAR islowerdir __P_((char *, char *));
static char *NEAR getdestdir __P_((char *, char *));
static int NEAR getdestpath __P_((char *, char *, struct stat *));
static int NEAR checkdupl __P_((char *, char *, struct stat *, struct stat *));
static int NEAR checkrmv __P_((char *, int));
static int safecopy __P_((char *));
static int safemove __P_((char *));
static int cpdir __P_((char *));
static int touchdir __P_((char *));
#ifndef     _NOEXTRACOPY
static int mvdir __P_((char *));
#endif
static VOID NEAR showattr __P_((namelist *, attrib_t *, int y));
static char **NEAR getdirtree __P_((char *, char **, int *, int));
static int NEAR _applydir __P_((char *, int (*)(char *),
            int (*)(char *), int (*)(char *), int, char *, int));
static int forcecpfile __P_((char *));
static int forcecpdir __P_((char *));
static int forcetouchdir __P_((char *));

int copypolicy = 0;
int removepolicy = 0;
char *destpath = NULL;

static u_short attrmode = 0;
#ifdef      HAVEFLAGS
static u_long attrflags = 0;
#endif
static time_t attrtime = 0;
static char *destdir = NULL;
static time_t destmtime = (time_t)-1;
static time_t destatime = (time_t)-1;
#ifndef     _NOEXTRACOPY
static char *forwardpath = NULL;
#endif
#ifndef     _NODOSDRIVE
static int destdrive = -1;
#endif
#if   !defined (_NOEXTRACOPY) && !defined (_NODOSDRIVE)
static int forwarddrive = -1;
#endif


static int NEAR issamedir(path, org)
char *path, *org;
{
      char *cwd;
      int i;

      cwd = getwd2();
      if (!org) org = cwd;
      else if (_chdir2(org) >= 0) {
            org = getwd2();
            if (_chdir2(cwd) < 0) error(cwd);
      }
      else {
            free(cwd);
            return(0);
      }

#ifdef      _USEDOSPATH
      if (dospath(path, NULL) != dospath(org, NULL)) path = NULL;
      else
#endif
      path = (_chdir2(path) >= 0) ? getwd2() : NULL;
      if (_chdir2(cwd) < 0) error(cwd);
      i = (path) ? !strpathcmp(org, path) : 0;
      if (org != cwd) free(org);
      free(cwd);
      if (path) free(path);
      return(i);
}

static int NEAR islowerdir(path, org)
char *path, *org;
{
#ifdef      _USEDOSEMU
      char orgpath[MAXPATHLEN];
#endif
      char *cp, *top, *cwd, tmp[MAXPATHLEN];
      int i;

      cwd = getwd2();
      if (!org) org = cwd;
#ifdef      _USEDOSEMU
      else org = nodospath(orgpath, org);
#endif
      strcpy(tmp, path);
      top = tmp;
#ifdef      _USEDOSPATH
      if (dospath(path, NULL) != dospath(org, NULL)) {
            free(cwd);
            return(0);
      }
      if (_dospath(tmp)) top += 2;
#endif
      while (_chdir2(tmp) < 0) {
            if ((cp = strrdelim(top, 0)) && cp > top) *cp = '\0';
            else {
                  path = NULL;
                  break;
            }
      }
      i = 0;
      if (path) {
            path = getwd2();
            if (_chdir2(cwd) < 0) error(cwd);
            if (_chdir2(org) >= 0) {
                  org = getwd2();
                  i = strlen(org);
                  if (strnpathcmp(org, path, i) || path[i] != _SC_)
                        i = 0;
                  free(org);
            }
            if (_chdir2(cwd) < 0) error(cwd);
            free(path);
      }
      free(cwd);
      return(i);
}

static char *NEAR getdestdir(mes, arg)
char *mes, *arg;
{
      char *dir;
#ifndef     _NODOSDRIVE
      int drive;
#endif

      if (arg && *arg) dir = strdup2(arg);
      else if (!(dir = inputstr(mes, 1, -1, NULL, 1))) return(NULL);
      else if (!*(dir = evalpath(dir, 0))) {
            dir = realloc2(dir, 2);
            dir[0] = '.';
            dir[1] = '\0';
      }
#ifdef      _USEDOSPATH
      else if (_dospath(dir) && !dir[2]) {
            dir = realloc2(dir, 4);
            dir[2] = '.';
            dir[3] = '\0';
      }
#endif

#ifndef     _NODOSDRIVE
      destdrive = -1;
      if ((drive = dospath3(dir))
      && (destdrive = preparedrv(drive)) < 0) {
            warning(-1, dir);
            free(dir);
            return(NULL);
      }
#endif
      if (preparedir(dir) < 0) {
            warning(-1, dir);
            free(dir);
#ifndef     _NODOSDRIVE
            if (destdrive >= 0) shutdrv(destdrive);
#endif
            return(NULL);
      }
      return(dir);
}

static int NEAR getdestpath(file, dest, stp)
char *file, *dest;
struct stat *stp;
{
      char *cp, *tmp;
      int n;

      strcpy(dest, destpath);
      cp = file;
      if (destdir) {
            for (n = 0; (tmp = strdelim(cp, 0)); n++) cp = tmp + 1;
            for (tmp = destdir; n > 0 && (tmp = strdelim(tmp, 0)); tmp++)
                  n--;
            if (tmp) *tmp = '\0';
            if (*destdir) strcpy(strcatdelim(dest), destdir);
      }
      strcpy(strcatdelim(dest), cp);

      if (Xlstat(file, stp) < 0) {
            warning(-1, file);
            return(-1);
      }
      return(0);
}

static int NEAR checkdupl(file, dest, stp1, stp2)
char *file, *dest;
struct stat *stp1, *stp2;
{
      char *cp, *tmp, *str[MAXCOPYITEM];
      int i, n, ch, val[MAXCOPYITEM];
#ifndef     _NOEXTRACOPY
      char path[MAXPATHLEN];
#endif
#if   !defined (_NOEXTRACOPY) && !defined (_NODOSDRIVE)
      int dupdestdrive;
#endif

      if (getdestpath(file, dest, stp1) < 0) return(-1);
      if (Xlstat(dest, stp2) < 0) {
            stp2 -> st_mode = S_IWRITE;
            if (errno == ENOENT) return(0);
            warning(-1, dest);
            return(-1);
      }
      if (!s_isdir(stp2)) n = (copypolicy & ~FLAG_SAMEDIR);
      else if (!s_isdir(stp1)) n = 2;
#ifdef      _NOEXTRACOPY
      else return(1);
#else
      else if (!(copypolicy & FLAG_SAMEDIR)) return(1);
      else {
            n = (copypolicy &= ~FLAG_SAMEDIR);
            copypolicy = 0;
      }
#endif

      for (;;) {
            if (!n || n == 2) {
                  locate(0, L_CMDLINE);
                  putterm(l_clear);
                  cp = SAMEF_K;
                  i = strlen2(cp) - (sizeof("%.*s") - 1);
                  cp = asprintf3(cp, n_column - i, dest);
                  kanjiputs(cp);
                  free(cp);
            }
            if (!n) {
                  str[0] = UPDAT_K;
                  val[0] = 1;
                  str[1] = RENAM_K;
                  val[1] = 2;
                  str[2] = OVERW_K;
                  val[2] = 3;
                  str[3] = NOCPY_K;
                  val[3] = 4;
#ifndef     _NOEXTRACOPY
                  str[4] = FORWD_K;
                  val[4] = 5;
#endif
                  i = 1;
                  ch = selectstr(&i, MAXCOPYITEM, 0, str, val);
                  if (ch == K_ESC) return(-1);
                  else if (ch != K_CR) return(-2);
#ifndef     _NOEXTRACOPY
                  if (i == 5) {
                        str[0] = UPDAT_K;
                        str[1] = OVERW_K;
                        val[0] = 5;
                        val[1] = 6;
                        if (selectstr(&i, 2, 0, str, val) != K_CR)
                              continue;
# ifndef    _NODOSDRIVE
                        dupdestdrive = destdrive;
# endif

                        if (!(tmp = getdestdir(FRWDD_K, NULL)))
                              continue;
# ifndef    _NODOSDRIVE
                        forwarddrive = destdrive;
                        destdrive = dupdestdrive;
# endif
                        if (issamedir(tmp, NULL)
                        || issamedir(tmp, destpath)) {
                              warning(EINVAL, tmp);
                              free(tmp);
                              continue;
                        }
                        forwardpath = tmp;
                  }
#endif      /* !_NOEXTRACOPY */
                  copypolicy = n = i;
            }
            switch (n) {
                  case 1:
                        if (stp1 -> st_mtime < stp2 -> st_mtime)
                              return(-1);
                        return(2);
/*NOTREACHED*/
                        break;
                  case 2:
                        lcmdline = L_INFO;
                        tmp = inputstr(NEWNM_K, 1, -1, NULL, -1);
                        if (!tmp) return(-1);
                        strcpy(getbasename(dest), tmp);
                        free(tmp);
                        if (Xlstat(dest, stp2) < 0) {
                              stp2 -> st_mode = S_IWRITE;
                              if (errno == ENOENT) return(0);
                              warning(-1, dest);
                              return(-1);
                        }
                        if (s_isdir(stp1) && s_isdir(stp2)) return(1);
                        putterm(t_bell);
                        break;
                  case 3:
                        return(2);
/*NOTREACHED*/
                        break;
#ifndef     _NOEXTRACOPY
                  case 5:
                        if (stp1 -> st_mtime < stp2 -> st_mtime)
                              return(-1);
/*FALLTHRU*/
                  case 6:
                        strcatdelim2(path, forwardpath, file);
                        cp = strrdelim(path, 0);
                        *cp = '\0';
                        if (mkdir2(path, 0777) < 0
                        && errno != EEXIST) {
                              warning(-1, path);
                              return(-1);
                        }
                        *cp = _SC_;
                        if (safemvfile(dest, path, stp2, NULL) < 0) {
                              warning(-1, path);
                              return(-1);
                        }
                        return(2);
/*NOTREACHED*/
                        break;
#endif      /* !_NOEXTRACOPY */
                  default:
                        return(-1);
/*NOTREACHED*/
                        break;
            }
      }

/*NOTREACHED*/
      return(0);
}

static int NEAR checkrmv(path, mode)
char *path;
int mode;
{
      char *cp, *str[4];
      int ch, len, val[4];
#if   MSDOS

      if (Xaccess(path, mode) >= 0) return(0);
#else /* !MSDOS */
      struct stat *stp, st;
      char *tmp, dir[MAXPATHLEN];

# ifndef    _NODOSDRIVE
      if (dospath2(path)) {
            if (Xaccess(path, mode) >= 0) return(0);
            stp = NULL;
      }
      else
# endif
      {
            if (nodoslstat(path, &st) < 0) {
                  warning(-1, path);
                  return(-1);
            }
            if (s_islnk(&st)) return(0);

            if (!(tmp = strrdelim(path, 0))) strcpy(dir, ".");
            else if (tmp == path) strcpy(dir, _SS_);
            else strncpy2(dir, path, tmp - path);

            if (nodoslstat(dir, &st) < 0) {
                  warning(-1, dir);
                  return(-1);
            }
            if (Xaccess(path, mode) >= 0) return(0);
            stp = &st;
      }
#endif      /* !MSDOS */
      if (errno == ENOENT) return(0);
      if (errno != EACCES) {
            warning(-1, path);
            return(-1);
      }
#if   !MSDOS
      if (stp) {
            int duperrno;

            duperrno = errno;
# ifdef     NOUID
            mode = logical_access(stp -> st_mode)
# else
            mode = logical_access(stp -> st_mode,
                  stp -> st_uid, stp -> st_gid);
# endif
            if (!(mode & F_ISWRI)) {
                  errno = duperrno;
                  warning(-1, path);
                  return(-1);
            }
      }
#endif      /* !MSDOS */
      if (removepolicy > 0) return(removepolicy - 2);
      locate(0, L_CMDLINE);
      putterm(l_clear);
      cp = DELPM_K;
      len = strlen2(cp) - (sizeof("%.*s") - 1);
      cp = asprintf3(cp, n_column - len, path);
      kanjiputs(cp);
      free(cp);
      str[0] = ANYES_K;
      str[1] = ANNO_K;
      str[2] = ANALL_K;
      str[3] = ANKEP_K;
      val[0] = 0;
      val[1] = -1;
      val[2] = 2;
      val[3] = 1;
      ch = selectstr(&removepolicy, 4, 0, str, val);
      if (ch == K_ESC) removepolicy = -1;
      else if (ch != K_CR) removepolicy = -2;
      return((removepolicy > 0) ? removepolicy - 2 : removepolicy);
}

static int safecopy(path)
char *path;
{
      struct stat st1, st2;
      char dest[MAXPATHLEN];
      int n;

      if ((n = checkdupl(path, dest, &st1, &st2)) < 0)
            return((n < -1) ? -2 : 1);
      if (safecpfile(path, dest, &st1, &st2) < 0) return(-1);
      return(0);
}

static int safemove(path)
char *path;
{
      struct stat st1, st2;
      char dest[MAXPATHLEN];
      int n;

      if ((n = checkdupl(path, dest, &st1, &st2)) < 0
      || (n = checkrmv(path, W_OK)) < 0)
            return((n < -1) ? -2 : 1);
      if (safemvfile(path, dest, &st1, &st2) < 0) return(-1);
      return(0);
}

static int cpdir(path)
char *path;
{
      struct stat st1, st2;
      char dest[MAXPATHLEN];

      switch (checkdupl(path, dest, &st1, &st2)) {
            case 2:
            /* Already exist, but not directory */
                  if (Xunlink(dest) < 0) return(-1);
/*FALLTHRU*/
            case 0:
            /* Not exist */
#if   MSDOS
                  if (Xmkdir(dest, (st1.st_mode & 0777) | S_IWRITE) < 0)
#else
                  if (Xmkdir(dest, st1.st_mode & 0777) < 0)
#endif
                        return(-1);
                  destmtime = st1.st_mtime;
                  destatime = st1.st_atime;
                  break;
            case -1:
            case -2:
            /* Abandon copy */
                  return(-2);
/*NOTREACHED*/
                  break;
            default:
            /* Already exist */
                  destmtime = st2.st_mtime;
                  destatime = st2.st_atime;
                  break;
      }

      if (destdir) free(destdir);
      destdir = &(dest[strlen(destpath)]);
      while (*destdir == _SC_) destdir++;
      destdir = strdup2(destdir);

      return(0);
}

/*ARGSUSED*/
static int touchdir(path)
char *path;
{
#if   defined (_USEDOSCOPY) || !defined (_NOEXTRACOPY)
      struct stat st;
      char dest[MAXPATHLEN];

# if  !defined (_USEDOSCOPY)
      if (!inheritcopy) return(0);
# endif
      if (getdestpath(path, dest, &st) < 0) return(-2);
      if (destmtime != (time_t)-1 || destatime != (time_t)-1) {
            st.st_mtime = destmtime;
            st.st_atime = destatime;
      }
# ifdef     HAVEFLAGS
      st.st_flags = (u_long)-1;
# endif
      if (touchfile(dest, &st) < 0) return(-1);
#endif      /* _USEDOSCOPY || !_NOEXTRACOPY */
      return(0);
}

#ifndef     _NOEXTRACOPY
static int mvdir(path)
char *path;
{
      struct stat st;
      char dest[MAXPATHLEN];
      int n;

      if (getdestpath(path, dest, &st) < 0) return(-2);
      if (destmtime != (time_t)-1 || destatime != (time_t)-1) {
            st.st_mtime = destmtime;
            st.st_atime = destatime;
      }
# ifdef     HAVEFLAGS
      st.st_flags = (u_long)-1;
# endif
      if (touchfile(dest, &st) < 0) return(-1);
      if ((n = checkrmv(path, R_OK | W_OK | X_OK)) < 0)
            return((n < -1) ? -2 : 1);
      return(Xrmdir(path));
}
#endif      /* !_NOEXTRACOPY */

int rmvfile(path)
char *path;
{
      int n;

      if ((n = checkrmv(path, W_OK)) < 0) return((n < -1) ? -2 : 1);
      return(Xunlink(path));
}

int rmvdir(path)
char *path;
{
      int n;

      if ((n = checkrmv(path, R_OK | W_OK | X_OK)) < 0)
            return((n < -1) ? -2 : 1);
      return(Xrmdir(path));
}

int findfile(path)
char *path;
{
      if (regexp_exec(findregexp, getbasename(path), 1)) {
            if (path[0] == '.' && path[1] == _SC_) path += 2;
            locate(0, L_CMDLINE);
            putterm(l_clear);
            cprintf2("[%.*k]", n_column - 2, path);
            if (yesno(FOUND_K)) {
                  destpath = strdup2(path);
                  return(-2);
            }
      }
      return(0);
}

int finddir(path)
char *path;
{
      if (regexp_exec(findregexp, getbasename(path), 1)) {
            if (yesno(FOUND_K)) {
                  destpath = strdup2(path);
                  return(-2);
            }
      }
      return(0);
}

static VOID NEAR showattr(namep, attr, y)
namelist *namep;
attrib_t *attr;
int y;
{
      struct tm *tm;
      char buf[WMODE + 1];
      int x1, x2, w;

      tm = localtime(&(namep -> st_mtim));
      if (isbestomit()) {
            x1 = n_column / 2 - 16;
            x2 = n_column / 2 - 3;
            w = 12;
      }
      else {
            x1 = n_column / 2 - 20;
            x2 = n_column / 2;
            w = 16;
      }

      locate(0, y);
      putterm(l_clear);

      locate(0, ++y);
      putterm(l_clear);
      locate(x1, y);
      cprintf2("[%-*.*k]", w, w, namep -> name);
      locate(x2 + 3, y);
      kanjiputs(TOLD_K);
      locate(x2 + 13, y);
      kanjiputs(TNEW_K);

      locate(0, ++y);
      putterm(l_clear);
      locate(x1, y);
      kanjiputs(TMODE_K);
      locate(x2, y);
      putmode(buf, namep -> st_mode, 1);
      cputs2(buf);
      locate(x2 + 10, y);
      putmode(buf, attr -> mode, 1);
      cputs2(buf);

#ifdef      HAVEFLAGS
      locate(0, ++y);
      putterm(l_clear);
      locate(x1, y);
      kanjiputs(TFLAG_K);
      locate(x2, y);
      putflags(buf, namep -> st_flags);
      cputs2(buf);
      locate(x2 + 10, y);
      putflags(buf, attr -> flags);
      cputs2(buf);
#endif

      locate(0, ++y);
      putterm(l_clear);
      locate(x1, y);
      kanjiputs(TDATE_K);
      locate(x2, y);
      cprintf2("%02d-%02d-%02d",
            tm -> tm_year % 100, tm -> tm_mon + 1, tm -> tm_mday);
      locate(x2 + 10, y);
      cputs2(attr -> timestr[0]);

      locate(0, ++y);
      putterm(l_clear);
      locate(x1, y);
      kanjiputs(TTIME_K);
      locate(x2, y);
      cprintf2("%02d:%02d:%02d",
            tm -> tm_hour, tm -> tm_min, tm -> tm_sec);
      locate(x2 + 10, y);
      cputs2(attr -> timestr[1]);

      locate(0, ++y);
      putterm(l_clear);
}

int inputattr(namep, flag)
namelist *namep;
int flag;
{
      struct tm *tm;
      attrib_t attr;
      char buf[WMODE + 1];
      u_int tmp;
      int i, ch, x, y, xx, yy, ymin, ymax, dupwin_x, dupwin_y;

      dupwin_x = win_x;
      dupwin_y = win_y;
      subwindow = 1;
      Xgetkey(-1, 0);

      yy = LFILETOP;
      while (yy + WMODELINE + 5 > n_line - 1) yy--;
      if (yy <= L_TITLE) yy = L_TITLE + 1;
      xx = n_column / 2 + ((isbestomit()) ? 7 : 10);

      attr.mode = namep -> st_mode;
#ifdef      HAVEFLAGS
      attr.flags = namep -> st_flags;
#endif
      tm = localtime(&(namep -> st_mtim));
      snprintf2(attr.timestr[0], sizeof(attr.timestr[0]), "%02d-%02d-%02d",
            tm -> tm_year % 100, tm -> tm_mon + 1, tm -> tm_mday);
      snprintf2(attr.timestr[1], sizeof(attr.timestr[1]), "%02d:%02d:%02d",
            tm -> tm_hour, tm -> tm_min, tm -> tm_sec);
      showattr(namep, &attr, yy);
      y = ymin = (flag & 1) ? 0 : WMODELINE;
      ymax = (flag & 2) ? WMODELINE + 1 : 0;
      x = 0;

      do {
            win_x = xx + x;
            win_y = yy + y + 2;
            locate(win_x, win_y);
            tflush();

            keyflush();
            switch (ch = Xgetkey(1, 0)) {
                  case K_UP:
                        if (y > ymin) y--;
                        else y = ymax;
                        if (y && x >= 8) x = 7;
                        if (!y && x >= WMODE - 1) x = WMODE - 2;
                        break;
                  case K_DOWN:
                        if (y < ymax) y++;
                        else y = ymin;
                        if (y && x >= 8) x = 7;
                        if (!y && x >= WMODE - 1) x = WMODE - 2;
                        break;
                  case 'a':
                  case 'A':
                        if (ymin <= 0) x = y = 0;
                        break;
                  case 'd':
                  case 'D':
                        if (ymax >= WMODELINE) {
                              x = 0;
                              y = WMODELINE;
                        }
                        break;
                  case 't':
                  case 'T':
                        if (ymax >= WMODELINE + 1) {
                              x = 0;
                              y = WMODELINE + 1;
                        }
                        break;
                  case '0':
                  case '1':
                  case '2':
                  case '3':
                  case '4':
                  case '5':
                  case '6':
                  case '7':
                  case '8':
                  case '9':
                        if (y < WMODELINE) break;
                        putch2(ch);
                        attr.timestr[y - WMODELINE][x] = ch;
/*FALLTHRU*/
                  case K_RIGHT:
#ifdef      HAVEFLAGS
                        if (y == WMODELINE - 1) {
                              if (x < 7) x++;
                        }
                        else
#endif
                        if (y) {
                              if (x >= 7) {
                                    if (y == WMODELINE + 1) break;
                                    y++;
                                    x = 0;
                              }
                              else {
                                    x++;
                                    if (!((x + 1) % 3)) x++;
                              }
                        }
                        else if (x < WMODE - 2) x++;
                        break;
                  case K_BS:
                        if (y < WMODELINE) break;
/*FALLTHRU*/
                  case K_LEFT:
#ifdef      HAVEFLAGS
                        if (y == WMODELINE - 1) {
                              if (x > 0) x--;
                        }
                        else
#endif
                        if (y) {
                              if (x <= 0) {
                                    if (y == WMODELINE) break;
                                    y--;
                                    x = 7;
                              }
                              else {
                                    if (!(x % 3)) x--;
                                    x--;
                              }
                        }
                        else if (x > 0) x--;
                        break;
                  case K_CTRL('L'):
                        yy = LFILETOP;
                        while (yy + WMODELINE + 5 > n_line - 1) yy--;
                        if (yy <= L_TITLE) yy = L_TITLE + 1;
                        xx = n_column / 2 + ((isbestomit()) ? 7 : 10);
                        showattr(namep, &attr, yy);
                        break;
                  case ' ':
#ifdef      HAVEFLAGS
                        if (y == WMODELINE - 1) {
                              attr.flags ^= fflaglist[x];
                              locate(xx, yy + y + 2);
                              putflags(buf, attr.flags);
                              cputs2(buf);
                              break;
                        }
#endif
                        if (y) break;
#if   MSDOS
                        if (x == 2) break;
                        else if (x == 3) attr.mode ^= S_ISVTX;
                        else {
                              tmp = 1;
                              for (i = 8; i > x; i--) tmp <<= 1;
                              attr.mode ^= tmp;
                        }
#else
                        tmp = 1;
                        for (i = 8; i > x; i--) tmp <<= 1;
                        if (!((x + 1) % 3) && (attr.mode & tmp)) {
                              i = (x * 2) / 3 + 4;
                              if (!(attr.mode & (tmp << i)))
                                    tmp <<= i;
                              else attr.mode ^= (tmp << i);
                        }
                        attr.mode ^= tmp;
#endif
                        locate(xx, yy + y + 2);
                        putmode(buf, attr.mode, 1);
                        cputs2(buf);
                        break;
                  default:
                        break;
            }
      } while (ch != K_ESC && ch != K_CR);

      win_x = dupwin_x;
      win_y = dupwin_y;
      subwindow = 0;
      Xgetkey(-1, 0);

      if (ch == K_ESC) return(0);

      tm -> tm_year = (attr.timestr[0][0] - '0') * 10
            + attr.timestr[0][1] - '0';
      if (tm -> tm_year < 70) tm -> tm_year += 100;
      tm -> tm_mon = (attr.timestr[0][3] - '0') * 10
            + attr.timestr[0][4] - '0';
      tm -> tm_mon--;
      tm -> tm_mday = (attr.timestr[0][6] - '0') * 10
            + attr.timestr[0][7] - '0';
      tm -> tm_hour = (attr.timestr[1][0] - '0') * 10
            + attr.timestr[1][1] - '0';
      tm -> tm_min = (attr.timestr[1][3] - '0') * 10
            + attr.timestr[1][4] - '0';
      tm -> tm_sec = (attr.timestr[1][6] - '0') * 10
            + attr.timestr[1][7] - '0';

      if (tm -> tm_mon < 0 || tm -> tm_mon > 11
      || tm -> tm_mday < 1 || tm -> tm_mday > 31
      || tm -> tm_hour > 23 || tm -> tm_min > 59 || tm -> tm_sec > 59)
            return(-1);

      attrmode = attr.mode;
#ifdef      HAVEFLAGS
      attrflags = attr.flags;
#endif
      attrtime = timelocal2(tm);
      if (flag == 3) {
            if (attrmode == namep -> st_mode) attrmode = (u_short)-1;
#ifdef      HAVEFLAGS
            if (attrflags == namep -> st_flags) attrflags = (u_long)-1;
#endif
            if (attrtime == namep -> st_mtim) attrtime = (time_t)-1;
      }
      else {
            if (!(flag & 1)) attrmode = (u_short)-1;
#ifdef      HAVEFLAGS
            attrflags = (u_long)-1;
#endif
            if (!(flag & 2)) attrtime = (time_t)-1;
      }

      return(1);
}

int setattr(path)
char *path;
{
      struct stat st;

      st.st_mtime = attrtime;
#ifdef      HAVEFLAGS
      st.st_flags = attrflags;
#endif
      st.st_mode = attrmode;
#ifndef     NOUID
      st.st_gid = (gid_t)-1;
#endif
      return(touchfile(path, &st));
}

int applyfile(func, endmes)
int (*func)__P_((char *));
char *endmes;
{
#ifdef      _USEDOSEMU
      char path[MAXPATHLEN];
#endif
      int i, ret, old, dupfilepos;

      dupfilepos = filepos;
      ret = old = filepos;

      if (mark <= 0) {
            i = (*func)(fnodospath(path, filepos));
            if (i == -1) warning(-1, filelist[filepos].name);
            else if (!i) ret++;
            return(ret);
      }

      helpbar();
      for (filepos = 0; filepos < maxfile; filepos++) {
            if (intrkey()) {
                  endmes = NULL;
                  break;
            }
            if (!ismark(&(filelist[filepos]))) continue;

            movepos(old, 0);
            locate(win_x, win_y);
            tflush();
            i = (*func)(fnodospath(path, filepos));
            if (i < -1) {
                  endmes = NULL;
                  break;
            }
            if (i < 0) warning(-1, filelist[filepos].name);
            else if (!i && ret == filepos) ret++;

            old = filepos;
      }

      if (endmes) warning(0, endmes);
      filepos = dupfilepos;
      movepos(old, 0);
      locate(win_x, win_y);
      tflush();
      return(ret);
}

static char **NEAR getdirtree(dir, dirlist, maxp, depth)
char *dir, **dirlist;
int *maxp, depth;
{
      DIR *dirp;
      struct dirent *dp;
      struct stat st;
      char *cp;
      int d;

      if (!(dirp = Xopendir(dir))) return(dirlist);
      cp = strcatdelim(dir);
      while ((dp = Xreaddir(dirp))) {
            if (isdotdir(dp -> d_name)) continue;
            strcpy(cp, dp -> d_name);

            if (Xlstat(dir, &st) < 0 || !s_isdir(&st)) continue;
            dirlist = b_realloc(dirlist, *maxp, char *);
            dirlist[(*maxp)++] = strdup2(dir);
            if (!(d = depth)) /*EMPTY*/;
            else if (d > 1) d--;
            else continue;
            dirlist = getdirtree(dir, dirlist, maxp, d);
      }
      if (cp > dir) *(cp - 1) = '\0';
      Xclosedir(dirp);
      return(dirlist);
}

static int NEAR _applydir(dir, funcf, funcd1, funcd2, order, endmes, verbose)
char *dir;
int (*funcf)__P_((char *));
int (*funcd1)__P_((char *));
int (*funcd2)__P_((char *));
int order;
char *endmes;
int verbose;
{
      DIR *dirp;
      struct dirent *dp;
      struct stat st;
      time_t dupmtime, dupatime;
      char *cp, *fname, path[MAXPATHLEN], **dirlist;
      int ret, ndir, max;

      if (intrkey()) return(-2);

      if (verbose) {
            locate(0, L_CMDLINE);
            putterm(l_clear);
            cp = (dir[0] == '.' && dir[1] == _SC_) ? dir + 2 : dir;
            cprintf2("[%.*k]", n_column - 2, cp);
            tflush();
      }
#ifdef      FAKEUNINIT
      else cp = NULL;   /* fake for -Wuninitialized */
#endif

      if (!funcd1 && !funcd2) order = 0;
      strcpy(path, dir);

      ret = max = 0;
      if (!order) dirlist = NULL;
      else dirlist = getdirtree(path, NULL, &max, (order == 2) ? 0 : 1);
      fname = strcatdelim(path);

      destmtime = destatime = (time_t)-1;
      if ((order == 1 || order == 2) && (ret = (*funcd1)(dir)) < 0) {
            if (ret == -1) warning(-1, dir);
            if (dirlist) {
                  for (ndir = 0; ndir < max; ndir++) free(dirlist[ndir]);
                  free(dirlist);
            }
            return(ret);
      }
      dupmtime = destmtime;
      dupatime = destatime;

      if (order) for (ndir = 0; ndir < max; ndir++) {
            if (order != 2)
                  ret = _applydir(dirlist[ndir], funcf,
                        funcd1, funcd2, order, NULL, verbose);
            else if ((ret = (*funcd1)(dirlist[ndir])) < 0) {
                  if (ret == -1) warning(-1, dir);
                  ret = -2;
            }
            else ret = _applydir(dirlist[ndir], funcf,
                  funcd1, funcd2, 0, NULL, verbose);
            if (ret < -1) {
                  for (; ndir < max; ndir++) free(dirlist[ndir]);
                  free(dirlist);
                  return(ret);
            }
            free(dirlist[ndir]);

            if (verbose) {
                  locate(0, L_CMDLINE);
                  putterm(l_clear);
                  cprintf2("[%.*k]", n_column - 2, cp);
                  tflush();
            }
      }
      if (dirlist) free(dirlist);

      if (!(dirp = Xopendir(dir))) warning(-1, dir);
      else {
            while ((dp = Xreaddir(dirp))) {
                  if (intrkey()) {
                        ret = -2;
                        break;
                  }
                  if (isdotdir(dp -> d_name)) continue;
                  strcpy(fname, dp -> d_name);

                  if (Xlstat(path, &st) < 0) warning(-1, path);
                  else if (s_isdir(&st)) continue;
                  else if ((ret = (*funcf)(path)) < 0) {
                        if (ret < -1) break;
                        warning(-1, path);
                  }
            }
            Xclosedir(dirp);
            if (ret < -1) return(ret);
      }

      destmtime = dupmtime;
      destatime = dupatime;
      if (funcd2 && (ret = (*funcd2)(dir)) < 0) {
            if (ret < -1) return(ret);
            warning(-1, dir);
      }
      if (endmes) warning(0, endmes);
      return(ret);
}

int applydir(dir, funcf, funcd1, funcd2, order, endmes)
char *dir;
int (*funcf)__P_((char *));
int (*funcd1)__P_((char *));
int (*funcd2)__P_((char *));
int order;
char *endmes;
{
      char path[MAXPATHLEN];
      int verbose;

      verbose = 1;
      if (!dir) {
            dir = ".";
            verbose = 0;
      }
      else if (dir[0] == '.' && dir[1] == '.' && !dir[2]) {
            realpath2(dir, path, 0);
            dir = path;
      }
#ifdef      _USEDOSEMU
      else dir = nodospath(path, dir);
#endif
      return(_applydir(dir, funcf, funcd1, funcd2, order, endmes, verbose));
}

/*ARGSUSED*/
int copyfile(arg, tr)
char *arg;
int tr;
{
      if (!mark && isdotdir(filelist[filepos].name)) {
            putterm(t_bell);
            return(0);
      }
#ifdef      _NOTREE
      destpath = getdestdir(COPYD_K, arg);
#else
# ifdef     _NODOSDRIVE
      destpath = (tr) ? tree(1, (int *)1) : getdestdir(COPYD_K, arg);
# else
      destpath = (tr) ? tree(1, &destdrive) : getdestdir(COPYD_K, arg);
# endif
#endif      /* !_NOTREE */

      if (!destpath) return((tr) ? 2 : 1);
      destdir = NULL;
      copypolicy = (issamedir(destpath, NULL)) ? (FLAG_SAMEDIR | 2) : 0;
#ifndef     _NODOSDRIVE
      if (dospath3("")) waitmes();
#endif
      if (mark > 0
      || (!isdir(&(filelist[filepos])) || islink(&(filelist[filepos]))))
            applyfile(safecopy, ENDCP_K);
      else {
#ifdef      _NOEXTRACOPY
            if (copypolicy) {
                  warning(EEXIST, filelist[filepos].name);
                  free(destpath);
                  return((tr) ? 2 : 1);
            }
#endif
            applydir(filelist[filepos].name, safecopy, cpdir, touchdir,
                  (islowerdir(destpath, filelist[filepos].name)) ? 2 : 1,
                  ENDCP_K);
      }

      free(destpath);
      if (destdir) free(destdir);
#ifndef     _NOEXTRACOPY
      if (forwardpath) free(forwardpath);
      forwardpath = NULL;
#endif
#ifndef     _NODOSDRIVE
      if (destdrive >= 0) shutdrv(destdrive);
#endif
#if   !defined (_NOEXTRACOPY) && !defined (_NODOSDRIVE)
      if (forwarddrive >= 0) shutdrv(forwarddrive);
      forwarddrive = -1;
#endif
      return(4);
}

/*ARGSUSED*/
int movefile(arg, tr)
char *arg;
int tr;
{
#ifdef      _USEDOSEMU
      char path[MAXPATHLEN];
#endif
      int i;

      if (!mark && isdotdir(filelist[filepos].name)) {
            putterm(t_bell);
            return(0);
      }
#ifdef      _NOTREE
      destpath = getdestdir(MOVED_K, arg);
#else
# ifdef     _NODOSDRIVE
      destpath = (tr) ? tree(1, (int *)1) : getdestdir(MOVED_K, arg);
# else
      destpath = (tr) ? tree(1, &destdrive) : getdestdir(MOVED_K, arg);
# endif
#endif      /* !_NOTREE */

      if (!destpath || issamedir(destpath, NULL)) return((tr) ? 2 : 1);
      destdir = NULL;
      copypolicy = removepolicy = 0;
      if (mark > 0) filepos = applyfile(safemove, ENDMV_K);
      else if (islowerdir(destpath, filelist[filepos].name))
            warning(EINVAL, filelist[filepos].name);
      else {
            i = safemove(fnodospath(path, filepos));
            if (!i) filepos++;
            else if (i == -1) {
#ifdef      _NOEXTRACOPY
                  warning(-1, filelist[filepos].name);
#else
                  if (errno != EXDEV
                  || !isdir(&(filelist[filepos]))
                  || islink(&(filelist[filepos])))
                        warning(-1, filelist[filepos].name);
                  else if (applydir(filelist[filepos].name,
                        safemove, cpdir, mvdir,
                        (islowerdir(destpath, filelist[filepos].name))
                        ? 2 : 1,
                        ENDMV_K) >= 0)
                              filepos++;
#endif
            }
      }

      if (filepos >= maxfile) filepos = maxfile - 1;
      free(destpath);
      if (destdir) free(destdir);
#ifndef     _NOEXTRACOPY
      if (forwardpath) free(forwardpath);
      forwardpath = NULL;
#endif
#ifndef     _NODOSDRIVE
      if (destdrive >= 0) shutdrv(destdrive);
#endif
#if   !defined (_NOEXTRACOPY) && !defined (_NODOSDRIVE)
      if (forwarddrive >= 0) shutdrv(forwarddrive);
      forwarddrive = -1;
#endif
      return(4);
}

static int forcecpfile(path)
char *path;
{
      struct stat st;
      char dest[MAXPATHLEN];

      if (getdestpath(path, dest, &st) < 0) return(0);
      if (safecpfile(path, dest, &st, NULL) < 0) return(-1);
#ifdef      HAVEFLAGS
      st.st_flags = (u_long)-1;
#endif
      return(touchfile(dest, &st));
}

static int forcecpdir(path)
char *path;
{
      struct stat st;
      char dest[MAXPATHLEN];
      int mode;

      if (isdotdir(path)) return(0);
      if (getdestpath(path, dest, &st) < 0) return(0);
      mode = (st.st_mode & 0777);
#if   MSDOS
      mode |= S_IWRITE;
#endif
      if (Xmkdir(dest, mode) >= 0) return(0);
      if (errno != EEXIST) return(-1);
      if (stat2(dest, &st) >= 0) {
            if (s_isdir(&st)) return(0);
            if (Xunlink(dest) >= 0 && Xmkdir(dest, mode) >= 0) return(0);
      }

      errno = EEXIST;
      return(-1);
}

static int forcetouchdir(path)
char *path;
{
      struct stat st;
      char dest[MAXPATHLEN];

      if (isdotdir(path)) return(0);
      if (getdestpath(path, dest, &st) < 0) return(-2);
#ifdef      HAVEFLAGS
      st.st_flags = (u_long)-1;
#endif
      return(touchfile(dest, &st));
}

int forcemovefile(dest)
char *dest;
{
      int ret;

      destpath = dest;
      ret = applydir(NULL, forcecpfile, forcecpdir, forcetouchdir, 1, NULL);
      destpath = NULL;
      return(ret);
}

Generated by  Doxygen 1.6.0   Back to index