示例#1
0
/*
 * Given an absolute path to a file (for example /a/b/myFile), vfs_create 
 * will create a new file named myFile in the /a/b directory.
 *
 */
static int vfs_create(const char *path, mode_t mode, struct fuse_file_info *fi) {
  vcb vb = getvcb(); // Get our VCB, used to find start/end points of dirents.

  if(validate_path(path) != 0) // If the path is invalid, return an error.
    return -1;
  path++; // Increment path, getting rid of the leading /.

  int first_free = -1; // Index of first free dirent. 

  // To create a file, we need to first read used dirents and search for a duplicate.
  for(int i = vb.de_start; i < vb.de_start+vb.de_length && first_free < 0; i++){
    dirent de = getdirent(i);
 
    if(de.valid == 1){
      if(strcmp(de.name, path) == 0)
        return -EEXIST;
    } 
    else{
        first_free = i;
    }
  }

  // File doesn't already exist. Next, check for free spaces. If free_flag != 0 first_free == idx of first free dirent.
  if(first_free >= 0){ // If free dirents exist...
    dirent new_file; // Creating a new dirent, and assign its fields.
    new_file.valid = 1;
    new_file.first_block = -1; // Used to indicate a file with no data.
    new_file.size = 0;
    new_file.userid = getuid();
    new_file.groupid = getgid();
    new_file.mode = mode;

    struct timespec newtime;
    clock_gettime(CLOCK_REALTIME, &newtime);

    new_file.access_time = newtime;
    new_file.modify_time = newtime;
    new_file.create_time = newtime;

    memset(new_file.name,0,sizeof(new_file.name));

    //char file_name[27];
    //memset(file_name,0,27);
    char file_name[512 - (3*sizeof(struct timespec)) - 24]; // Build the name string...
    memset(file_name,0,sizeof(file_name));
    strcpy(file_name,path); // Save path in to filename. Note: path has already been incrimented, so we're good.
    strcpy(new_file.name, file_name);

    setdirent(first_free,new_file); // Finally, we write our new dirent to disk at the index of first_free.
    return 0;
  }
  return -1; // If we reached here, free_flag == 0, meaning no free dirents exist.
}
示例#2
0
文件: fsls.c 项目: wgdavies/fs-utils
/** Process command line arguements and decide how to proceed.
 *  Includes explanatory text for inline help and self-documentation.
 */
int main( int argc, char *argv[] )
{
    int descend_flag = 0, hadoop_flag = 0, stats_flag = 0, verbose_flag = 0, json_flag = 0;
    int count = 0, ret_val = 0;
    g_dir_arg = "."; /// set the default directory argument to "here"
    poptContext pc;
    struct poptOption po[] = {
	{"descend", 'd', POPT_ARG_NONE, &descend_flag, 0, UNIMPL"Parallelise and descend into subdirectories.", NULL},
	{"stats",   's', POPT_ARG_NONE, &stats_flag,   0, "Print detailed statistics.", NULL},
	{"verbose", 'v', POPT_ARG_NONE, &verbose_flag, 0, UNIMPL"Expand statistics output for each subdirectory.", NULL},
	{"json",    'j', POPT_ARG_NONE, &json_flag,    0, UNIMPL"Write output in JSON format.", NULL},
	POPT_AUTOHELP
	POPT_TABLEEND
    };
    
    pc = poptGetContext(NULL, argc, (const char **)argv, po, 0);
    poptSetOtherOptionHelp(pc, "[directory]");
    
    while ( (count = poptGetNextOpt(pc) ) >= 0 ) {
	printf("poptGetNextOpt return val %d\n", count);
    }

    for ( count = 0 ; poptPeekArg(pc) != NULL ; ++count ) {
	asprintf(&g_dir_arg, (char*)poptGetArg(pc));
	
	if ( count > 0 ) {
	    poptPrintUsage(pc, stderr, 0);
	    goto EXITNOW;
	}
    }
    
    if ( descend_flag + hadoop_flag + stats_flag + verbose_flag + json_flag > 5 ) {
	poptPrintUsage(pc, stderr, 0);
	goto EXITNOW;
    } else {
	if ( descend_flag != POPT_ARG_NONE ) printf("%s: %s %s\n", PROGNAME, UNIMPL, "descend");
	else if ( stats_flag != POPT_ARG_NONE ) ret_val = getdirent(g_dir_arg);
	else if ( verbose_flag != POPT_ARG_NONE ) printf("%s: %s %s\n", PROGNAME, UNIMPL, "verbose");
	else if ( json_flag != POPT_ARG_NONE ) printf("%s: %s %s\n", PROGNAME, UNIMPL, "json");
	else ret_val = quickcount(g_dir_arg);
    }
    
    if ( ret_val == 0 ) { 
	exit(EXIT_SUCCESS);
    } else {
	goto EXITNOW;
    }

EXITNOW:
    exit(EXIT_FAILURE);
}
示例#3
0
/** Read directory
 *
 * Given an absolute path to a directory, vfs_readdir will return 
 * all the files and directories in that directory.
 *
 * HINT:
 * Use the filler parameter to fill in, look at fusexmp.c to see an example
 * Prototype below
 *
 * Function to add an entry in a readdir() operation
 *
 * @param buf the buffer passed to the readdir() operation
 * @param name the file name of the directory entry
 * @param stat file attributes, can be NULL
 * @param off offset of the next entry or zero
 * @return 1 if buffer is full, zero otherwise
 * typedef int (*fuse_fill_dir_t) (void *buf, const char *name,
 *                                 const struct stat *stbuf, off_t off);
 *			   
 * Your solution should not need to touch fi
 *
 */
