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