Ejemplo n.º 1
0
int main(void) {
   put_str("I am kernel\n");
   init_all();
/********  测试代码  ********/
   printf("/dir1 content before delete /dir1/subdir1:\n");
   struct dir* dir = sys_opendir("/dir1/");
   char* type = NULL;
   struct dir_entry* dir_e = NULL;
   while((dir_e = sys_readdir(dir))) { 
      if (dir_e->f_type == FT_REGULAR) {
	 type = "regular";
      } else {
	 type = "directory";
      }
      printf("      %s   %s\n", type, dir_e->filename);
   }
   printf("try to delete nonempty directory /dir1/subdir1\n");
   if (sys_rmdir("/dir1/subdir1") == -1) {
      printf("sys_rmdir: /dir1/subdir1 delete fail!\n");
   }

   printf("try to delete /dir1/subdir1/file2\n");
   if (sys_rmdir("/dir1/subdir1/file2") == -1) {
      printf("sys_rmdir: /dir1/subdir1/file2 delete fail!\n");
   } 
   if (sys_unlink("/dir1/subdir1/file2") == 0 ) {
      printf("sys_unlink: /dir1/subdir1/file2 delete done\n");
   }
   
   printf("try to delete directory /dir1/subdir1 again\n");
   if (sys_rmdir("/dir1/subdir1") == 0) {
      printf("/dir1/subdir1 delete done!\n");
   }

   printf("/dir1 content after delete /dir1/subdir1:\n");
   sys_rewinddir(dir);
   while((dir_e = sys_readdir(dir))) { 
      if (dir_e->f_type == FT_REGULAR) {
	 type = "regular";
      } else {
	 type = "directory";
      }
      printf("      %s   %s\n", type, dir_e->filename);
   }

/********  测试代码  ********/
   while(1);
   return 0;
}
Ejemplo n.º 2
0
/*
 * get the name of the newest ticket cache for the uid user.
 * pam_krb5 defines a non default ticket cache for each user
 */