static int vfs_readdir(const char *path, void *buf, fuse_fill_dir_t filler,
                       off_t offset, struct fuse_file_info *fi)
{
  if(strcmp(path, "/") == 0){
    vcb vb = getvcb();
    for(int i = vb.de_start; i < vb.de_start+vb.de_length; i++){
      dirent de = getdirent(i);
      if(filler(buf, de.name, NULL, 0) != 0){
	return -ENOMEM;
      }
    }
    return 0;
  }else{
    return -1;
  }
}
示例#4
0
/*
 * The function rename will rename a file or directory named by the
 * string 'oldpath' and rename it to the file name specified by 'newpath'.
 *
 * HINT: Renaming could also be moving in disguise
 *
 */
static int vfs_rename(const char *from, const char *to)
{
  vcb vb = getvcb();

  if(validate_path(from) != 0)
    return -1;

  from++;
  for(int i = vb.de_start; i < vb.de_start+vb.de_length;i++){
    dirent de = getdirent(i);
    if(strcmp(de.name,from) == 0){
      strcpy(de.name, to);
      return 0;
    }
  }
  return -1;
}
示例#5
0
/*
 * This function will change the permissions on the file
 * to be mode.  This should only update the file's mode.  
 * Only the permission bits of mode should be examined 
 * (basically, the last 16 bits).  You should do something like
 * 
 * fcb->mode = (mode & 0x0000ffff);
 *
 */
static int vfs_chmod(const char *file, mode_t mode)
{
  vcb vb = getvcb();
  
  if(validate_path(file) != 0)
    return -1; // Invalid path.
  
  file++;
  for(int i = vb.de_start; i < vb.de_start+vb.de_length; i++){
    dirent de = getdirent(i);
    if(strcmp(de.name,file)==0){
      //de.mode = (mode & 0x0000ffff);
      de.mode = mode;
      setdirent(i,de);
      return 0; // Success
    }
  }
  return -1; // File not found.
}
示例#6
0
/*
 * This function will update the file's last accessed time to
 * be ts[0] and will update the file's last modified time to be ts[1].
 */
static int vfs_utimens(const char *file, const struct timespec ts[2])
{
  vcb vb = getvcb();
  
  if(validate_path(file) != 0)
    return -1; // Invalid path.
  
  file++;
  for(int i = vb.de_start; i < vb.de_start+vb.de_length; i++){
    dirent de = getdirent(i);
    if(strcmp(de.name,file)==0){
      de.access_time = ts[0];
      de.modify_time = ts[1];
      setdirent(i,de);
      return 0; // Success
    }
  }
  return -1; // File not found.
}
示例#7
0
/*
 * This function will change the user and group of the file
 * to be uid and gid.  This should only update the file's owner
 * and group.
 */
static int vfs_chown(const char *file, uid_t uid, gid_t gid)
{
  vcb vb = getvcb();
  
  if(validate_path(file) != 0)
    return -1; // Invalid path.
  
  file++;
  for(int i = vb.de_start; i < vb.de_start+vb.de_length; i++){
    dirent de = getdirent(i);
    if(strcmp(de.name,file)==0){
      de.userid = uid;
      de.groupid = gid;
      setdirent(i,de);
      return 0; // Success
    }
  }
  return -1; // File not found.
}
示例#8
0
文件: sosh.c 项目: gz/aos10
static int dir(int argc, char **argv) {
	int i = 0, r;
	char buf[BUF_SIZ];

	if (argc > 2) {
		printf("usage: %s [file]\n", argv[0]);
		return 1;
	}

	if (argc == 2) {
		r = stat(argv[1], &sbuf);
		if (r < 0) {
			printf("stat(%s) failed: %d\n", buf, r);
			return 0;
		}
		prstat(argv[1]);
		return 0;
	}

	while (1) {
		r = getdirent(i, buf, BUF_SIZ);
		if (r < 0) {
			printf("dirent(%d) failed: %d\n", i, r);
			break;
		} else if (!r) {
			break;
		}
#if 0
		printf("dirent(%d): \"%s\"\n", i, buf);
#endif
		r = stat(buf, &sbuf);
		if (r < 0) {
			printf("stat(%s) failed: %d\n", buf, r);
			break;
		}
		prstat(buf);
		i++;
	}
	return 0;
}
示例#9
0
/*
 * This function will truncate the file at the given offset
 * (essentially, it should shorten the file to only be offset
 * bytes long).
 */
static int vfs_truncate(const char *file, off_t offset)
{
  // First, we ensure thepath is valid.
  if(validate_path(file) != 0)
    return -1;

  file++; 
  vcb vb = getvcb();

  dirent de;
  int dirent_index = -1;

  for(int i = vb.de_start; i < vb.de_start + vb.de_length && dirent_index == -1; i++){ // Get matching dirent.
    de = getdirent(i);
    if(strcmp(de.name,file) == 0)
      dirent_index = i;
  }
/*
   3600: NOTE THAT ANY BLOCKS FREED BY THIS OPERATION SHOULD
           BE AVAILABLE FOR OTHER FILES TO USE.
*/
  return 0;
}
示例#10
0
/**
 * This function deletes the last component of the path (e.g., /a/b/c you 
 * need to remove the file 'c' from the directory /a/b).
 */
