⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 filesys.c

📁 picoos源码。The RTOS and the TCP/IP stack will be built automatically.
💻 C
📖 第 1 页 / 共 4 页
字号:
}


/* test if a directory is empty */
sint_t fs_isDirEmpty(const char *pathname, char **fnout)
{
  sint_t l;
  s32_t  rc;

  l = fsys_buildPathName(fsearch_g.mask, pathname, "*");
  if (l < 0)
    return -1;

  if ((fsearch_g.mask[0] == 0) || (fsearch_g.mask[0] == '*'))
    return -1;

  fsearch_g.image = -1;
  rc = fs_findnext(&fsearch_g, &finfo_g);

  if (rc >= 0)
    return 0;  /* directory not empty */

  if (fnout != NULL)
  {
    fsearch_g.mask[l-2] = 0;
    *fnout = fsearch_g.mask;
  }

  return 1;
}
 
#endif /* FS_SUBDIRECTORIES */


/*-------------------------------------------------------------------------*/


static sint_t  fs_seek(const sint_t file, const sint_t position,
                       const sint_t origin)
{
  FSROOTBLOCK_t *rb;
  FSFILE_t  *f;
  u32_t     i, b, pb, lb, r, p, n;
  s32_t     t;

  f = &fsFileList_g[file];
  if (!(f->flags & FSFILE_F_USED))
    return -1;

  rb = FSROOTBLOCK(f->image);

  switch (origin)
  {
    case FSSEEK_SET:
    {
      t = 0;
      break;
    }
    case FSSEEK_CUR:
    {
      t = (s32_t) f->curPosition;
      break;
    }
    case FSSEEK_END:
    {
      t = (s32_t) f->dblockptr->filesize;
      break;
    }
    default:
    {
      return -1;
    }
  }

  t += (s32_t) position;
  if (t < 0)
    return -1;

  p = (u32_t) t;
  i = (p + (FS_DATABYTESPERBLOCK(rb) - 1)) / FS_DATABYTESPERBLOCK(rb);

  if (p > f->dblockptr->filesize)
  {
    if (f->mode & FSO_RDONLY)
      return -1;

    /* increase the file size */
    lb = fs_lastBlock(rb, f->dirblock, &n);
    i -= n;
    b  = lb;
    pb = 0;
    r  = 0;
    while (i > 0)
    {
      b = fs_allocBlock(rb);
      if (b == 0)
      {
        fs_freeBlockChain(rb, r);
        return -1;
      }
      if (r == 0)
      {
        r  = b;
        pb = b;
      }
      else
      {
        fs_getBlock(rb, pb)->nextBlock = b;
        pb = b;
      }
      i--;
    }
    if (lb == 0)
    {
      f->dblockptr->firstFileBlock = r;
    }
    else
    {
      fs_getBlock(rb, lb)->nextBlock = r;
    }
    f->dblockptr->filesize = p;
  }
  else
  {
    b = 0;
    if (p != 0)
    {
      b = f->dblockptr->firstFileBlock;
      while ((b != 0) && (i > 1))
      {
        b = fs_getBlock(rb, b)->nextBlock;
        i--;
      }
      if (i > 1)
        return -1; /* error, should never happen */
    }
  }

  f->curDataPtr  = p % FS_DATABYTESPERBLOCK(rb);
  f->curBlock    = b;
  f->curPosition = p;
  return (sint_t) p;
}


static u32_t fs_lastBlock(FSROOTBLOCK_t *rb, u32_t dirblock, u32_t *blocks)
{
  FSBLOCK_t *bl;
  u32_t b, l, n;

  n = 0;
  l = 0;
  b = fs_getDirBlock(rb, dirblock)->firstFileBlock;
  while (b != 0)
  {
    l  = b;
    bl = fs_getBlock(rb, b);
    b  = bl->nextBlock;
    n++;
  }
  if (blocks != NULL)
    *blocks = n;
  return l;
}


static sint_t fs_isFileOpened(const char* filename, sint_t forWriting)
{
  sint_t i;

  for (i=0; i<FS_MAXFILES; i++)
  {
    if (fsFileList_g[i].flags & FSFILE_F_USED)
    {
      if (!(fsFileList_g[i].dblockptr->flags & FSDIR_F_IGNORE) &&
          (sysStrncmp(fsFileList_g[i].dblockptr->filename, filename,
           FSROOTBLOCK(fsFileList_g[i].image)->maxFilenameLength) == 0))
      {
        if ((forWriting == 0) || !(fsFileList_g[i].mode & FSO_RDONLY))
          return 1;
      }
    }
  }

  return 0;
}


