[comp.sys.acorn] ADFS <-> Unix file names

fl@tools.uucp (Frank Lancaster) (01/23/91)

Here are my file name and time conversion routines.

Frank Lancaster

/*****************************************************************************/
/*                                                                           */
/* File name conversion routines                                             */
/*                                                                           */
/*****************************************************************************/

#define UNIX_DIRSEP  '/'
#define FS_DIRSEP    '.'
#define REPLACE_CHR  '_'
#define MAXLEAFLEN   10
#define MAXPATHLEN      256

int sflag; /* see tar documentation */
int zflag;
int Eflag;
int Sflag;

static char Buffer[MAXPATHLEN];

int name_to_unix(char *Name) {
  char *LastSep, *cp, *Ext;

  LastSep = NULL;
  Ext = Name;
  cp = Name;
  while (*cp) {
    if (*cp == FS_DIRSEP) {
      if (LastSep != NULL)
        Ext = LastSep + 1;
      LastSep = cp;
      *cp = UNIX_DIRSEP;
    } else if (*cp == UNIX_DIRSEP)
      *cp = REPLACE_CHR;
    else if (*cp == '!')
      *cp = '.';
    cp++;
  }
  if (LastSep != NULL) {
    *LastSep = '\0';
    if (strlen(Ext) > MaxExtLength)
      *LastSep = UNIX_DIRSEP;
    else {
      if (*(LastSep + 1) == '\0')
        return 0;
      strcpy(Buffer,Ext);
      *Ext = 0;
      strcpy(Ext,LastSep + 1);
      strcat(Name,".");
      strcat(Name,Buffer);
    }
  }
  return 1;
} /* name_to_unix */


static int chktruncate(char *leaf, char *rest) {
  int len,n;
  char *cp,*cp2;

  n = 0;
  if ((len = strlen(leaf)) > MAXLEAFLEN) {
    fprintf(stderr,"tar: shorten: %s -> ",leaf);
    cp = leaf;
    while (*cp && len > MAXLEAFLEN) {
      switch (*cp) {
        case 'a':
        case 'e':
        case 'i':
        case 'o':
        case 'u':
        case '-':
          if (cp != leaf) {
            n += 1;
            len -= 1;
            cp2 = cp+1;
            while (*cp2) {
              *(cp2-1) = *cp2;
              cp2++;
            }
            *(cp2-1) = 0;
            break;
          }
        default:
          cp++;
          break;
      }
    }
    if ((len = strlen(leaf)) > MAXLEAFLEN) {
      n += len-MAXLEAFLEN;
      *(leaf+MAXLEAFLEN) = 0;
    }
    if (n > 0 && rest != NULL) {
      cp++;
      cp2 = rest;
      while (*cp2)
        *cp++ = *cp2++;
    }
    fprintf(stderr,"%s\n",leaf);
  }
  return(n);
} /* truncate */


void name_to_fs(char *name) {
  char *cp, *leaf, *ext;
  int extlen;

  Buffer[0] = '\0';
  leaf = name;
  ext = NULL;

  for (cp = name; *cp; cp++) {
    if (*cp == UNIX_DIRSEP) {
      *cp = 0;
      cp -= chktruncate(leaf,cp + 1);
      if ((sflag || Sflag) && Buffer[0] != '\0') {
        if (Sflag) {
        }
        Buffer[0] = '\0';
      }
      *cp = FS_DIRSEP;
      leaf = cp + 1;
    } else if (*cp == FS_DIRSEP) {
      if (sflag || Sflag) {
        *cp = '\0';
        if (Zflag && *(cp + 1) && strcmp(cp + 1, "Z") == 0) {
          if (Buffer[0] == '\0')
            strcpy(Buffer,leaf);
          strcat(Buffer,CompressExt);
          cp++;
        } else {
          strcpy(Buffer,leaf);
          if (Eflag)
            *cp = REPLACE_CHR;
          else
            *cp = FS_DIRSEP;
          ext = cp + 1;
        }
      } else if (Eflag)
        *cp = REPLACE_CHR;
      else {
        *cp = 0;
        cp -= chktruncate(leaf,cp+1);
        *cp = FS_DIRSEP;
        leaf =cp + 1;
      }
    } else if (Eflag && *cp == REPLACE_CHR) {
      *cp = 0;
      strcpy(Buffer,name);
      strcat(Buffer,cp+1);
      strcpy(name,Buffer);
      cp--;
    }
  }
  if ((sflag || Sflag) && Buffer[0] != '\0') {
    if (ext != NULL) {
      extlen = strlen(ext);
      strcpy(leaf,ext);
      leaf += extlen;
      *leaf++ = '.';
    }
    strcpy(leaf,Buffer);
    Buffer[0] = '\0';
  }
  chktruncate(leaf,(char *)NULL);
} /* name_to_fs */