static
char * get_ticket_cache( uid_t uid )
{
  char *ticket_file = NULL;
  SMB_STRUCT_DIR *tcdir;                  /* directory where ticket caches are stored */
  SMB_STRUCT_DIRENT *dirent;   /* directory entry */
  char *filename = NULL;       /* holds file names on the tmp directory */
  SMB_STRUCT_STAT buf;        
  char user_cache_prefix[CC_MAX_FILE_LEN];
  char file_path[CC_MAX_FILE_PATH_LEN];
  time_t t = 0;

  snprintf(user_cache_prefix, CC_MAX_FILE_LEN, "%s%d", CC_PREFIX, uid );
  tcdir = sys_opendir( TICKET_CC_DIR );
  if ( tcdir == NULL ) 
    return NULL; 
  
  while ( (dirent = sys_readdir( tcdir ) ) ) 
  { 
    filename = dirent->d_name;
    snprintf(file_path, CC_MAX_FILE_PATH_LEN,"%s/%s", TICKET_CC_DIR, filename); 
    if (sys_stat(file_path, &buf) == 0 ) 
    {
      if ( ( buf.st_uid == uid ) && ( S_ISREG(buf.st_mode) ) ) 
      {
        /*
         * check the user id of the file to prevent denial of
         * service attacks by creating fake ticket caches for the 
         * user
         */
        if ( strstr( filename, user_cache_prefix ) ) 
        {
          if ( buf.st_mtime > t ) 
          { 
            /*
             * a newer ticket cache found 
             */
            free(ticket_file);
            ticket_file=SMB_STRDUP(file_path);
            t = buf.st_mtime;
          }
        }
      }
    }
  }

  sys_closedir(tcdir);

  if ( ticket_file == NULL )
  {
    /* no ticket cache found */
    fprintf(stderr, "ERROR: No ticket cache found for userid=%d\n", uid);
    return NULL;
  }

  return ticket_file;
}
Ejemplo n.º 3
0
SMB_STRUCT_DIRENT *vfswrap_readdir(vfs_handle_struct *handle, connection_struct *conn, SMB_STRUCT_DIR *dirp)
{
	SMB_STRUCT_DIRENT *result;

	START_PROFILE(syscall_readdir);
	result = sys_readdir(dirp);
	END_PROFILE(syscall_readdir);
	return result;
}
Ejemplo n.º 4
0
int
prociter(int (*proch)(pid_t pid, pid_t ppid, char *tmpname, void *data),
         void *data)
{
    char *name = NULL;
    DIR *d = NULL;
    struct dirent *de = NULL;
    struct dirent scratch[2] = {
        {
            0,
        },
    };
    pid_t pid = -1;
    pid_t ppid = -1;
    int ret = 0;

    d = sys_opendir(PROC);
    if (!d)
        return -1;

    for (;;) {
        errno = 0;
        de = sys_readdir(d, scratch);
        if (!de || errno != 0)
            break;

        if (gf_string2int(de->d_name, &pid) != -1 && pid >= 0) {
            ppid = pidinfo(pid, &name);
            switch (ppid) {
                case -1:
                    continue;
                case -2:
                    break;
            }
            ret = proch(pid, ppid, name, data);
            GF_FREE(name);
            if (ret)
                break;
        }
    }
    sys_closedir(d);
    if (!de && errno) {
        fprintf(stderr, "failed to traverse " PROC " (%s)\n", strerror(errno));
        ret = -1;
    }

    return ret;
}
Ejemplo n.º 5
0
SMB_STRUCT_WDIRENT *wsys_readdir(DIR *dirp)
{
	static SMB_STRUCT_WDIRENT retval;
	SMB_STRUCT_DIRENT *dirval = sys_readdir(dirp);

	if(!dirval)
		return NULL;

	/*
	 * The only POSIX defined member of this struct is d_name.
	 */

	unix_to_unicode(retval.d_name,dirval->d_name,sizeof(retval.d_name));

	return &retval;
}
Ejemplo n.º 6
0
/*
 * read a directory
 */
struct dirent * readdir(void * dir)
{
    struct dir * pdir;
    struct file * fp;

    if(!dir)
        return NULL;

    pdir = (struct dir *)dir;
    if((fp = get_fp(pdir->fd)) == NULL)
        return NULL;

    if(sys_readdir(fp, &pdir->entry) == 0)
        return &pdir->entry;
    return NULL;
}
Ejemplo n.º 7
0
static int change_mode_r(const char *path, mode_t mode)
{
    int ret = 0;
    struct infinity_dirent dent;
    int fd = open(path, O_RDONLY);
    char buf[256];
    int d = 0;
    while(sys_readdir(fd, d++, &dent) == 0) {
        if(path[0] == '/' && path[1] == 0)
            sprintf(buf, "/%s", dent.d_name);
        else
            sprintf(buf, "%s/%s", path, dent.d_name);
        if(dent.d_type == 0x02)
            ret = change_mode_r(buf, mode);
        int res = sys_chmod(buf, mode);
        if(res != 0) {
            printf("chmod: can not access %s : %s\n", buf, get_errmsg(res));
            ret = res;
        }
    }
    return ret;
}
Ejemplo n.º 8
0
static void atalk_rrmdir(TALLOC_CTX *ctx, char *path)
{
	char *dpath;
	SMB_STRUCT_DIRENT *dent = 0;
	SMB_STRUCT_DIR *dir;

	if (!path) return;

	dir = sys_opendir(path);
	if (!dir) return;

	while (NULL != (dent = sys_readdir(dir))) {
		if (strcmp(dent->d_name, ".") == 0 ||
		    strcmp(dent->d_name, "..") == 0)
			continue;
		if (!(dpath = talloc_asprintf(ctx, "%s/%s", 
					      path, dent->d_name)))
			continue;
		atalk_unlink_file(dpath);
	}

	sys_closedir(dir);
}
Ejemplo n.º 9
0
static void
syscall_handler (struct intr_frame *f ) 
{
  /* VALUE */	
  int syscall_num;
  int arg[5];
  void *esp = f->esp;
  /* VALUE */
  check_address(esp);
  syscall_num = *(int *)esp;
  
  switch(syscall_num)
  {
	  case SYS_HALT:
		  halt();
		  break;
	  case SYS_EXIT:
		  get_argument(esp,arg,1);
		  exit(arg[0]);
		  break;
	  case SYS_EXEC:
		  get_argument(esp,arg,1);
		  check_address((void *)arg[0]);
		  f->eax = exec((const char *)arg[0]);
		  break;
	  case SYS_WAIT:
		  get_argument(esp,arg,1);
		  f->eax = wait(arg[0]);
		  break;
	  case SYS_CREATE:
		  get_argument(esp,arg,2);
		  check_address((void *)arg[0]);
		  f->eax = create((const char *)arg[0],(unsigned)arg[1]);
		  break;
	  case SYS_REMOVE:
		  get_argument(esp,arg,1);
		  check_address((void *)arg[0]);
		  f->eax=remove((const char *)arg[0]);
		  break;
	  case SYS_OPEN:
		  get_argument(esp,arg,1);
		  check_address((void *)arg[0]);
		  f->eax = open((const char *)arg[0]);
		  break;
	  case SYS_FILESIZE:
		  get_argument(esp,arg,1);
		  f->eax = filesize(arg[0]);
		  break;
	  case SYS_READ:
		  get_argument(esp,arg,3);
		  check_address((void *)arg[1]);
		  f->eax = read(arg[0],(void *)arg[1],(unsigned)arg[2]);
		  break;
	  case SYS_WRITE:
		  get_argument(esp,arg,3);
		  check_address((void *)arg[1]);
		  f->eax = write(arg[0],(void *)arg[1],(unsigned)arg[2]);
		  break;
	  case SYS_SEEK:
		  get_argument(esp,arg,2);
		  seek(arg[0],(unsigned)arg[1]);
		  break;
	  case SYS_TELL:
		  get_argument(esp,arg,1);
		  f->eax = tell(arg[0]);
		  break;
	  case SYS_CLOSE:
		  get_argument(esp,arg,1);
		  close(arg[0]);
		  break;
	  case SYS_ISDIR:
		  get_argument(esp,arg,1);
		  sys_isdir(arg[0]);
		  break;
	  case SYS_MKDIR:
		  get_argument(esp, arg, 1);
		  check_address((void *)arg[0]);
		  f->eax = sys_mkdir((const char *)arg[0]);
		  break;
	  case SYS_READDIR:
		  get_argument(esp, arg, 2);
		  check_address((char *)arg[1]);
		  f->eax = sys_readdir(arg[0], (char *)arg[1]);
		  break;
	  case SYS_CHDIR:
		  get_argument(esp, arg, 1);
		  check_address((void *)arg[0]);
		  f->eax = sys_chdir((const char *)arg[0]);
		  break;
  }
}
Ejemplo n.º 10
0
static void
syscall_handler (struct intr_frame *f)
{
  int syscall_number;
  ASSERT( sizeof(syscall_number) == 4 ); // assuming x86

  // The system call number is in the 32-bit word at the caller's stack pointer.
  memread_user(f->esp, &syscall_number, sizeof(syscall_number));
  _DEBUG_PRINTF ("[DEBUG] system call, number = %d!\n", syscall_number);

  // Store the esp, which is needed in the page fault handler.
  // refer to exception.c:page_fault() (see manual 4.3.3)
  thread_current()->current_esp = f->esp;

  // Dispatch w.r.t system call number
  // SYS_*** constants are defined in syscall-nr.h
  switch (syscall_number) {
  case SYS_HALT: // 0
    {
      sys_halt();
      NOT_REACHED();
      break;
    }

  case SYS_EXIT: // 1
    {
      int exitcode;
      memread_user(f->esp + 4, &exitcode, sizeof(exitcode));

      sys_exit(exitcode);
      NOT_REACHED();
      break;
    }

  case SYS_EXEC: // 2
    {
      void* cmdline;
      memread_user(f->esp + 4, &cmdline, sizeof(cmdline));

      int return_code = sys_exec((const char*) cmdline);
      f->eax = (uint32_t) return_code;
      break;
    }

  case SYS_WAIT: // 3
    {
      pid_t pid;
      memread_user(f->esp + 4, &pid, sizeof(pid_t));

      int ret = sys_wait(pid);
      f->eax = (uint32_t) ret;
      break;
    }

  case SYS_CREATE: // 4
    {
      const char* filename;
      unsigned initial_size;
      bool return_code;

      memread_user(f->esp + 4, &filename, sizeof(filename));
      memread_user(f->esp + 8, &initial_size, sizeof(initial_size));

      return_code = sys_create(filename, initial_size);
      f->eax = return_code;
      break;
    }

  case SYS_REMOVE: // 5
    {
      const char* filename;
      bool return_code;

      memread_user(f->esp + 4, &filename, sizeof(filename));

      return_code = sys_remove(filename);
      f->eax = return_code;
      break;
    }

  case SYS_OPEN: // 6
    {
      const char* filename;
      int return_code;

      memread_user(f->esp + 4, &filename, sizeof(filename));

      return_code = sys_open(filename);
      f->eax = return_code;
      break;
    }

  case SYS_FILESIZE: // 7
    {
      int fd, return_code;
      memread_user(f->esp + 4, &fd, sizeof(fd));

      return_code = sys_filesize(fd);
      f->eax = return_code;
      break;
    }

  case SYS_READ: // 8
    {
      int fd, return_code;
      void *buffer;
      unsigned size;

      memread_user(f->esp + 4, &fd, sizeof(fd));
      memread_user(f->esp + 8, &buffer, sizeof(buffer));
      memread_user(f->esp + 12, &size, sizeof(size));

      return_code = sys_read(fd, buffer, size);
      f->eax = (uint32_t) return_code;
      break;
    }

  case SYS_WRITE: // 9
    {
      int fd, return_code;
      const void *buffer;
      unsigned size;

      memread_user(f->esp + 4, &fd, sizeof(fd));
      memread_user(f->esp + 8, &buffer, sizeof(buffer));
      memread_user(f->esp + 12, &size, sizeof(size));

      return_code = sys_write(fd, buffer, size);
      f->eax = (uint32_t) return_code;
      break;
    }

  case SYS_SEEK: // 10
    {
      int fd;
      unsigned position;

      memread_user(f->esp + 4, &fd, sizeof(fd));
      memread_user(f->esp + 8, &position, sizeof(position));

      sys_seek(fd, position);
      break;
    }

  case SYS_TELL: // 11
    {
      int fd;
      unsigned return_code;

      memread_user(f->esp + 4, &fd, sizeof(fd));

      return_code = sys_tell(fd);
      f->eax = (uint32_t) return_code;
      break;
    }

  case SYS_CLOSE: // 12
    {
      int fd;
      memread_user(f->esp + 4, &fd, sizeof(fd));

      sys_close(fd);
      break;
    }

#ifdef VM
  case SYS_MMAP: // 13
    {
      int fd;
      void *addr;
      memread_user(f->esp + 4, &fd, sizeof(fd));
      memread_user(f->esp + 8, &addr, sizeof(addr));

      mmapid_t ret = sys_mmap (fd, addr);
      f->eax = ret;
      break;
    }

  case SYS_MUNMAP: // 14
    {
      mmapid_t mid;
      memread_user(f->esp + 4, &mid, sizeof(mid));

      sys_munmap(mid);
      break;
    }
#endif
#ifdef FILESYS
  case SYS_CHDIR: // 15
    {
      const char* filename;
      int return_code;

      memread_user(f->esp + 4, &filename, sizeof(filename));

      return_code = sys_chdir(filename);
      f->eax = return_code;
      break;
    }

  case SYS_MKDIR: // 16
    {
      const char* filename;
      int return_code;

      memread_user(f->esp + 4, &filename, sizeof(filename));

      return_code = sys_mkdir(filename);
      f->eax = return_code;
      break;
    }

  case SYS_READDIR: // 17
    {
      int fd;
      char *name;
      int return_code;

      memread_user(f->esp + 4, &fd, sizeof(fd));
      memread_user(f->esp + 8, &name, sizeof(name));

      return_code = sys_readdir(fd, name);
      f->eax = return_code;
      break;
    }

  case SYS_ISDIR: // 18
    {
      int fd;
      int return_code;

      memread_user(f->esp + 4, &fd, sizeof(fd));
      return_code = sys_isdir(fd);
      f->eax = return_code;
      break;
    }

  case SYS_INUMBER: // 19
    {
      int fd;
      int return_code;

      memread_user(f->esp + 4, &fd, sizeof(fd));
      return_code = sys_inumber(fd);
      f->eax = return_code;
      break;
    }

#endif


  /* unhandled case */
  default:
    printf("[ERROR] system call %d is unimplemented!\n", syscall_number);

    // ensure that waiting (parent) process should wake up and terminate.
    sys_exit(-1);
    break;
  }

}
Ejemplo n.º 11
0
Archivo: run.c Proyecto: 2510/glusterfs
int
runner_start (runner_t *runner)
{
        int pi[3][2] = {{-1, -1}, {-1, -1}, {-1, -1}};
        int xpi[2];
        int ret = 0;
        int errno_priv = 0;
        int i = 0;
        sigset_t set;

        if (runner->runerr) {
                errno = runner->runerr;
                return -1;
        }

        GF_ASSERT (runner->argv[0]);

        /* set up a channel to child to communicate back
         * possible execve(2) failures
         */
        ret = pipe(xpi);
        if (ret != -1)
                ret = fcntl (xpi[1], F_SETFD, FD_CLOEXEC);

        for (i = 0; i < 3; i++) {
                if (runner->chfd[i] != -2)
                        continue;
                ret = pipe (pi[i]);
                if (ret != -1) {
                        runner->chio[i] = fdopen (pi[i][i ? 0 : 1], i ? "r" : "w");
                        if (!runner->chio[i])
                                ret = -1;
                }
        }

        if (ret != -1)
                runner->chpid = fork ();
        switch (runner->chpid) {
        case -1:
                errno_priv = errno;
                sys_close (xpi[0]);
                sys_close (xpi[1]);
                for (i = 0; i < 3; i++) {
                        sys_close (pi[i][0]);
                        sys_close (pi[i][1]);
                }
                errno = errno_priv;
                return -1;
        case 0:
                for (i = 0; i < 3; i++)
                        sys_close (pi[i][i ? 0 : 1]);
                sys_close (xpi[0]);
                ret = 0;

                for (i = 0; i < 3; i++) {
                        if (ret == -1)
                                break;
                        switch (runner->chfd[i]) {
                        case -1:
                                /* no redir */
                                break;
                        case -2:
                                /* redir to pipe */
                                ret = dup2 (pi[i][i ? 1 : 0], i);
                                break;
                        default:
                                /* redir to file */
                                ret = dup2 (runner->chfd[i], i);
                        }
                }

                if (ret != -1 ) {
#ifdef GF_LINUX_HOST_OS
                        DIR *d = NULL;
                        struct dirent *de = NULL;
                        char *e = NULL;

                        d = sys_opendir ("/proc/self/fd");
                        if (d) {
                                while ((de = sys_readdir (d))) {
                                        i = strtoul (de->d_name, &e, 10);
                                        if (*e == '\0' && i > 2 &&
                                            i != dirfd (d) && i != xpi[1])
                                                sys_close (i);
                                }
                                sys_closedir (d);
                        } else
                                ret = -1;
#else /* !GF_LINUX_HOST_OS */
                        struct rlimit rl;
                        ret = getrlimit (RLIMIT_NOFILE, &rl);
                        GF_ASSERT (ret == 0);

                        for (i = 3; i < rl.rlim_cur; i++) {
                                if (i != xpi[1])
                                        sys_close (i);
                        }
#endif /* !GF_LINUX_HOST_OS */
                }

                if (ret != -1) {
                        /* save child from inheriting our singal handling */
                        sigemptyset (&set);
                        sigprocmask (SIG_SETMASK, &set, NULL);

                        execvp (runner->argv[0], runner->argv);
                }
                ret = sys_write (xpi[1], &errno, sizeof (errno));
                _exit (1);
        }

        errno_priv = errno;
        for (i = 0; i < 3; i++)
                sys_close (pi[i][i ? 1 : 0]);
        sys_close (xpi[1]);
        if (ret == -1) {
                for (i = 0; i < 3; i++) {
                        if (runner->chio[i]) {
                                fclose (runner->chio[i]);
                                runner->chio[i] = NULL;
                        }
                }
        } else {
                ret = sys_read (xpi[0], (char *)&errno_priv, sizeof (errno_priv));
                sys_close (xpi[0]);
                if (ret <= 0)
                        return 0;
                GF_ASSERT (ret == sizeof (errno_priv));
        }
        errno = errno_priv;
        return -1;
}
Ejemplo n.º 12
0
/**
 * Retrieve one direntry and optional stat buffer from our readdir cache.
 *
 * Increment the internal resume cookie, and refresh the cache from the
 * kernel if necessary.
 *
 * @param[in] handle vfs handle given in most VFS calls
 * @param[in] dirp system DIR handle to retrieve direntries from
 * @param[in/out] sbuf optional stat buffer to fill, this can be NULL
 *
 * @return dirent structure, NULL if at the end of the directory, NULL on error
 */