static void fs_incRefCount(sint_t img, u32_t dirblock)
{
  sint_t i, f = -1;

  for (i=0; i<FS_MAXFILES; i++)
  {
    if (fsRefList_g[i].refcount != 0)
    {
      if ((fsRefList_g[i].image == img) &&
          (fsRefList_g[i].dirblock == dirblock))
      {
        fsRefList_g[i].refcount++;
        return;
      }
    }
    else
    {
      if (f < 0)
        f = i;
    }
  }

  fsRefList_g[f].image    = img;
  fsRefList_g[f].dirblock = dirblock;
  fsRefList_g[f].refcount = 1;
}


static void fs_decRefCount(sint_t img, u32_t dirblock)
{
  FSROOTBLOCK_t *rb;
  FSDIRBLOCK_t  *dbl;
  sint_t i;

  rb = FSROOTBLOCK(img);

  for (i=0; i<FS_MAXFILES; i++)
  {
    if ((fsRefList_g[i].refcount != 0) &&
        (fsRefList_g[i].image == img) &&
        (fsRefList_g[i].dirblock == dirblock))
    {
      if (--fsRefList_g[i].refcount == 0)
      {
        dbl = fs_getDirBlock(rb, dirblock);
        if (dbl->flags & FSDIR_F_DELONCLOSE)
        {
          /* remove directory entry */
          fs_removeDirEntry(rb, dirblock);
        }
      }
      break;
    }
  }
}


static FSBLOCK_t* fs_getBlock(FSROOTBLOCK_t *rb, u32_t blocknbr)
{
  FSBLOCK_t     *bl;

  bl = (FSBLOCK_t*) (void*) 
         (((u32_t*)rb) + ((rb->bytesPerBlock * blocknbr) / sizeof(u32_t)));

  return bl;
}

static FSDIRBLOCK_t* fs_getDirBlock(FSROOTBLOCK_t *rb, u32_t blocknbr)
{
  FSDIRBLOCK_t  *db;
  u32_t         bofs;

  bofs = rb->bytesPerBlock * (blocknbr / rb->dirBlocksPerBlock);
  db =  (FSDIRBLOCK_t*)(void*) 
          (((u32_t*)rb) + ((bofs + (rb->bytesPerDirBlock * 
             (blocknbr % rb->dirBlocksPerBlock))) / sizeof(u32_t)));

  return db;
}


/*-------------------------------------------------------------------------*/


static sint_t fs_containWildcard(const char* filename)
{
  char *c = (char*) filename;

  if (filename != NULL)
  {
    while (*c != 0)
    {
      if ((*c == '?') || (*c == '*'))
        return 1;
      c++;
    }
  }
  return 0;
}


static char* fs_validateFileName(const char* filename)
{
  char *s = (char*) filename;
  char *d = fnbuffer_g;
#if FS_SUBDIRECTORIES
  sint_t  img;
  u32_t   b;
  sint_t  j;
#else
  sint_t  i, j;
#endif

  if (s == d)
    return d;

  *d = 0;
  if (s == NULL)
    return d;

  while ((*s != 0) && ((*s <= ' ') || (*s == '/') || (*s =='\\'))) s++;

#if !FS_SUBDIRECTORIES

  for (i=0, j=0; (s[i] != 0) && (j < (FS_MAXFNAMELEN-1)); i++)
  {
    if ((s[i] == '\\') || (s[i] == '/'))
    {
      if ((j == 0) || (d[j-1] != '/'))
      {
        d[j++] = '/';
      }
    }
    else
    {
      d[j++] = s[i];
    }
  }

  while ((j > 0) && (d[j-1] <= ' ')) j--;
  if ((j > 0) && (d[j-1] == '/'))  j = 0;
  d[j] = 0;

#else /* !FS_SUBDIRECTORIES */

  j = sysStrlen(s);
  while ((j > 0) && (s[j-1] != '/')) j--;
  sysStrcpy(d, s);
  if (j > 0)
  {
    d[j-1] = 0;
    j = fsys_buildPathName(d, d, &d[j]);
    if (j < 0)
      return d;
  }

  /* validate the directory path */
  while ((j > 0) && (d[--j] != '/'));
  if (j > 0)
  {
    d[j] = 0;
    b = fs_findFile(&img, d);
    if (b == 0)
    {
      *d = 0;
    }
    else
    {
      if ((fs_getDirBlock(FSROOTBLOCK(img), b)->flags & FSDIR_F_SUBDIR) == 0)
      {
        *d = 0;
      }
      else
      {
        d[j] = '/';
      }
    }
  }

#endif
  return d;
}