static int vfs_delete(const char *path)
{
  vcb vb = getvcb(); // Get our VCB, used to find start/end points of dirents.

  if(validate_path(path) != 0) // If the path is invalid, return an error.
    return -1;
  path++; // Increment path, getting rid of the leading /.

  // To create a file, we need to first read used dirents and search for a duplicate.
  for(int i = vb.de_start; i < vb.de_start+vb.de_length; i++){
    dirent de = getdirent(i); 
    if(strcmp(de.name, path) == 0){
      de.valid = 0;
      setdirent(i,de);
      return 0;
    }
  }
   return -EEXIST;
 
  /* 3600: NOTE THAT THE BLOCKS CORRESPONDING TO THE FILE SHOULD BE MARKED
           AS FREE, AND YOU SHOULD MAKE THEM AVAILABLE TO BE USED WITH OTHER FILES */
  // TODO: Mark blocks as free.
}
示例#11
0
DIR *opendir(char *name)
{
  struct stat statb;
  DIR *dirp;
  char c;
  char *s;
  struct _dircontents *dp;
  char nbuf[MAXPATHLEN + 1];
  int len;

  strcpy(nbuf, name);
  len = strlen (nbuf);
  s = nbuf + len;

#if 1
  if ( ((c = nbuf[strlen(nbuf) - 1]) == '\\' || c == '/') &&
       (strlen(nbuf) > 1) )
  {
    nbuf[strlen(nbuf) - 1] = 0;

    if ( nbuf[strlen(nbuf) - 1] == ':' )
      strcat(nbuf, "\\.");
  }
  else
    if ( nbuf[strlen(nbuf) - 1] == ':' )
      strcat(nbuf, ".");
#else
  if ( len && ((c = nbuf[len-1]) == '\\' || c == '/' || c == ':') )
  {
    nbuf[len++] = '.';      /* s now points to '.' */
    nbuf[len] = 0;
  }
#endif

  if (stat(nbuf, &statb) < 0 || (statb.st_mode & S_IFMT) != S_IFDIR)
    return NULL;

  if ( (dirp = malloc(sizeof(DIR))) == NULL )
    return NULL;

#if 1
  if ( nbuf[strlen(nbuf) - 1] == '.' )
    strcpy(nbuf + strlen(nbuf) - 1, "*.*");
  else
    if ( ((c = nbuf[strlen(nbuf) - 1]) == '\\' || c == '/') &&
         (strlen(nbuf) == 1) )
      strcat(nbuf, "*.*");
    else
      strcat(nbuf, "\\*.*");
#else
  if ( *s == 0 )
    *s++ = '\\';

  strcpy (s, "*.*");
#endif

  dirp -> dd_loc = 0;
  dirp -> dd_contents = dirp -> dd_cp = NULL;

  if ((s = getdirent(nbuf)) == NULL)
    return dirp;

  do
  {
    if (((dp = malloc(sizeof(struct _dircontents))) == NULL) ||
        ((dp -> _d_entry = malloc(strlen(s) + 1)) == NULL)      )
    {
      if (dp)
        free(dp);
      free_dircontents(dirp -> dd_contents);

      return NULL;
    }

    if (dirp -> dd_contents)
    {
      dirp -> dd_cp -> _d_next = dp;
      dirp -> dd_cp = dirp -> dd_cp -> _d_next;
    }
    else
      dirp -> dd_contents = dirp -> dd_cp = dp;

    strcpy(dp -> _d_entry, s);
    dp -> _d_next = NULL;

    dp -> _d_size = find.cbFile;
    dp -> _d_mode = find.attrFile;
    dp -> _d_time = *(unsigned *) &(find.ftimeLastWrite);
    dp -> _d_date = *(unsigned *) &(find.fdateLastWrite);
  }
  while ((s = getdirent(NULL)) != NULL);

  dirp -> dd_cp = dirp -> dd_contents;

  return dirp;
}
示例#12
0
文件: main.c 项目: michft/sparkfun
int main(int argc, char *argv[])
#endif
{
    u8 sta = 0, cmd;
    int i;

#ifndef __AVR__
    if (argc > 3 || argc < 2) {
        printf("Usage: (sudo) testfat rawdevice  e.g. fat32 /dev/sdb \r\n");
        return 1;
    }
    //    fcntl(0, F_SETFL, fcntl(0, F_GETFL) | O_NONBLOCK);
    if (initsec(argv[1]))
        return -1;
#endif

    hwinit();

    printf("\nFAT32 Test\n");
    i = sdhcinit();
    printf("init %d\n", i);
    if (!i) {
        printf( "%lu sects\n", sdnumsectors );
        i = mount(0);
        printf("Mount: %d\n", i);
        if (!i)
            seekfile(0, 0);
#if 1                           // show what is read
        else
            for (i = 0; i < 1; i++) {
                readsec(i);
                dumpsect();
            }
#endif
    }
    if (i)
        printf("Not Ready\n");

    for (;;) {
        cmd = tzgetchar();
        if (cmd >= 'a')
            cmd -= 32;
        switch (cmd) {
#ifdef __AVR__
        case '0':
        case '1':
        case '2':
        case '3':
        case '4':
        case '5':
        case '6':
        case '7':
        case '8':
        case '9':
            //            while (!tzkbhit()) {
                ADMUX = 0xe0 + cmd - '0';
                ADCSRA = 0xc7;
                while (ADCSRA & 0x40);
                printf("%c %04x\n", cmd, ADC);
                //            }
            break;
#endif
        case 3:
        case 26:
        case 'Q':
            exit(0);
        case 'Y':
            {
                u16 u;
                u = getdirent((u8 *) "");
                printf("%u entries in dir\n", u);
            }
            break;
        case 'I':
            sta = sdhcinit();
            printf("init %d\n", sta);
            if (sta)
                continue;
            printf( "%lu sects\n", sdnumsectors );
            sta = cardinfo(0);
            printf("inf %d\n", sta);
            if (sta)
                continue;
            for (sta = 0; sta < 18; sta++)
                printf("%02X", filesectbuf[sta]);
            printf(" ");
            for (sta = 0; sta < 18; sta++)
                printf("%c", dochar(filesectbuf[sta]));
            printf("\n");
            sta = cardinfo(1);
            printf("inf %d\n", sta);
            if (sta)
                continue;
            for (sta = 0; sta < 18; sta++)
                printf("%02X", filesectbuf[sta]);
            printf(" ");
            for (sta = 0; sta < 18; sta++)
                printf("%c", dochar(filesectbuf[sta]));
            printf("\n");
            break;
        case 'M':
            i = mount(0);
            if (!i)
                printf("Mounted\n");
            else
                printf("Error\n");
            break;
        case 'O':
            printf("Open:\n");
            i = getfname();
            if (i < 0) {
                printf("bad fname\n");
                break;
            }
            i = getdirent(filename);
            if (i == 2)
                printf("Entered Dir\n");
            else if (!i)
                printf("Opened\n");
            else
                printf("Not Found\n");
            break;
        case 'C':
            printf("Create:\n");
            i = getfname();
            if (i < 0) {
                printf("bad fname\n");
                break;
            }
            if (i == 1) {
                printf("Directory:\n");
                i = getfname();
                if (i) {
                    printf("bad fname\n");
                    break;
                }
                i = 0x10;       // directory attribute
            }
            i = newdirent(filename, i);
            if (!i)
                printf("Created\n");
            else if (i == 2)
                printf("Exists\n");
            else
                printf("Error\n");
            break;
        case 'N':
            i = newdirent(NULL, 0);
            if (!i)
                printf("Created Ser Log\n");
            else
                printf("Error\n");
            break;
        case 'L':
            resettodir();
            seekfile(0, 0);
            for (i = 0; i < 16; i++) {
                if (!filesectbuf[i << 5])
                    break;
                if (0xe5 == filesectbuf[i << 5]) {
                    printf("(del)\n");
                    continue;
                }
                if (0xf == filesectbuf[(i << 5) + 11]) {
                    printf("(lfn)\n");
                    continue;
                }
                printf("%8.8s.%3.3s %c\n", &filesectbuf[i << 5], &filesectbuf[(i << 5) + 8],
                  filesectbuf[(i << 5) + 11] & 0x10 ? '/' : ' ');
                if (i == 15) {
                    i = readnextsect();
                    if (i != 512)
                        break;
                    i = -1;
                }
            }
            break;
        case 'W':
            printf("Write: ^c|^z to exit\n");
            for (;;) {
                char cx;
                cx = tzgetchar();
                if (cx == 3 || cx == 26)
                    break;
                writebyte(cx);
                printf("%c", cx);
            }
            printf("\nWritten ");
            flushbuf();
            printf("Flushed ");
            syncdirent(0);
            printf("DSynced\n");
            break;
        case 'F':
            flushbuf();
            printf("Flushed\n");
            break;
        case 'E':
            syncdirent(0);
            printf("dirsynced\n");
            break;
        case 'P':
            syncdirent(1);
            printf("size pushed\n");
            break;
        case 'Z':
            zaphint();
            printf("hint zapped\n");
            break;
        case 'T':
            truncatefile();
            printf("Trunc-ed\n");
            break;
        case 'D':
            i = deletefile();
            if (i == 1)
                printf("no rmdir\n");
            else if (!i)
                printf("Deleted\n");
            else
                printf("Error\n");
            break;
            // will go away when seek is filled in
        case 'A':
            seekfile(0, 2);
            printf("At EOF\n");
            break;
        case 'S':
            {
                u32 x = 0;
                u8 y = 1;
                seekfile(x, y);
                printf("Rewound\n");
            }
            break;
        case 'R':
        case 'V':
        case 'X':
            sta = 0;
            while (!tzkbhit()) {
                i = readbyte();
                if (i < 0) {
                    printf("\n=EOF=\n");
                    break;
                }
                switch (cmd) {
                case 'R':
                    printf("%c", i);
                    break;
                case 'V':
                    printf("%c", dochar(i));
                    break;
                case 'X':
                    if (!(sta++ & 15))
                        printf("\n");
                    printf("%02X", i);
                    break;
                }
            }
            break;
        case 'U':
            resetrootdir();
            seekfile(0, 0);     // for list
            printf("At rootdir\n");
            break;
        case 'G':
            resettodir();
            seekfile(0, 0);     // for list
            printf("At curdir\n");
            break;

        default:
            // help message
            {
                char *c = mainmenu;
                while (pgm_read_byte(c))
                    putchar(pgm_read_byte(c++));
            }
            break;
        }
    }
}
示例#13
0
文件: getcwd.c 项目: Theldus/nanvix
/*
 * Gets the pathname of the current working directory.
 */