SMB_STRUCT_DIRENT *
onefs_readdir(vfs_handle_struct *handle, SMB_STRUCT_DIR *dirp,
	      SMB_STRUCT_STAT *sbuf)
{
	struct rdp_dir_state *dsp = NULL;
	SMB_STRUCT_DIRENT *ret_direntp;
	bool same_as_last;
	int ret = -1;

	/* Set stat invalid in-case we error out */
	if (sbuf)
		SET_STAT_INVALID(*sbuf);

	/* Fallback to default system routines if readdirplus is disabled */
	if (!lp_parm_bool(SNUM(handle->conn), PARM_ONEFS_TYPE,
	    PARM_USE_READDIRPLUS, PARM_USE_READDIRPLUS_DEFAULT))
	{
		return sys_readdir(dirp);
	}

	/* Retrieve state based off DIR handle */
	ret = rdp_retrieve_dir_state(dirp, &dsp, &same_as_last);
	if (ret) {
		DEBUG(1, ("Could not retrieve dir_state struct for "
			 "SMB_STRUCT_DIR pointer.\n"));
		ret_direntp = NULL;
		goto end;
	}

	/* DIR is the same, current buffer and cursors are valid.
	 * Grab the next direntry from our cache. */
	if (same_as_last) {
		if ((dsp->direntries_cursor >=
		    rdp_direntries + RDP_DIRENTRIES_SIZE) ||
		    (dsp->stat_cursor == dsp->stat_count))
		{
			/* Cache is empty, refill from kernel */
			ret = rdp_fill_cache(dsp);
			if (ret <= 0) {
				ret_direntp = NULL;
				goto end;
			}
		}
	} else {
		/* DIR is different from last call, reset all buffers and
		 * cursors, and refill the global cache from the new DIR */
		ret = rdp_fill_cache(dsp);
		if (ret <= 0) {
			ret_direntp = NULL;
			goto end;
		}
		DEBUG(8, ("Switched global rdp cache to new DIR entry.\n"));
	}

	/* Return next entry from cache */
	ret_direntp = ((SMB_STRUCT_DIRENT *)dsp->direntries_cursor);
	dsp->direntries_cursor +=
	    ((SMB_STRUCT_DIRENT *)dsp->direntries_cursor)->d_reclen;
	if (sbuf) {
		*sbuf = rdp_stats[dsp->stat_cursor];
		/* readdirplus() sets st_ino field to 0, if it was
		 * unable to retrieve stat information for that
		 * particular directory entry. */
		if (sbuf->st_ino == 0)
			SET_STAT_INVALID(*sbuf);
	}

	DEBUG(9, ("Read from DIR %p, direntry: \"%s\", location: %ld, "
		 "resume cookie: 0x%llx, cache cursor: %zu, cache count: %zu\n",
		 dsp->dirp, ret_direntp->d_name, dsp->location,
		 dsp->resume_cookie, dsp->stat_cursor, dsp->stat_count));

	dsp->resume_cookie = rdp_cookies[dsp->stat_cursor];
	dsp->stat_cursor++;
	dsp->location++;

	/* FALLTHROUGH */
end:
	/* Set rdp_last_dirp at the end of every VFS call where the cache was
	 * reloaded */
	rdp_last_dirp = dirp;
	return ret_direntp;
}
Ejemplo n.º 13
0
int readdir(unsigned int fd, struct dirent *dirp, unsigned int count)
{
  return sys_readdir(fd, dirp, count);
}
Ejemplo n.º 14
0
/**
 * @API
 *  gf_changelog_scan() - scan and generate a list of change entries
 *
 * calling this api multiple times (without calling gf_changlog_done())
 * would result new changelogs(s) being refreshed in the tracker file.
 * This call also acts as a cancellation point for the consumer.
 */
ssize_t
gf_changelog_scan ()
{
        int             tracker_fd  = 0;
        size_t          off         = 0;
        xlator_t       *this        = NULL;
        size_t          nr_entries  = 0;
        gf_changelog_journal_t *jnl = NULL;
        struct dirent  *entry       = NULL;
        struct dirent   scratch[2]  = {{0,},};
        char            buffer[PATH_MAX] = {0,};

        this = THIS;
        if (!this)
                goto out;

        jnl = (gf_changelog_journal_t *) GF_CHANGELOG_GET_API_PTR (this);
        if (!jnl)
                goto out;
        if (JNL_IS_API_DISCONNECTED (jnl)) {
                errno = ENOTCONN;
                goto out;
        }

        errno = EINVAL;

        tracker_fd = jnl->jnl_fd;
        if (gf_ftruncate (tracker_fd, 0))
                goto out;

        rewinddir (jnl->jnl_dir);

        for (;;) {
                errno = 0;
                entry = sys_readdir (jnl->jnl_dir, scratch);
                if (!entry || errno != 0)
                        break;

                if (!strcmp (basename (entry->d_name), ".")
                     || !strcmp (basename (entry->d_name), ".."))
                        continue;

                nr_entries++;

                GF_CHANGELOG_FILL_BUFFER (jnl->jnl_processing_dir,
                                          buffer, off,
                                          strlen (jnl->jnl_processing_dir));
                GF_CHANGELOG_FILL_BUFFER (entry->d_name, buffer,
                                          off, strlen (entry->d_name));
                GF_CHANGELOG_FILL_BUFFER ("\n", buffer, off, 1);

                if (gf_changelog_write (tracker_fd, buffer, off) != off) {
                        gf_msg (this->name, GF_LOG_ERROR, 0,
                                CHANGELOG_LIB_MSG_WRITE_FAILED,
                                "error writing changelog filename"
                                " to tracker file");
                        break;
                }
                off = 0;
        }

        if (!entry) {
                if (gf_lseek (tracker_fd, 0, SEEK_SET) != -1)
                        return nr_entries;
        }
 out:
        return -1;
}