#if FS_SUBDIRECTORIES

sint_t fsys_buildPathName(char *outbuf, const char *pathname,
                          const char *filename)
{
  sint_t s = 0, d = 0;
  const char *p, *f;
  char   b, c;

  p = pathname;
  f = filename;
  if ((*f == '/') || (*f == '\\'))
  {
    p = filename;
    f = NULL;
  }

  while ((p[s] == '/') || (p[s] == '\\') ||
         (p[s] == ' ')) s++;

  while ((c = p[s++]) != 0)
  {
    if ((c == '?') || (c == '*') || (d >= (FS_MAXFNAMELEN-4)))
    {
      *outbuf = 0;
      return -1;
    }
    if (c == '\\')
      c = '/';

    if ((c == '/') && (s > 1) &&
        ((p[s-2] == '/') || (p[s-2] == '\\')))
    {
      continue;
    }

    if ((d == 0) || (outbuf[d-1] == '/'))
    {
      if (c == '.')
      {
        b = p[s];
        if ((b == '/') || (b == '\\') || (b == 0))
        {
          s += 1;
          continue;
        }
        if ((b == '.') &&
            ((p[s+1] == '\\') || (p[s+1] == '/') ||
             (p[s+1] == 0)))
        {
          if ((d > 0) && (outbuf[d-1] == '/')) d--;
          while ((d > 0) && (outbuf[d-1] != '/')) d--;
          if (p[s+1] == 0)
            break;
          s += 2;
          continue;
        }
      }
    }

    if ((d != 0) || (c != '/'))
    {
      outbuf[d++] = c;
    }
  }

  if ((d > 0) && (outbuf[d-1] != '/'))
    outbuf[d++] = '/';

  if (f == NULL)
  {
    d--;
  }
  else
  {
    s = 0;
    while ((f[s] == '/') || (f[s] == '\\') ||
           (f[s] == ' ')) s++;

    if ((f[s] == '.') &&
        ((f[s+1] == 0) ||
         ((f[s+1] == '.') && (f[s+2] == '0'))))
    {
      *outbuf = 0;
      return -1;
    }
    while (f[s] != 0)
    {
      outbuf[d++] = f[s++];
    }
  }

  outbuf[d] = 0;
  return d;
}

#endif /* FS_SUBDIRECTORIES */


static void fs_getCurrentTime(struct fsys_time *fstime)
{
#ifdef HAVE_LOCALTIME

  time_t     ltime;
  struct tm  *today;

  time(&ltime);
  today = localtime(&ltime);
  if (today == NULL)
    return;

  fstime->year  = (u16_t) today->tm_year + 1900;
  fstime->month = (u8_t)  today->tm_mon + 1;
  fstime->day   = (u8_t)  today->tm_mday;
  fstime->hour  = (u8_t)  today->tm_hour;
  fstime->min   = (u8_t)  today->tm_min;
  fstime->sec   = (u8_t)  today->tm_sec;

#else

  fstime->year  = 2000;
  fstime->month = 1;
  fstime->day   = 1;
  fstime->hour  = 0;
  fstime->min   = 0;
  fstime->sec   = 0;

#endif
}


/*-------------------------------------------------------------------------*/


static u32_t  fs_findFile(sint_t *img, const char *filename)
{
  FSROOTBLOCK_t *rb;
  FSDIRBLOCK_t  *dbl;
  u32_t b, pb;
  sint_t i;

  if (*filename == 0)
    return 0;

  for (i=0; i<FS_MAXIMAGES; i++)
  {
    rb = FSROOTBLOCK(i);
    if (rb == NULL)
      continue;

    pb = 0;
    b  = rb->firstDirBlock;
    while (b != 0)
    {
      dbl = fs_getDirBlock(rb, b);
      if (!(dbl->flags & FSDIR_F_IGNORE) &&
          (sysStricmp(dbl->filename, filename) == 0))
      {
        if (img != NULL)
          *img = i;
        return b;
      }
      pb = b;
      b  = dbl->nextBlock;
    }
  }
  return 0;
}


static sint_t  fs_open(const char *filename, const sint_t mode)

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -