home *** CD-ROM | disk | FTP | other *** search
/ kermit.columbia.edu / kermit.columbia.edu.tar / kermit.columbia.edu / uniflex / ufattr.c next >
C/C++ Source or Header  |  1993-08-22  |  9KB  |  302 lines

  1. /*
  2.    Kermit's attribute packets services
  3. */
  4.  
  5. #include "ufk.h"
  6. #include <stat.h>
  7. #include <time.h>
  8. #include <timeb.h>
  9.  
  10. #define leap(y) (!(y & 3))    /* Return TRUE if it's a leap year */
  11.  
  12. unsigned int perms,
  13.              operms;
  14. int owner;
  15. struct tm timbuf;
  16. char opsys[3];
  17.  
  18.  
  19. init_attributes()
  20. {
  21.    file_size = 0;                       /* for % display, remains 0 if none */
  22.    perms = 0xffff;                      /* 'world' permissions */
  23.    operms = 0xffff;                     /* permissions in our syntax */
  24.    timbuf.tm_yday = -1;                 /* no date given yet */
  25. }
  26.  
  27. snd_attributes()
  28. {
  29.    struct stat buf;
  30.    struct tm *localtime();
  31.    struct tm *tpt;
  32.    int locfp;
  33.    char *p,
  34.         hlpstr[16];
  35.  
  36.    locfp = open(filnam,0);
  37.    fstat(locfp,&buf);                     /* filnam is already verified */
  38.    p = sndpkt;
  39.  
  40. /* setup system of origin. Define UniFLEX to be number 'UF' */
  41.  
  42.    addstr('.',&p,"UF");
  43.  
  44. /* setup file size in blocks */
  45.  
  46.    sprintf(hlpstr,"%d",(int)((buf.st_size + 1024l) / 1024l));/* Rounded in K */
  47.    addstr('!',&p,hlpstr);
  48.  
  49. /* setup file size in bytes */
  50.  
  51.    sprintf(hlpstr,"%ld",buf.st_size);
  52.    addstr('1',&p,hlpstr);
  53.  
  54. /* setup creation date */
  55.  
  56.    tpt = localtime(&buf.st_mtime);
  57.    sprintf(hlpstr,"%02.2d%02.2d%02.2d %02.2d:%02.2d:%02.2d",
  58.            tpt->tm_year, tpt->tm_mon + 1, tpt->tm_mday,
  59.            tpt->tm_hour, tpt->tm_min, tpt->tm_secs);
  60.    addstr('#',&p,hlpstr);
  61.  
  62. /* setup file protection with respect to the world */
  63.  
  64.    *p++ = '-';
  65.    *p++ = tochar(1);
  66.    *p++ = tochar((buf.st_mode & S_IPRM) >> 3);
  67.  
  68. /* setup file protection in our syntax */
  69.  
  70.    *p++ = ',';
  71.    *p++ = tochar(2);
  72.    *p++ = tochar((buf.st_mode & S_IPRM) & 0x0f);
  73.    *p++ = tochar((buf.st_mode & S_IPRM) >> 4);
  74.  
  75. /* setup file owner */
  76.  
  77.    sprintf(hlpstr,"%d",buf.st_uid);
  78.    addstr('$',&p,hlpstr);
  79.  
  80. /* set file type */
  81.  
  82.    *p++ = '"';
  83.    *p++ = tochar(1);
  84.    if (binfil = seltype(locfp))
  85.       *p++ = 'B';                               /* Binary file */
  86.    else
  87.       *p++ = 'A';                               /* Ascii file */
  88.  
  89.    *p = '\0';
  90.    size = p - sndpkt;                           /* Final packet size */
  91.    close (locfp);
  92. }
  93.  
  94. rcv_attributes()
  95. {
  96.    int len,
  97.        filesize;
  98.    long dsize;
  99.    char *p,
  100.         *q,
  101.         *r,
  102.         *pos,
  103.         hlpstr[10],
  104.         type,
  105.         *index(),
  106.         *rindex();
  107.  
  108.    p = recpkt;
  109.    while (p < recpkt + size)
  110.    {
  111.       type = *p++;
  112.       if ((len = unchar(*p++)) != 0)
  113.       {
  114.          switch(type)
  115.          {
  116.             case '.':                   /* operating system origin */
  117.                   strncpy(opsys,p,len);
  118.                   opsys[len] = '\0';
  119.                   break;
  120.  
  121.             case '!':                   /* Filesize in K bytes */
  122.                   strncpy(hlpstr,p,len);
  123.                   hlpstr[len] = '\0';
  124.                   sscanf(hlpstr,"%d",&filesize);
  125.                   pos = rindex(rec_filnam,'/');
  126.                   if (pos == NULL)
  127.                      strcpy(hlpstr,".");
  128.                   else
  129.                   {
  130.                      strncpy(hlpstr,rec_filnam,pos - rec_filnam);
  131.                      hlpstr[pos-rec_filnam] = '\0';
  132.                   }
  133.                   dsize = get_free(hlpstr);    /* Get number of free blocks */
  134.                   if ((dsize == -1l) ||
  135.                       (dsize < (long)filesize))
  136.                      return(ERROR);            /* File too big to fit */
  137.                   break;
  138.  
  139.             case '1':                          /* Number of bytes in file */
  140.                   strncpy(hlpstr,p,len);
  141.                   hlpstr[len] = '\0';
  142.                   sscanf(hlpstr,"%ld",&file_size);
  143.                   break;
  144.  
  145.              case '"':                         /* File type */
  146.                   type = *p;
  147.                   if (type == 'A')
  148.                      binfil = FALSE;           /* Ascii */
  149.                   else if (type == 'B')
  150.                      binfil = TRUE;            /* Binary */
  151.                   break;
  152.  
  153.             case '-':                          /* File permissions */
  154.                   perms = unchar(*p) & 7;
  155.                   break;
  156.  
  157.             case ',':                     /* File permissions in our syntax */
  158.                   operms = unchar(p[0]);
  159.                   if (len > 1)
  160.                      operms |= (unchar(p[1]) << 4);
  161.                   break;
  162.  
  163.             case '$':                          /* File owner */
  164.                   strncpy(hlpstr,p,len);
  165.                   hlpstr[len] = '\0';
  166.                   sscanf(hlpstr,"%d",&owner);
  167.                   break;
  168.  
  169.             case '#':                          /* File date */
  170.                   q = p;                /* Check if date and time specified */
  171.                   if (len > 8)
  172.                   {                     /* both date and time */
  173.                      r = index(p,' ');
  174.                      if ((r - p) == 8)
  175.                         q = &p[2];      /* skip first two digits of date */
  176.                   }
  177.                   else if (len == 8)    /* only date specified */
  178.                      q = &p[2];
  179.  
  180.                   timbuf.tm_hour = 0;   /* Zero out optional items */
  181.                   timbuf.tm_min = 0;
  182.                   timbuf.tm_secs = 0;
  183.                   sscanf(q,"%2d%2d%2d %d:%d:%d",
  184.                             &timbuf.tm_year,
  185.                             &timbuf.tm_mon,
  186.                             &timbuf.tm_mday,
  187.                             &timbuf.tm_hour,
  188.                             &timbuf.tm_min,
  189.                             &timbuf.tm_secs);
  190.                   timbuf.tm_mon--;             /* Adjust month */
  191.                   timbuf.tm_yday = 0;          /* Flag date given */
  192.                   break;
  193.  
  194.             default:
  195.                   break;
  196.          }
  197.       }
  198.       p += len;
  199.    }
  200.    return NULL;
  201. }
  202.  
  203. seltype(fp)
  204. int fp;
  205. {
  206.    unsigned char filechar[256];
  207.    char *i;
  208.    int size;
  209.  
  210.    size = read(fp,filechar,256);
  211.  
  212.    for (i = filechar; i < &filechar[size]; i++)
  213.       if ((*i != 0x09) &&               /* tab */
  214.           (*i != 0x0a) &&               /* linefeed */
  215.           (*i != 0x0c) &&               /* formfeed */
  216.           (*i != 0x0d) &&               /* carriage return */
  217.           ((*i  > 0x7e) || (*i  < 0x20)) )
  218.          return TRUE;                   /* it must be binary */
  219.    return FALSE;                        /* ascii */
  220. }
  221.  
  222. fset_attributes()
  223. {
  224.    long cvttime();
  225.  
  226.    struct stat buf;
  227.  
  228.    if (stat(rec_filnam,&buf))           /* Get status of current filename */
  229.       prterr(ER_PERMS);
  230.    else
  231.    {
  232.       if (perms != 0xffff)
  233.       {                                    /* 'world' syntax */
  234.          perms = (buf.st_mode &
  235.                   S_IPRM &                 /* Mask for permissions */
  236.                   ~(S_IOREAD | S_IOWRITE | S_IOEXEC)) |
  237.                   (perms << 3);            /* set new 'other' bits */
  238.          if (chmod(rec_filnam,perms) == ERROR)
  239.             prterr(ER_PERMS);
  240.       }
  241.       if ((operms != 0xffff) &&
  242.           (strcmp(opsys,"UF") == 0))       /* 'our' syntax */
  243.          if (chmod(rec_filnam,operms) == ERROR)
  244.             prterr(ER_PERMS);
  245.    }
  246.    if (timbuf.tm_yday != -1)
  247.       fset_date(rec_filnam,cvttime(&timbuf));  /* Set new date */
  248. }
  249.  
  250. addstr(type,q,string)
  251. char type,
  252.      **q,
  253.      *string;
  254. {
  255.    int length;
  256.  
  257.    length = strlen(string);
  258.    *(*q)++ = type;
  259.    *(*q)++ = tochar(length);
  260.    strcpy(*q,string);
  261.    *q += length;
  262. }
  263.  
  264. long cvttime(buf)
  265. struct tm *buf;
  266. {
  267.    struct timeb tbuf;         /* To read the timezone */
  268.    static char daytab[] = {   /* Number of days for each month */
  269.       31, 28, 31, 30,
  270.       31, 30, 31, 31,
  271.       30, 31, 30, 31
  272.       };
  273.    int days_so_far,
  274.        i,
  275.        j;
  276.    long int sec_sin_80;        /* Accumulated number of seconds */
  277.  
  278.    days_so_far = 0;
  279.    for (j = 80; j < buf->tm_year; j++)/* Calc number of days for past years */
  280.    {
  281.       for (i = 0; i < 12; i++)
  282.          days_so_far += daytab[i]; /* Add number of days in a year */
  283.       if (leap(j))
  284.          days_so_far++;            /* one more in a leap year */
  285.    }
  286.    for (i = 0; i < buf->tm_mon; i++)/* Calc number of days for past months */
  287.    {
  288.       days_so_far += daytab[i];
  289.       if ((i == 1) && leap(buf->tm_year))
  290.          days_so_far++;             /* Take care of 29 februari */
  291.    }
  292.    days_so_far += buf->tm_mday - 1;     /* Add number of days this month */
  293.    sec_sin_80 = ((long)buf->tm_hour * 3600) +
  294.                  (buf->tm_min * 60) +
  295.                   buf->tm_secs;
  296.    sec_sin_80 += days_so_far * (long) 86400;
  297.  
  298.    ftime(&tbuf);                    /* Get timezone value */
  299.    sec_sin_80 += tbuf.timezone * 60; /* Correct for it */
  300.    return(sec_sin_80);               /* That's it, return the time */
  301. }
  302.