char *getcwd(char *buf, size_t size)
{
	ino_t cino;            /* Current dir inode number.  */
	dev_t cdev;            /* Current dir inode pointer. */
	ino_t rino;            /* Root dir inode number.     */
	dev_t rdev;            /* Root dir device number.    */
	DIR *dirp;             /* Working directory.         */
	struct stat st;        /* Working directory stat.    */
	struct dirent *dp;     /* Working directory entry.   */
	char curdir[PATH_MAX]; /* Current directory.         */

	/* Invalid size. */
	if (size == 0)
	{
		errno = EINVAL;
		return (NULL);
	}

	buf[0] = '\0';
	strcpy(curdir, ".");

	/*
	 * Get root inode and device numbers
	 * so we know where we should stop.
	 */
	if (stat("/", &st) < 0)
		goto error0;
	
	rino = st.st_ino;
	rdev = st.st_dev;
	
	/* Get current working directory pathname. */
	while (1)
	{		
		/*
		 * Remember current directory inode
		 * and device number to get it name later.
		 */
		if (stat(curdir, &st) < 0)
			goto error0;
		
		cino = st.st_ino;
		cdev = st.st_dev;
		
		/* Done. */
		if ((cino == rino) && (cdev == rdev))
			break;
		
		/* Open upper directory. */
		strcat(curdir, "/..");
		if ((dirp = opendir(curdir)) == NULL)
			goto error0;
			
		/* Get lower directory name. */
		dp = getdirent(dirp, cino);
		if (prepend(buf, dp->d_name, size))
			goto error1;
			
		closedir(dirp);
	}
	
	/*
	 * Special case when current working directory
	 * is the root directory.
	 */
	if (buf[0] == '\0')
	{	
		/* Start from root*/
		if (prepend(buf, "", size))
			goto error0;
	}
	
	return (buf);

error1:
	closedir(dirp);
error0:
	return (NULL);
}
示例#14
0
文件: dirent.c 项目: undwad/websrv
DIR *opendirx(char *name, char *pattern)
{
    struct stat statb;
    DIR *dirp;
    char c;
    char *s;
    struct _dircontents *dp;
    int len;
    int unc;
    char path[OFS_MAXPATHNAME];
    register char *ip, *op;

    for (ip = name, op = path;; op++, ip++) {
        *op = *ip;
        if (*ip == '\0') {
            break;
        }
    }
    len = ip - name;
    if (len > 0) {
        unc = ((path[0] == '\\' || path[0] == '/') &&
               (path[1] == '\\' || path[1] == '/'));
        c = path[len - 1];
        if (unc) {
            if (c != '\\' && c != '/') {
                path[len] = '/';
                len++;
                path[len] = '\0';
            }
        } else {
            if ((c == '\\' || c == '/') && (len > 1)) {
                len--;
                path[len] = '\0';

                if (path[len - 1] == ':') {
                    path[len] = '/';
                    len++;
                    path[len] = '.';
                    len++;
                    path[len] = '\0';
                }
            } else if (c == ':') {
                path[len] = '.';
                len++;
                path[len] = '\0';
            }
        }
    } else {
        unc = 0;
        path[0] = '.';
        path[1] = '\0';
        len = 1;
    }

    if (stat(path, &statb) < 0 || (statb.st_mode & S_IFMT) != S_IFDIR) {
        return NULL;
    }
    dirp = malloc(sizeof(DIR));
    if (dirp == NULL) {
        return dirp;
    }
    c = path[len - 1];
    if (c == '.') {
        if (len == 1) {
            len--;
        } else {
            c = path[len - 2];
            if (c == '\\' || c == ':') {
                len--;
            } else {
                path[len] = '/';
                len++;
            }
        }
    } else if (!unc && ((len != 1) || (c != '\\' && c != '/'))) {
        path[len] = '/';
        len++;
    }
    strcpy(path + len, pattern);

    dirp->dd_loc = 0;
    dirp->dd_contents = dirp->dd_cp = NULL;

    if ((s = getdirent(path)) == NULL) {
        return dirp;
    }
    do {
        if (((dp = malloc(sizeof(struct _dircontents))) == NULL) ||
                ((dp->_d_entry = malloc(strlen(s) + 1)) == NULL)) {
            if (dp)
                free(dp);
            free_dircontents(dirp->dd_contents);

            return NULL;
        }
        if (dirp->dd_contents)
            dirp->dd_cp = dirp->dd_cp->_d_next = dp;
        else
            dirp->dd_contents = dirp->dd_cp = dp;

        strcpy(dp->_d_entry, s);
        dp->_d_next = NULL;

    }
    while ((s = getdirent(NULL)) != NULL);

    dirp->dd_cp = dirp->dd_contents;
    return dirp;
}
示例#15
0
文件: fatdir.c 项目: TijmenW/FreeDOS
/* Description.
 *  Read next consequitive directory entry, pointed by fnp.
 *  If some error occures the other critical
 *  fields aren't changed, except those used for caching.
 *  The fnp->f_diroff always corresponds to the directory entry
 *  which has been read.
 * Return value.
 *  1              - all OK, directory entry having been read is not empty.
 *  0              - Directory entry is empty.
 *  DE_SEEK        - Attempt to read beyound the end of the directory.
 *  DE_BLKINVLD    - Invalid block.
 * Note. Empty directory entries always resides at the end of the directory. */