/*****************************************************************************/
/*                                                                           */
/* Time conversion routines                                                  */
/*                                                                           */
/*****************************************************************************/

#include <limits.h>

/* 5 byte time value for 1970 in centi-seconds: */
static unsigned char TimeShift[5] = { 96, 106, 153, 110, 51 };


void unix_to_fs_time(unsigned char *fstime, unsigned long unixtime) {
  int Cnt;
  signed long Carry,tmp;

  fstime[4] = 0;
  fstime[3] = (unsigned char)(unixtime >> 24);
  fstime[2] = (unsigned char)(unixtime >> 16) & 255;
  fstime[1] = (unsigned char)(unixtime >>  8) & 255;
  fstime[0] = (unsigned char)(unixtime & 255);
  Carry = 0;
  Cnt = 0;
  while (Cnt <= 4) {
    tmp = fstime[Cnt] * 100 + Carry;
    Carry = 0;
    while (tmp >= 256) {
      Carry++;
      tmp -= 256;
    }
    fstime[Cnt] = (unsigned char)tmp;
    Cnt++;
  }
  Carry = 0;
  Cnt = 0;
  while (Cnt <= 4) {
    tmp = fstime[Cnt] + TimeShift[Cnt] + Carry;
    Carry = 0;
    if (tmp >= 256) {
      Carry = 1;
      tmp -= 256;
    }
    fstime[Cnt] = (unsigned char)tmp;
    Cnt++;
  }
} /* unix_to_fs_time */


unsigned long fs_to_unix_time(unsigned char *FStime) {
  signed int Cnt;
  signed long tmp,Carry,divident;
  unsigned char fstime[5];

  Cnt = 0;
  Carry = 0;
  while (Cnt <= 4) {
    tmp = FStime[Cnt] - TimeShift[Cnt] - Carry;
    Carry = 0;
    if (tmp < 0) {
      tmp += 256;
      Carry = 1;
    }
    fstime[Cnt] = (unsigned char)tmp;
    Cnt++;
  }
  if (Carry > 0) {
    fprintf(stderr,"tar: warning: UNIX time underflow\n");
    return 0;
  }
  Cnt = 4;
  Carry = 0;
  while (Cnt >= 0) {
    divident = (Carry * 256 + fstime[Cnt]); 
    tmp =  divident / 100;
    Carry = divident - tmp * 100;
    fstime[Cnt] = (unsigned char)tmp;
    Cnt--;
  }
  if (Carry * 256 / 100 >= 128)
    fstime[0]++;
  if (fstime[4] > 0) {
    fprintf(stderr,"tar: warning: UNIX time overflow");
    return ULONG_MAX;
  } else
    return fstime[0] +
           fstime[1] * 256 +
           fstime[2] * 256 * 256 +
           fstime[3] * 256 * 256 * 256;
} /* fs_to_unix_time */

OSmith@acorn.co.uk (Owen Smith) (01/24/91)

In article <1399@karl.UUCP> fl@tools.uucp (Frank Lancaster) writes:

>Here are my file name and time conversion routines.

How about some comments? A readable layout style would be helpful too.
You don't have to copy the Unix hackers' dreadful coding style you know :-)
The views expressed are my own and are not necessarily those of Acorn.

gtoal@tharr.UUCP (Graham Toal) (01/27/91)

In article <4767@acorn.co.uk> OSmith@acorn.co.uk (Owen Smith) writes:
>In article <1399@karl.UUCP> fl@tools.uucp (Frank Lancaster) writes:
>
>>Here are my file name and time conversion routines.
>
>How about some comments? A readable layout style would be helpful too.
>You don't have to copy the Unix hackers' dreadful coding style you know :-)
>The views expressed are my own and are not necessarily those of Acorn.


Come on, Owen, give the guy a break.  Real Programmers (tm) don't
need comments anyway.  The code was perfectly readable to me, and I'd
like to thank Frank for posting the source in a readable format.  It's
the first posting I've been able to download from this group in months.
G
PS Anyone for 'indent'? I think I have it kicking around somewhere...
-- 
(* Posted from tharr.uucp - Public Access Unix - +44 (234) 261804 *)

fl@tools.uucp (Frank Lancaster) (01/28/91)

Owen Smith writes:
>How about some comments? A readable layout style would be helpful too.

Well, maybe if I were employed by Acorn, I would have enough time
to comment PD sources. I find my layout style more readable than
the normal C hack style.

These opions are mine, and only mine.

Frank Lancaster