COUNT dir_read(REG f_node_ptr fnp)
{
  struct buffer FAR *bp;
  REG UWORD secsize = fnp->f_dpb->dpb_secsize;
  ULONG new_diroff = fnp->f_diroff;

  /* Directories need to point to their current offset, not for   */
  /* next op. Therefore, if it is anything other than the first   */
  /* directory entry, we will update the offset on entry rather   */
  /* than wait until exit. If it was new, clear the special new   */
  /* flag.                                                        */
  if (!fnp->f_flags.f_dnew)
    new_diroff += DIRENT_SIZE;

  /* Determine if we hit the end of the directory. If we have,    */
  /* bump the offset back to the end and exit. If not, fill the   */
  /* dirent portion of the fnode, clear the f_dmod bit and leave, */
  /* but only for root directories                                */

  if (fnp->f_flags.f_droot)
  {
    if (new_diroff >= DIRENT_SIZE * (ULONG)fnp->f_dpb->dpb_dirents)
      return DE_SEEK;

    bp = getblock((ULONG) (new_diroff / secsize
                           + fnp->f_dpb->dpb_dirstrt),
                  fnp->f_dpb->dpb_unit);
#ifdef DISPLAY_GETBLOCK
    printf("DIR (dir_read)\n");
#endif
  }
  else
  {
    /* Do a "seek" to the directory position        */
    fnp->f_offset = new_diroff;

    /* Search through the FAT to find the block     */
    /* that this entry is in.                       */
#ifdef DISPLAY_GETBLOCK
    printf("dir_read: ");
#endif
    if (map_cluster(fnp, XFR_READ) != SUCCESS)
      return DE_SEEK;

    /* Compute the block within the cluster and the */
    /* offset within the block.                     */
    fnp->f_sector = (fnp->f_offset / secsize) & fnp->f_dpb->dpb_clsmask;
    fnp->f_boff = fnp->f_offset % secsize;

    /* Get the block we need from cache             */
    bp = getblock(clus2phys(fnp->f_cluster, fnp->f_dpb) + fnp->f_sector,
                  fnp->f_dpb->dpb_unit);
#ifdef DISPLAY_GETBLOCK
    printf("DIR (dir_read)\n");
#endif
  }

  /* Now that we have the block for our entry, get the    */
  /* directory entry.                                     */
  if (bp == NULL)
    return DE_BLKINVLD;

  bp->b_flag &= ~(BFR_DATA | BFR_FAT);
  bp->b_flag |= BFR_DIR | BFR_VALID;

  getdirent((BYTE FAR *) & bp->b_buffer[((UWORD)new_diroff) % fnp->f_dpb->dpb_secsize],
              (struct dirent FAR *)&fnp->f_dir);

  /* Update the fnode's directory info                    */
  fnp->f_flags.f_dmod = FALSE;
  fnp->f_flags.f_dnew = FALSE;
  fnp->f_diroff = new_diroff;
    
  /* and for efficiency, stop when we hit the first       */
  /* unused entry.                                        */
  /* either returns 1 or 0                                */
  return (fnp->f_dir.dir_name[0] != '\0');
}
示例#16
0
文件: dirread.c 项目: 00001/plan9port
static int
mygetdents(int fd, struct dirent *buf, int n)
{
	return getdirent(fd, (void*)buf, n);
}
示例#17
0
文件: fatdir.c 项目: TijmenW/FreeDOS
/* Description.
 *  Read next consequitive directory entry, pointed by fnp.
 *  If some error occures the other critical
 *  fields aren't changed, except those used for caching.
 *  The fnp->f_diroff always corresponds to the directory entry
 *  which has been read.
 * Return value.
 *  1              - all OK, directory entry having been read is not empty.
 *  0              - Directory entry is empty.
 *  DE_SEEK        - Attempt to read beyound the end of the directory.
 *  DE_BLKINVLD    - Invalid block.
 * Note. Empty directory entries always resides at the end of the directory. */
COUNT dir_read(REG f_node_ptr fnp)
{
  struct buffer FAR *bp;
  REG UWORD secsize = fnp->f_dpb->dpb_secsize;

  /* can't have more than 65535 directory entries */
  if (fnp->f_diroff >= 65535U)
  {
      FDirDbgPrintf(("dir_read: exceed dir entry count\n"));
      return DE_SEEK;
  }

  /* Determine if we hit the end of the directory. If we have,    */
  /* bump the offset back to the end and exit. If not, fill the   */
  /* dirent portion of the fnode, clear the f_dmod bit and leave, */
  /* but only for root directories                                */

  if (fnp->f_dirstart == 0)
  {
    if (fnp->f_diroff >= fnp->f_dpb->dpb_dirents)
    {
      FDirDbgPrintf(("dir_read: end of dir\n"));
      return DE_SEEK;
    }

    bp = getblock(fnp->f_diroff / (secsize / DIRENT_SIZE)
                           + fnp->f_dpb->dpb_dirstrt, fnp->f_dpb->dpb_unit);
#ifdef DISPLAY_GETBLOCK
    printf("DIR (dir_read)\n");
#endif
  }
  else
  {
    /* Do a "seek" to the directory position        */
    fnp->f_offset = fnp->f_diroff * (ULONG)DIRENT_SIZE;

    /* Search through the FAT to find the block     */
    /* that this entry is in.                       */
#ifdef DISPLAY_GETBLOCK
    printf("dir_read: ");
#endif
    if (map_cluster(fnp, XFR_READ) != SUCCESS)
    {
      DebugPrintf(("dir_read: map_cluster failed\n"));
      return DE_SEEK;
    }

    bp = getblock_from_off(fnp, secsize);
#ifdef DISPLAY_GETBLOCK
    printf("DIR (dir_read)\n");
#endif
  }

  /* Now that we have the block for our entry, get the    */
  /* directory entry.                                     */
  if (bp == NULL)
  {
    FDirDbgPrintf(("dir_read: invalid block\n"));
    return DE_BLKINVLD;
  }

  bp->b_flag &= ~(BFR_DATA | BFR_FAT);
  bp->b_flag |= BFR_DIR | BFR_VALID;

  getdirent((BYTE FAR *) & bp->
            b_buffer[(fnp->f_diroff * DIRENT_SIZE) % fnp->f_dpb->dpb_secsize],
            &fnp->f_dir);

  swap_deleted(fnp->f_dir.dir_name);

  /* Update the fnode's directory info                    */
  fnp->f_flags &= ~F_DMOD;

  /* and for efficiency, stop when we hit the first       */
  /* unused entry.                                        */
  /* either returns 1 or 0                                */
  FDirDbgPrintf(("dir_read: dir_name is %11s\n", fnp->f_dir.dir_name));
  return (fnp->f_dir.dir_name[0] != '\0');
}
示例#18
0
/* 
 *
 * Given an absolute path to a file/directory (i.e., /foo ---all
 * paths will start with the root directory of the CS3600 file
 * system, "/"), you need to return the file attributes that is
 * similar stat system call.
 *
 * HINT: You must implement stbuf->stmode, stbuf->st_size, and
 * stbuf->st_blocks correctly.
 *
 */
static int vfs_getattr(const char *path, struct stat *stbuf) {
  fprintf(stderr, "vfs_getattr called\n");
  // Do not mess with this code 
  stbuf->st_nlink = 1; // hard links
  stbuf->st_rdev  = 0;
  stbuf->st_blksize = BLOCKSIZE;

  /* 3600: YOU MUST UNCOMMENT BELOW AND IMPLEMENT THIS CORRECTLY */
  
  /*
  if (The path represents the root directory)
    stbuf->st_mode  = 0777 | S_IFDIR;
  else 
    stbuf->st_mode  = <<file mode>> | S_IFREG;

  stbuf->st_uid     = // file uid
  stbuf->st_gid     = // file gid
  stbuf->st_atime   = // access time 
  stbuf->st_mtime   = // modify time
  stbuf->st_ctime   = // create time
  stbuf->st_size    = // file size
  stbuf->st_blocks  = // file size in blocks
    */

  if(strcmp(path, "/") == 0){
    vcb vb = getvcb();
    
    struct tm * tm1;
    struct tm * tm2;
    struct tm * tm3;
    tm1 = localtime(&((vb.access_time).tv_sec));
    tm2 = localtime(&((vb.modify_time).tv_sec));
    tm3 = localtime(&((vb.create_time).tv_sec));
    
    stbuf->st_mode = 0777 | S_IFDIR;
    
    stbuf->st_uid = vb.userid;
    stbuf->st_gid = vb.groupid;
    stbuf->st_atime = mktime(tm1);
    stbuf->st_mtime = mktime(tm2);
    stbuf->st_ctime = mktime(tm3);
    stbuf->st_size = BLOCKSIZE;
    stbuf->st_blocks = 1;
    return 0;
  }
  else{
    if(validate_path(path) != 0) // If the path is valid, we can proceed.
      return -1;
    path++;
    // char *filename = (char *) malloc(512 - (3 * sizeof(timespec)) - 24);
    for(int i = 1; i < 101; i++){
      dirent de = getdirent(i);
      if(de.valid == 1){
	if(strcmp(de.name, path) == 0){
	  struct tm * tm1;
	  struct tm * tm2;
	  struct tm * tm3;
	  tm1 = localtime(&((de.access_time).tv_sec));
	  tm2 = localtime(&((de.modify_time).tv_sec));
	  tm3 = localtime(&((de.create_time).tv_sec));
	  
	  stbuf->st_mode = de.mode | S_IFREG;
	  
	  stbuf->st_uid = de.userid;
	  stbuf->st_gid = de.groupid;
	  stbuf->st_atime = mktime(tm1);
	  stbuf->st_mtime = mktime(tm2);
	  stbuf->st_ctime = mktime(tm3);
	  stbuf->st_size = de.size;
	  stbuf->st_blocks = (de.size / BLOCKSIZE);
	  return 0;
	}// End if
      }// End if
    }// End for loop
    return -ENOENT;
  }
}
示例#19
0
文件: fatdir.c 项目: TijmenW/FreeDOS
COUNT dir_read(REG struct f_node FAR * fnp)
{
  REG i;
  REG j;
  struct buffer FAR *bp;

  /* Directories need to point to their current offset, not for   */
  /* next op. Therefore, if it is anything other than the first   */
  /* directory entry, we will update the offset on entry rather   */
  /* than wait until exit. If it was new, clear the special new   */
  /* flag.                                                        */
  if (fnp->f_flags.f_dnew)
    fnp->f_flags.f_dnew = FALSE;
  else
    fnp->f_diroff += DIRENT_SIZE;

  /* Determine if we hit the end of the directory. If we have,    */
  /* bump the offset back to the end and exit. If not, fill the   */
  /* dirent portion of the fnode, clear the f_dmod bit and leave, */
  /* but only for root directories                                */
  if (fnp->f_flags.f_droot && fnp->f_diroff >= fnp->f_dsize)
  {
    fnp->f_diroff -= DIRENT_SIZE;
    return 0;
  }
  else
  {
    if (fnp->f_flags.f_droot)
    {
      if ((fnp->f_diroff / fnp->f_dpb->dpb_secsize
           + fnp->f_dpb->dpb_dirstrt)
          >= fnp->f_dpb->dpb_data)
      {
        fnp->f_flags.f_dfull = TRUE;
        return 0;
      }

      bp = getblock((ULONG) (fnp->f_diroff / fnp->f_dpb->dpb_secsize
                             + fnp->f_dpb->dpb_dirstrt),
                    fnp->f_dpb->dpb_unit);
      bp->b_flag &= ~(BFR_DATA | BFR_FAT);
      bp->b_flag |= BFR_DIR;
#ifdef DISPLAY_GETBLOCK
      printf("DIR (dir_read)\n");
#endif
    }
    else
    {
      REG UWORD secsize = fnp->f_dpb->dpb_secsize;

      /* Do a "seek" to the directory position        */
      fnp->f_offset = fnp->f_diroff;

      /* Search through the FAT to find the block     */
      /* that this entry is in.                       */
#ifdef DISPLAY_GETBLOCK
      printf("dir_read: ");
#endif
      if (map_cluster(fnp, XFR_READ) != SUCCESS)
      {
        fnp->f_flags.f_dfull = TRUE;
        return 0;
      }

      /* If the returned cluster is FREE, return zero */
      /* bytes read.                                  */
      if (fnp->f_cluster == FREE)
        return 0;

      /* If the returned cluster is LAST_CLUSTER or   */
      /* LONG_LAST_CLUSTER, return zero bytes read    */
      /* and set the directory as full.               */

      if (last_link(fnp))
      {
        fnp->f_diroff -= DIRENT_SIZE;
        fnp->f_flags.f_dfull = TRUE;
        return 0;
      }

      /* Compute the block within the cluster and the */
      /* offset within the block.                     */
      fnp->f_sector = (fnp->f_offset / secsize) & fnp->f_dpb->dpb_clsmask;
      fnp->f_boff = fnp->f_offset % secsize;

      /* Get the block we need from cache             */
      bp = getblock((ULONG) clus2phys(fnp->f_cluster,
                                      (fnp->f_dpb->dpb_clsmask + 1),
                                      fnp->f_dpb->dpb_data)
                    + fnp->f_sector,
                    fnp->f_dpb->dpb_unit);
      bp->b_flag &= ~(BFR_DATA | BFR_FAT);
      bp->b_flag |= BFR_DIR;
#ifdef DISPLAY_GETBLOCK
      printf("DIR (dir_read)\n");
#endif
    }

    /* Now that we have the block for our entry, get the    */
    /* directory entry.                                     */
    if (bp != NULL)
      getdirent((BYTE FAR *) & bp->b_buffer[fnp->f_diroff % fnp->f_dpb->dpb_secsize],
                (struct dirent FAR *)&fnp->f_dir);
    else
    {
      fnp->f_flags.f_dfull = TRUE;
      return 0;
    }

    /* Update the fnode's directory info                    */
    fnp->f_flags.f_dfull = FALSE;
    fnp->f_flags.f_dmod = FALSE;

    /* and for efficiency, stop when we hit the first       */
    /* unused entry.                                        */
    if (fnp->f_dir.dir_name[0] == '\0')
      return 0;
    else
      return DIRENT_SIZE;
  }
}
示例#20
0
/*
 * The function vfs_write will attempt to write 'size' bytes from 
 * memory address 'buf' into a file specified by an absolute 'path'.
 * It should do so starting at the specified offset 'offset'.  If
 * offset is beyond the current size of the file, you should pad the
 * file with 0s until you reach the appropriate length.
 *
 * You should return the number of bytes written.
 *
 * HINT: Ignore 'fi'
 */
static int vfs_write(const char *path, const char *buf, size_t size,
                     off_t offset, struct fuse_file_info *fi)
{
  // First, we ensure thepath is valid.
  if(validate_path(path) != 0)
    return -1;
  
  vcb vb = getvcb();
  path++;               // Get rid of leading slash in path
  int byteswritten = 0; // Amount of bytes we've written to disk from buffer
  int num_pad = 0;      // Amount of 0s we need to pad between EOF and offset
  int write_offset = 0; // variable to hold an offset for vfs_write.

  dirent de;
  int found_dirent = 0;
  int dirent_index = -1;
  
  for(int i = vb.de_start; i < vb.de_start + vb.de_length, found_dirent == 0; i++){
    de = getdirent(i);
    if(de.valid == 1)
      if(strcmp(path,de.name)==0){
        found_dirent = 1;
        dirent_index = i;
      }
  }

  if(found_dirent){	// Begin writing to disk.
    if(offset > de.size){ // Check for padding.
      num_pad = (offset - de.size); // Number of 0's to add.
    }
    if((size + offset) > de.size){
      de.size = (size + offset);    // Set the new size of the file.
    }
    
    // Update access modify times of file
    struct timespec newtime;
    clock_gettime(CLOCK_REALTIME, &newtime);
    
    de.access_time = newtime;
    de.modify_time = newtime;
    
    /* Next, since we have our dirent to write to, we must:
       - Check to see if the dirent has a FAT entry allocated.
       - Attempt to allocate one if necessary.
       x If the dirent has at least one FAT entry, begin writing:
       x Begin traversing offset, decrementing it as necessary until offset == 0.
       x Attempt to create new FAT entries if necessary.
       x Begin padding the file with zeros, if necessary, decrementing num_pad until it == 0.
       x Attempt to create new FAT entries if necessary.
       x Begin appending buf to file, decrementing size while doing so.
       x Attempt to create new FAT entries if necessary.
       x If, in any of the above cases, creating a new FAT entry fails, return -ENOSPC.
    */    
   
    

 
    // Check if found dirent has allocated FAT. If not, attempt to allocate one.
    if((int) de.first_block == -1){
      char block[BLOCKSIZE];
      int found_free = 0;
      
      for(int i = vb.fat_start;(i < vb.fat_start + ((int) (vb.fat_length/128))) && found_free == 0; i++){ // For each fat block...
	int block_index = (i-vb.fat_start)*128;
	
	memset(block,0,BLOCKSIZE); // Reset block.
	dread(i, block); // Read FAT Block into block.
	
	for(int j = 0; j < 128 && found_free == 0; j++){
	  fatent fe = getfe( block_index + j);
	  if(fe.used == 0){
	    de.first_block = block_index + j;
	    fe.used = 1;
	    fe.eof = 1;
	    fe.next = 0;
	    found_free = 1;
	  }
	}
      }
      if(found_free != 1){
        return -ENOSPC;
      }
    }
    
    
    
    fatent fe = getfe(de.first_block);
    
    char block[BLOCKSIZE];
    memset(block,0,BLOCKSIZE);
      
    // Expand file and pad 0's, if necessary.
    if(num_pad > 0){
      
      int eof_fat_idx = get_eof_fe(&fe) + vb.db_start;// find index of eof 
      dread(eof_fat_idx,block);
	
      int eof_data_idx;
	
      for(int i = 0; block[i] != EOF; i++)
        eof_data_idx++;

      eof_data_idx++; // Increment counter so block[eof_data_idx] == EOF.
	
	while(num_pad > 0){
          if(eof_data_idx < BLOCKSIZE){
	    memset(&block[eof_data_idx],0,1);
	    eof_data_idx++;
	    num_pad--;
	    if(num_pad == 0){
		dwrite(eof_data_idx,block);
		memset(block,0,BLOCKSIZE);
	    }
          } 
	  else{
	    dwrite(eof_fat_idx,block);
	    memset(block,0,BLOCKSIZE);
	    if(allocate_fat(&fe) != 0){
		return -ENOSPC;
	    }
	    eof_fat_idx = get_eof_fe(&fe) + vb.db_start;
	    eof_data_idx = 0;
	  }
	}
    }    
        
    // Now, we need to start writing size chars from buf into the file, starting at offset
    
    // Start by finding where offset is in the datablock.
    int offset_block = (int)(offset/512);
    int offset_into_block = offset % 512;
    int buffer_offset = 0;
    
    // Read in offset block, write at offset into block
    memset(block,0,BLOCKSIZE);
    dread(offset_block + vb.db_start, block);
    
    // Memcpy the rest of the block, or size bytes, whichever bounds first
    while(offset_into_block < BLOCKSIZE && size > 0){
      memcpy(&block[offset_into_block], buf, 1);
      size--;
      buf++;
      buffer_offset++;
      offset_into_block++;
      byteswritten++;
    }

    // Write block rest of block
    dwrite(offset_block + vb.db_start, block);
    
    // While there remains bytes to be written...
    while(size > 0){
      if(offset_into_block == BLOCKSIZE){
	// Write block
	dwrite(offset_block + vb.db_start, block);
	
	// Allocate new fat/data block
	if(allocate_fat(&fe) != 0){
	  return -ENOSPC;
	}
	
	// reset offset_into_block
	offset_into_block = 0;
	offset_block = get_eof_fe(&fe);
        memset(block,0,BLOCKSIZE);
      }
      
      memcpy(&block[offset_into_block], &buf[buffer_offset], 1);
      
      size--;
      buffer_offset++;
      offset_into_block++;
      byteswritten++;
    }

    // Write the rest of size bytes
    dwrite(offset_block + vb.db_start, block);
    setdirent(dirent_index,de);
    return byteswritten;
  }
  else{
    // No free dirents found
    return -1;
  }
  
}