static int sys_path_to_bdev(const char *path, char **mntpath, char **bdev, char **fs)
{
	int ret = -1;
	SMB_STRUCT_STAT S;
	FILE *fp;
	struct mntent *mnt;
	SMB_DEV_T devno;

	/* find the block device file */

	if (!path||!mntpath||!bdev||!fs)
		smb_panic("sys_path_to_bdev: called with NULL pointer");

	(*mntpath) = NULL;
	(*bdev) = NULL;
	(*fs) = NULL;
	
	if ( sys_stat(path, &S) == -1 )
		return (-1);

	devno = S.st_dev ;

	fp = setmntent(MOUNTED,"r");
	if (fp == NULL) {
		return -1;
	}
  
	while ((mnt = getmntent(fp))) {
		if ( sys_stat(mnt->mnt_dir,&S) == -1 )
			continue ;

		if (S.st_dev == devno) {
			(*mntpath) = SMB_STRDUP(mnt->mnt_dir);
			(*bdev) = SMB_STRDUP(mnt->mnt_fsname);
			(*fs)   = SMB_STRDUP(mnt->mnt_type);
			if ((*mntpath)&&(*bdev)&&(*fs)) {
				ret = 0;
			} else {
				SAFE_FREE(*mntpath);
				SAFE_FREE(*bdev);
				SAFE_FREE(*fs);
				ret = -1;
			}

			break;
		}
	}

	endmntent(fp) ;

	return ret;
}
Exemple #2
0
/* Check whether user is allowed to mount on the specified mount point. If it's
   OK then we change into that directory - this prevents race conditions */
static int mount_ok(char *mount_point)
{
	SMB_STRUCT_STAT st;

	if (chdir(mount_point) != 0) {
		return -1;
	}

        if (sys_stat(".", &st) != 0) {
		return -1;
        }

        if (!S_ISDIR(st.st_mode)) {
                errno = ENOTDIR;
                return -1;
        }

        if ((getuid() != 0) && 
	    ((getuid() != st.st_uid) || 
	     ((st.st_mode & S_IRWXU) != S_IRWXU))) {
                errno = EPERM;
                return -1;
        }

        return 0;
}
Exemple #3
0
int main(void) {
   put_str("I am kernel\n");
   init_all();
/********  测试代码  ********/
   struct stat obj_stat;
   sys_stat("/", &obj_stat);
   printf("/`s info\n   i_no:%d\n   size:%d\n   filetype:%s\n", \
	 obj_stat.st_ino, obj_stat.st_size, \
	 obj_stat.st_filetype == 2 ? "directory" : "regular");
   sys_stat("/dir1", &obj_stat);
   printf("/dir1`s info\n   i_no:%d\n   size:%d\n   filetype:%s\n", \
	 obj_stat.st_ino, obj_stat.st_size, \
	 obj_stat.st_filetype == 2 ? "directory" : "regular");
/********  测试代码  ********/
   while(1);
   return 0;
}
Exemple #4
0
int vfswrap_stat(vfs_handle_struct *handle, connection_struct *conn, const char *fname, SMB_STRUCT_STAT *sbuf)
{
	int result;

	START_PROFILE(syscall_stat);
	result = sys_stat(fname, sbuf);
	END_PROFILE(syscall_stat);
	return result;
}
Exemple #5
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;
}
Exemple #6
0
/*
 * get file's status
 */
int stat(const char * path, struct stat * st)
{
    char buf[MAX_PATH];
    int err;

    if((err = vfs_path_conv(path, buf)) !=0 )
        return err;

    return sys_stat(buf, st);
}
Exemple #7
0
long sys_fstatat(int dirfd, const char* name, void* st, int flags)
{
  if(name[0] == '/'){
    return sys_stat(name, st);
  }
  file_t* dir = file_get(dirfd);
  if(dir)
  {
    size_t name_size = strlen(name)+1;
    populate_mapping(st, sizeof(struct stat), PROT_WRITE);
    return frontend_syscall(SYS_fstatat, dir->kfd, (uintptr_t)name, name_size, (uintptr_t)st, flags);
  }
  return -EBADF;
}
static bool directory_exist_stat(const char *dname,SMB_STRUCT_STAT *st)
{
	SMB_STRUCT_STAT st2;
	bool ret;

	if (!st)
		st = &st2;

	if (sys_stat(dname, st, false) != 0)
		return(False);

	ret = S_ISDIR(st->st_ex_mode);
	if(!ret)
		errno = ENOTDIR;
	return ret;
}
Exemple #9
0
static codepage_p load_client_codepage( int client_codepage )
{
  pstring codepage_file_name;
  unsigned char buf[8];
  FILE *fp = NULL;
  SMB_OFF_T size;
  codepage_p cp_p = NULL;
  SMB_STRUCT_STAT st;

  DEBUG(5, ("load_client_codepage: loading codepage %d.\n", client_codepage));

  if(strlen(CODEPAGEDIR) + 14 > sizeof(codepage_file_name))
  {
    DEBUG(0,("load_client_codepage: filename too long to load\n"));
    return NULL;
  }

  pstrcpy(codepage_file_name, CODEPAGEDIR);
  pstrcat(codepage_file_name, "/");
  pstrcat(codepage_file_name, "codepage.");
  slprintf(&codepage_file_name[strlen(codepage_file_name)], 
	   sizeof(pstring)-(strlen(codepage_file_name)+1),
	   "%03d",
           client_codepage);

  if(sys_stat(codepage_file_name,&st)!=0)
  {
    DEBUG(0,("load_client_codepage: filename %s does not exist.\n",
              codepage_file_name));
    return NULL;
  }

  /* Check if it is at least big enough to hold the required
     data. Should be 2 byte version, 2 byte codepage, 4 byte length, 
     plus zero or more bytes of data. Note that the data cannot be more
     than 4 * MAXCODEPAGELINES bytes.
   */
  size = st.st_size;

  if( size < CODEPAGE_HEADER_SIZE || size > (CODEPAGE_HEADER_SIZE + 4 * MAXCODEPAGELINES))
  {
    DEBUG(0,("load_client_codepage: file %s is an incorrect size for a \
code page file (size=%d).\n", codepage_file_name, (int)size));
    return NULL;
  }
BOOL load_unicode_map(const char *codepage, smb_ucs2_t **pp_cp_to_ucs2, uint16 **pp_ucs2_to_cp)
{
  pstring unicode_map_file_name;
  FILE *fp = NULL;
  SMB_STRUCT_STAT st;
  smb_ucs2_t *cp_to_ucs2 = *pp_cp_to_ucs2;
  uint16 *ucs2_to_cp = *pp_ucs2_to_cp;
  size_t cp_to_ucs2_size;
  size_t ucs2_to_cp_size;
  size_t i;
  size_t size;
  char buf[UNICODE_MAP_HEADER_SIZE];

  DEBUG(5, ("load_unicode_map: loading unicode map for codepage %s.\n", codepage));

  if (*codepage == '\0')
    goto clean_and_exit;

  if(strlen(CODEPAGEDIR) + 13 + strlen(codepage) > sizeof(unicode_map_file_name)) {
    DEBUG(0,("load_unicode_map: filename too long to load\n"));
    goto clean_and_exit;
  }

  pstrcpy(unicode_map_file_name, CODEPAGEDIR);
  pstrcat(unicode_map_file_name, "/");
  pstrcat(unicode_map_file_name, "unicode_map.");
  pstrcat(unicode_map_file_name, codepage);

  if(sys_stat(unicode_map_file_name,&st)!=0) {
    DEBUG(0,("load_unicode_map: filename %s does not exist.\n",
              unicode_map_file_name));
    goto clean_and_exit;
  }

  size = st.st_size;

  if ((size != UNICODE_MAP_HEADER_SIZE + 4*65536) && (size != UNICODE_MAP_HEADER_SIZE +(2*256 + 2*65536))) {
    DEBUG(0,("load_unicode_map: file %s is an incorrect size for a \
unicode map file (size=%d).\n", unicode_map_file_name, (int)size));
    goto clean_and_exit;
  }
Exemple #11
0
/* we have this on HPUX, ... */
static int sys_path_to_bdev(const char *path, char **mntpath, char **bdev, char **fs)
{
	int ret = -1;
	char dev_disk[256];
	SMB_STRUCT_STAT S;

	if (!path||!mntpath||!bdev||!fs)
		smb_panic("sys_path_to_bdev: called with NULL pointer");

	(*mntpath) = NULL;
	(*bdev) = NULL;
	(*fs) = NULL;
	
	/* find the block device file */

	if ((ret=sys_stat(path, &S))!=0) {
		return ret;
	}
	
	if ((ret=devnm(S_IFBLK, S.st_dev, dev_disk, 256, 1))!=0) {
		return ret;	
	}

	/* we should get the mntpath right...
	 * but I don't know how
	 * --metze
	 */
	(*mntpath) = SMB_STRDUP(path);
	(*bdev) = SMB_STRDUP(dev_disk);
	if ((*mntpath)&&(*bdev)) {
		ret = 0;
	} else {
		SAFE_FREE(*mntpath);
		SAFE_FREE(*bdev);
		ret = -1;
	}	
	
	
	return ret;	
}
Exemple #12
0
/****************************************************************************
This is a utility function of smbrun(). It must be called only from
the child as it may leave the caller in a privileged state.
****************************************************************************/
static BOOL setup_stdout_file(char *outfile,BOOL shared)
{  
  int fd;
  SMB_STRUCT_STAT st;
  mode_t mode = S_IWUSR|S_IRUSR|S_IRGRP|S_IROTH;
  int flags = O_RDWR|O_CREAT|O_TRUNC|O_EXCL;

  close(1);

  if (shared) {
	/* become root - unprivileged users can't delete these files */
	gain_root_privilege();
	gain_root_group_privilege();
  }

  if(sys_stat(outfile, &st) == 0) {
    /* Check we're not deleting a device file. */ 
    if(st.st_mode & S_IFREG)
      unlink(outfile);
    else
      flags = O_RDWR;
  }
  /* now create the file */
  fd = sys_open(outfile,flags,mode);

  if (fd == -1) return False;

  if (fd != 1) {
    if (dup2(fd,1) != 0) {
      DEBUG(2,("Failed to create stdout file descriptor\n"));
      close(fd);
      return False;
    }
    close(fd);
  }
  return True;
}
static void ListerThread(struct ListerParams *args) {
  int                found_parent = 0;
  pid_t              clone_pid  = sys_gettid(), ppid = sys_getppid();
  char               proc_self_task[80], marker_name[48], *marker_path;
  const char         *proc_paths[3];
  const char *const  *proc_path = proc_paths;
  int                proc = -1, marker = -1, num_threads = 0;
  int                max_threads = 0, sig;
  struct kernel_stat marker_sb, proc_sb;
  stack_t            altstack;

  /* Create "marker" that we can use to detect threads sharing the same
   * address space and the same file handles. By setting the FD_CLOEXEC flag
   * we minimize the risk of misidentifying child processes as threads;
   * and since there is still a race condition,  we will filter those out
   * later, anyway.
   */
  if ((marker = sys_socket(PF_LOCAL, SOCK_DGRAM, 0)) < 0 ||
      sys_fcntl(marker, F_SETFD, FD_CLOEXEC) < 0) {
  failure:
    args->result = -1;
    args->err    = errno;
    if (marker >= 0)
      NO_INTR(sys_close(marker));
    sig_marker = marker = -1;
    if (proc >= 0)
      NO_INTR(sys_close(proc));
    sig_proc = proc = -1;
    sys__exit(1);
  }

  /* Compute search paths for finding thread directories in /proc            */
  local_itoa(strrchr(strcpy(proc_self_task, "/proc/"), '\000'), ppid);
  strcpy(marker_name, proc_self_task);
  marker_path = marker_name + strlen(marker_name);
  strcat(proc_self_task, "/task/");
  proc_paths[0] = proc_self_task; /* /proc/$$/task/                          */
  proc_paths[1] = "/proc/";       /* /proc/                                  */
  proc_paths[2] = NULL;

  /* Compute path for marker socket in /proc                                 */
  local_itoa(strcpy(marker_path, "/fd/") + 4, marker);
  if (sys_stat(marker_name, &marker_sb) < 0) {
    goto failure;
  }

  /* Catch signals on an alternate pre-allocated stack. This way, we can
   * safely execute the signal handler even if we ran out of memory.
   */
  memset(&altstack, 0, sizeof(altstack));
  altstack.ss_sp    = args->altstack_mem;
  altstack.ss_flags = 0;
  altstack.ss_size  = ALT_STACKSIZE;
  sys_sigaltstack(&altstack, (const stack_t *)NULL);

  /* Some kernels forget to wake up traced processes, when the
   * tracer dies.  So, intercept synchronous signals and make sure
   * that we wake up our tracees before dying. It is the caller's
   * responsibility to ensure that asynchronous signals do not
   * interfere with this function.
   */
  sig_marker = marker;
  sig_proc   = -1;
  for (sig = 0; sig < sizeof(sync_signals)/sizeof(*sync_signals); sig++) {
    struct kernel_sigaction sa;
    memset(&sa, 0, sizeof(sa));
    sa.sa_sigaction_ = SignalHandler;
    sys_sigfillset(&sa.sa_mask);
    sa.sa_flags      = SA_ONSTACK|SA_SIGINFO|SA_RESETHAND;
    sys_sigaction(sync_signals[sig], &sa, (struct kernel_sigaction *)NULL);
  }
  
  /* Read process directories in /proc/...                                   */
  for (;;) {
    /* Some kernels know about threads, and hide them in "/proc"
     * (although they are still there, if you know the process
     * id). Threads are moved into a separate "task" directory. We
     * check there first, and then fall back on the older naming
     * convention if necessary.
     */
    if ((sig_proc = proc = c_open(*proc_path, O_RDONLY|O_DIRECTORY, 0)) < 0) {
      if (*++proc_path != NULL)
        continue;
      goto failure;
    }
    if (sys_fstat(proc, &proc_sb) < 0)
      goto failure;
    
    /* Since we are suspending threads, we cannot call any libc
     * functions that might acquire locks. Most notably, we cannot
     * call malloc(). So, we have to allocate memory on the stack,
     * instead. Since we do not know how much memory we need, we
     * make a best guess. And if we guessed incorrectly we retry on
     * a second iteration (by jumping to "detach_threads").
     *
     * Unless the number of threads is increasing very rapidly, we
     * should never need to do so, though, as our guestimate is very
     * conservative.
     */
    if (max_threads < proc_sb.st_nlink + 100)
      max_threads = proc_sb.st_nlink + 100;
    
    /* scope */ {
      pid_t pids[max_threads];
      int   added_entries = 0;
      sig_num_threads     = num_threads;
      sig_pids            = pids;
      for (;;) {
        struct kernel_dirent *entry;
        char buf[4096];
        ssize_t nbytes = sys_getdents(proc, (struct kernel_dirent *)buf,
                                      sizeof(buf));
        if (nbytes < 0)
          goto failure;
        else if (nbytes == 0) {
          if (added_entries) {
            /* Need to keep iterating over "/proc" in multiple
             * passes until we no longer find any more threads. This
             * algorithm eventually completes, when all threads have
             * been suspended.
             */
            added_entries = 0;
            sys_lseek(proc, 0, SEEK_SET);
            continue;
          }
          break;
        }
        for (entry = (struct kernel_dirent *)buf;
             entry < (struct kernel_dirent *)&buf[nbytes];
             entry = (struct kernel_dirent *)((char *)entry+entry->d_reclen)) {
          if (entry->d_ino != 0) {
            const char *ptr = entry->d_name;
            pid_t pid;
            
            /* Some kernels hide threads by preceding the pid with a '.'     */
            if (*ptr == '.')
              ptr++;
            
            /* If the directory is not numeric, it cannot be a
             * process/thread
             */
            if (*ptr < '0' || *ptr > '9')
              continue;
            pid = local_atoi(ptr);

            /* Attach (and suspend) all threads                              */
            if (pid && pid != clone_pid) {
              struct kernel_stat tmp_sb;
              char fname[entry->d_reclen + 48];
              strcat(strcat(strcpy(fname, "/proc/"),
                            entry->d_name), marker_path);
              
              /* Check if the marker is identical to the one we created      */
              if (sys_stat(fname, &tmp_sb) >= 0 &&
                  marker_sb.st_ino == tmp_sb.st_ino) {
                long i, j;

                /* Found one of our threads, make sure it is no duplicate    */
                for (i = 0; i < num_threads; i++) {
                  /* Linear search is slow, but should not matter much for
                   * the typically small number of threads.
                   */
                  if (pids[i] == pid) {
                    /* Found a duplicate; most likely on second pass         */
                    goto next_entry;
                  }
                }
                
                /* Check whether data structure needs growing                */
                if (num_threads >= max_threads) {
                  /* Back to square one, this time with more memory          */
                  NO_INTR(sys_close(proc));
                  goto detach_threads;
                }

                /* Attaching to thread suspends it                           */
                pids[num_threads++] = pid;
                sig_num_threads     = num_threads;
                if (sys_ptrace(PTRACE_ATTACH, pid, (void *)0,
                               (void *)0) < 0) {
                  /* If operation failed, ignore thread. Maybe it
                   * just died?  There might also be a race
                   * condition with a concurrent core dumper or
                   * with a debugger. In that case, we will just
                   * make a best effort, rather than failing
                   * entirely.
                   */
                  num_threads--;
                  sig_num_threads = num_threads;
                  goto next_entry;
                }
                while (sys_waitpid(pid, (int *)0, __WALL) < 0) {
                  if (errno != EINTR) {
                    sys_ptrace_detach(pid);
                    num_threads--;
                    sig_num_threads = num_threads;
                    goto next_entry;
                  }
                }
                
                if (sys_ptrace(PTRACE_PEEKDATA, pid, &i, &j) || i++ != j ||
                    sys_ptrace(PTRACE_PEEKDATA, pid, &i, &j) || i   != j) {
                  /* Address spaces are distinct, even though both
                   * processes show the "marker". This is probably
                   * a forked child process rather than a thread.
                   */
                  sys_ptrace_detach(pid);
                  num_threads--;
                  sig_num_threads = num_threads;
                } else {
                  found_parent |= pid == ppid;
                  added_entries++;
                }
              }
            }
          }
        next_entry:;
        }
      }
      NO_INTR(sys_close(proc));
      sig_proc = proc = -1;

      /* If we failed to find any threads, try looking somewhere else in
       * /proc. Maybe, threads are reported differently on this system.
       */
      if (num_threads > 1 || !*++proc_path) {
        NO_INTR(sys_close(marker));
        sig_marker = marker = -1;

        /* If we never found the parent process, something is very wrong.
         * Most likely, we are running in debugger. Any attempt to operate
         * on the threads would be very incomplete. Let's just report an
         * error to the caller.
         */
        if (!found_parent) {
          ResumeAllProcessThreads(num_threads, pids);
          sys__exit(3);
        }

        /* Now we are ready to call the callback,
         * which takes care of resuming the threads for us.
         */
        args->result = args->callback(args->parameter, num_threads,
                                      pids, args->ap);
        args->err = errno;

        /* Callback should have resumed threads, but better safe than sorry  */
        if (ResumeAllProcessThreads(num_threads, pids)) {
          /* Callback forgot to resume at least one thread, report error     */
          args->err    = EINVAL;
          args->result = -1;
        }

        sys__exit(0);
      }
    detach_threads:
      /* Resume all threads prior to retrying the operation                  */
      ResumeAllProcessThreads(num_threads, pids);
      sig_pids = NULL;
      num_threads = 0;
      sig_num_threads = num_threads;
      max_threads += 100;
    }
  }
}
Exemple #14
0
static int syscall_dispatch(uint32_t sysnum, uint32_t args, regs_t *regs)
{
    switch (sysnum) {
        case SYS_waitpid:
            return sys_waitpid((waitpid_args_t *)args);
            
        case SYS_exit:
            do_exit((int)args);
            panic("exit failed!\n");
            return 0;
            
        case SYS_thr_exit:
            kthread_exit((void *)args);
            panic("thr_exit failed!\n");
            return 0;
            
        case SYS_thr_yield:
            sched_make_runnable(curthr);
            sched_switch();
            return 0;
            
        case SYS_fork:
            return sys_fork(regs);
            
        case SYS_getpid:
            return curproc->p_pid;
            
        case SYS_sync:
            sys_sync();
            return 0;
            
#ifdef __MOUNTING__
        case SYS_mount:
            return sys_mount((mount_args_t *) args);
            
        case SYS_umount:
            return sys_umount((argstr_t *) args);
#endif
            
        case SYS_mmap:
            return (int) sys_mmap((mmap_args_t *) args);
            
        case SYS_munmap:
            return sys_munmap((munmap_args_t *) args);
            
        case SYS_open:
            return sys_open((open_args_t *) args);
            
        case SYS_close:
            return sys_close((int)args);
            
        case SYS_read:
            return sys_read((read_args_t *)args);
            
        case SYS_write:
            return sys_write((write_args_t *)args);
            
        case SYS_dup:
            return sys_dup((int)args);
            
        case SYS_dup2:
            return sys_dup2((dup2_args_t *)args);
            
        case SYS_mkdir:
            return sys_mkdir((mkdir_args_t *)args);
            
        case SYS_rmdir:
            return sys_rmdir((argstr_t *)args);
            
        case SYS_unlink:
            return sys_unlink((argstr_t *)args);
            
        case SYS_link:
            return sys_link((link_args_t *)args);
            
        case SYS_rename:
            return sys_rename((rename_args_t *)args);
            
        case SYS_chdir:
            return sys_chdir((argstr_t *)args);
            
        case SYS_getdents:
            return sys_getdents((getdents_args_t *)args);
            
        case SYS_brk:
            return (int) sys_brk((void *)args);
            
        case SYS_lseek:
            return sys_lseek((lseek_args_t *)args);
            
        case SYS_halt:
            sys_halt();
            return -1;
            
        case SYS_set_errno:
            curthr->kt_errno = (int)args;
            return 0;
            
        case SYS_errno:
            return curthr->kt_errno;
            
        case SYS_execve:
            return sys_execve((execve_args_t *)args, regs);
            
        case SYS_stat:
            return sys_stat((stat_args_t *)args);
            
        case SYS_uname:
            return sys_uname((struct utsname *)args);
            
        case SYS_debug:
            return sys_debug((argstr_t *)args);
        case SYS_kshell:
            return sys_kshell((int)args);
        default:
            dbg(DBG_ERROR, "ERROR: unknown system call: %d (args: %#08x)\n", sysnum, args);
            curthr->kt_errno = ENOSYS;
            return -1;
    }
}
Exemple #15
0
int sys_lstat(char* filename, struct stat * statbuf)
{
	return sys_stat(filename,statbuf);
}
Exemple #16
0
BOOL disk_quotas(const char *path, SMB_BIG_UINT *bsize, SMB_BIG_UINT *dfree, SMB_BIG_UINT *dsize)
{
  struct mntent *mnt;
  FILE *fd;
  SMB_STRUCT_STAT sbuf;
  SMB_DEV_T devno ;
  static SMB_DEV_T devno_cached = 0 ;
  static pstring name;
  struct q_request request ;
  struct qf_header header ;
  static int quota_default = 0 ;
  int found ;
  
  if ( sys_stat(path,&sbuf) == -1 )
    return(False) ;
  
  devno = sbuf.st_dev ;
  
  if ( devno != devno_cached ) {
    
    devno_cached = devno ;
    
    if ((fd = setmntent(KMTAB)) == NULL)
      return(False) ;
    
    found = False ;
    
    while ((mnt = getmntent(fd)) != NULL) {
      
      if ( sys_stat(mnt->mnt_dir,&sbuf) == -1 )
	continue ;
      
      if (sbuf.st_dev == devno) {
	
	found = True ;
	break ;
	
      }
      
    }
    
    pstrcpy(name,mnt->mnt_dir) ;
    endmntent(fd) ;
    
    if ( ! found )
      return(False) ;
  }
  
  request.qf_magic = QF_MAGIC ;
  request.qf_entry.id = geteuid() ;
  
  if (quotactl(name, Q_GETQUOTA, &request) == -1)
    return(False) ;
  
  if ( ! request.user )
    return(False) ;
  
  if ( request.qf_entry.user_q.f_quota == QFV_DEFAULT ) {
    
    if ( ! quota_default ) {
      
      if ( quotactl(name, Q_GETHEADER, &header) == -1 )
	return(False) ;
      else
	quota_default = header.user_h.def_fq ;
    }
    
    *dfree = quota_default ;
    
  }else if ( request.qf_entry.user_q.f_quota == QFV_PREVENT ) {
    
    *dfree = 0 ;
    
  }else{
    
    *dfree = request.qf_entry.user_q.f_quota ;
    
  }
  
  *dsize = request.qf_entry.user_q.f_use ;
  
  if ( *dfree < *dsize )
    *dfree = 0 ;
  else
    *dfree -= *dsize ;
  
  *bsize = 4096 ;  /* Cray blocksize */
  
  return(True) ;
  
}
Exemple #17
0
BOOL disk_quotas(const char *path, SMB_BIG_UINT *bsize, SMB_BIG_UINT *dfree, SMB_BIG_UINT *dsize)
{
	int r;
	SMB_STRUCT_STAT S;
	FILE *fp;
	LINUX_SMB_DISK_QUOTA D;
	struct mntent *mnt;
	SMB_DEV_T devno;
	int found;
	uid_t euser_id;

	euser_id = geteuid();
  
	/* find the block device file */
  
	if ( sys_stat(path, &S) == -1 )
		return(False) ;

	devno = S.st_dev ;
  
	fp = setmntent(MOUNTED,"r");
	found = False ;
  
	while ((mnt = getmntent(fp))) {
		if ( sys_stat(mnt->mnt_dir,&S) == -1 )
			continue ;

		if (S.st_dev == devno) {
			found = True ;
			break;
		}
	}

	endmntent(fp) ;
  
	if (!found)
		return(False);

	save_re_uid();
	set_effective_uid(0);  

	if (strcmp(mnt->mnt_type, "xfs")) {
		r=get_smb_linux_gen_quota(mnt->mnt_fsname, euser_id, &D);
		if (r == -1) {
			r=get_smb_linux_v2_quota(mnt->mnt_fsname, euser_id, &D);
			if (r == -1)
				r=get_smb_linux_v1_quota(mnt->mnt_fsname, euser_id, &D);
		}
	} else {
		r=get_smb_linux_xfs_quota(mnt->mnt_fsname, euser_id, &D);
	}

	restore_re_uid();

	/* Use softlimit to determine disk space, except when it has been exceeded */
	*bsize = D.bsize;
	if (r == -1) {
		if (errno == EDQUOT) {
			*dfree =0;
			*dsize =D.curblocks;
			return (True);
		} else {
			return(False);
		}
	}

	/* Use softlimit to determine disk space, except when it has been exceeded */
	if (
		(D.softlimit && D.curblocks >= D.softlimit) ||
		(D.hardlimit && D.curblocks >= D.hardlimit) ||
		(D.isoftlimit && D.curinodes >= D.isoftlimit) ||
		(D.ihardlimit && D.curinodes>=D.ihardlimit)
	) {
		*dfree = 0;
		*dsize = D.curblocks;
	} else if (D.softlimit==0 && D.hardlimit==0) {
		return(False);
	} else {
		if (D.softlimit == 0)
			D.softlimit = D.hardlimit;
		*dfree = D.softlimit - D.curblocks;
		*dsize = D.softlimit;
	}

	return (True);
}
Exemple #18
0
int dos_stat(char *fname,SMB_STRUCT_STAT *sbuf)
{
  return(sys_stat(dos_to_unix(fname,False),sbuf));
}
Exemple #19
0
BOOL disk_quotas(const char *path, SMB_BIG_UINT *bsize, SMB_BIG_UINT *dfree, SMB_BIG_UINT *dsize)
{
	uid_t euser_id;
	int ret;
	struct dqblk D;
#if defined(SUNOS5)
	struct quotctl command;
	int file;
	static struct mnttab mnt;
	static pstring name;
	pstring devopt;
#else /* SunOS4 */
	struct mntent *mnt;
	static pstring name;
#endif
	FILE *fd;
	SMB_STRUCT_STAT sbuf;
	SMB_DEV_T devno ;
	static SMB_DEV_T devno_cached = 0 ;
	static int found ;

	euser_id = geteuid();
  
	if ( sys_stat(path,&sbuf) == -1 )
		return(False) ;
  
	devno = sbuf.st_dev ;
	DEBUG(5,("disk_quotas: looking for path \"%s\" devno=%x\n", path,(unsigned int)devno));
	if ( devno != devno_cached ) {
		devno_cached = devno ;
#if defined(SUNOS5)
		if ((fd = sys_fopen(MNTTAB, "r")) == NULL)
			return(False) ;
    
		found = False ;
		slprintf(devopt, sizeof(devopt) - 1, "dev=%x", (unsigned int)devno);
		while (getmntent(fd, &mnt) == 0) {
			if( !hasmntopt(&mnt, devopt) )
				continue;

			DEBUG(5,("disk_quotas: testing \"%s\" %s\n", mnt.mnt_mountp,devopt));

			/* quotas are only on vxfs, UFS or NFS */
			if ( strcmp( mnt.mnt_fstype, MNTTYPE_UFS ) == 0 ||
				strcmp( mnt.mnt_fstype, "nfs" ) == 0    ||
				strcmp( mnt.mnt_fstype, "vxfs" ) == 0  ) { 
					found = True ;
					break;
			}
		}
    
		pstrcpy(name,mnt.mnt_mountp) ;
		pstrcat(name,"/quotas") ;
		fclose(fd) ;
#else /* SunOS4 */
		if ((fd = setmntent(MOUNTED, "r")) == NULL)
			return(False) ;
    
		found = False ;
		while ((mnt = getmntent(fd)) != NULL) {
			if ( sys_stat(mnt->mnt_dir,&sbuf) == -1 )
				continue ;
			DEBUG(5,("disk_quotas: testing \"%s\" devno=%x\n", mnt->mnt_dir,(unsigned int)sbuf.st_dev));
			if (sbuf.st_dev == devno) {
				found = True ;
				break;
			}
		}
    
		pstrcpy(name,mnt->mnt_fsname) ;
		endmntent(fd) ;
#endif
	}

	if ( ! found )
		return(False) ;

	save_re_uid();
	set_effective_uid(0);

#if defined(SUNOS5)
	if ( strcmp( mnt.mnt_fstype, "nfs" ) == 0) {
		BOOL retval;
		DEBUG(5,("disk_quotas: looking for mountpath (NFS) \"%s\"\n", mnt.mnt_special));
		retval = nfs_quotas(mnt.mnt_special, euser_id, bsize, dfree, dsize);
		restore_re_uid();
		return retval;
	}

	DEBUG(5,("disk_quotas: looking for quotas file \"%s\"\n", name));
	if((file=sys_open(name, O_RDONLY,0))<0) {
		restore_re_uid();
		return(False);
	}
	command.op = Q_GETQUOTA;
	command.uid = euser_id;
	command.addr = (caddr_t) &D;
	ret = ioctl(file, Q_QUOTACTL, &command);
	close(file);
#else
	DEBUG(5,("disk_quotas: trying quotactl on device \"%s\"\n", name));
	ret = quotactl(Q_GETQUOTA, name, euser_id, &D);
#endif

	restore_re_uid();

	if (ret < 0) {
		DEBUG(5,("disk_quotas ioctl (Solaris) failed. Error = %s\n", strerror(errno) ));

#if defined(SUNOS5) && defined(VXFS_QUOTA)
		/* If normal quotactl() fails, try vxfs private calls */
		set_effective_uid(euser_id);
		DEBUG(5,("disk_quotas: mount type \"%s\"\n", mnt.mnt_fstype));
		if ( 0 == strcmp ( mnt.mnt_fstype, "vxfs" )) {
			BOOL retval;
			retval = disk_quotas_vxfs(name, path, bsize, dfree, dsize);
			return(retval);
		}
#else
		return(False);
#endif
	}

	/* If softlimit is zero, set it equal to hardlimit.
	 */
  
	if (D.dqb_bsoftlimit==0)
		D.dqb_bsoftlimit = D.dqb_bhardlimit;

	/* Use softlimit to determine disk space. A user exceeding the quota is told
	 * that there's no space left. Writes might actually work for a bit if the
	 * hardlimit is set higher than softlimit. Effectively the disk becomes
	 * made of rubber latex and begins to expand to accommodate the user :-)
	 */

	if (D.dqb_bsoftlimit==0)
		return(False);
	*bsize = DEV_BSIZE;
	*dsize = D.dqb_bsoftlimit;

	if (D.dqb_curblocks > D.dqb_bsoftlimit) {
		*dfree = 0;
		*dsize = D.dqb_curblocks;
	} else
		*dfree = D.dqb_bsoftlimit - D.dqb_curblocks;
      
	DEBUG(5,("disk_quotas for path \"%s\" returning  bsize %.0f, dfree %.0f, dsize %.0f\n",
		path,(double)*bsize,(double)*dfree,(double)*dsize));

	return(True);
}
Exemple #20
0
BOOL disk_quotas(const char *path, SMB_BIG_UINT *bsize, SMB_BIG_UINT *dfree, SMB_BIG_UINT *dsize)
{
  uid_t euser_id;
  int r;
  struct dqblk D;
  struct fs_disk_quota        F;
  SMB_STRUCT_STAT S;
  FILE *fp;
  struct mntent *mnt;
  SMB_DEV_T devno;
  int found;
  
  /* find the block device file */
  
  if ( sys_stat(path, &S) == -1 ) {
    return(False) ;
  }

  devno = S.st_dev ;
  
  fp = setmntent(MOUNTED,"r");
  found = False ;
  
  while ((mnt = getmntent(fp))) {
    if ( sys_stat(mnt->mnt_dir,&S) == -1 )
      continue ;
    if (S.st_dev == devno) {
      found = True ;
      break ;
    }
  }
  endmntent(fp) ;
  
  if (!found) {
    return(False);
  }

  euser_id=geteuid();
  save_re_uid();
  set_effective_uid(0);  

  /* Use softlimit to determine disk space, except when it has been exceeded */

  *bsize = 512;

  if ( 0 == strcmp ( mnt->mnt_type, "efs" ))
  {
    r=quotactl (Q_GETQUOTA, mnt->mnt_fsname, euser_id, (caddr_t) &D);

    restore_re_uid();

    if (r==-1)
      return(False);
        
    /* Use softlimit to determine disk space, except when it has been exceeded */
    if (
        (D.dqb_bsoftlimit && D.dqb_curblocks>=D.dqb_bsoftlimit) ||
        (D.dqb_bhardlimit && D.dqb_curblocks>=D.dqb_bhardlimit) ||
        (D.dqb_fsoftlimit && D.dqb_curfiles>=D.dqb_fsoftlimit) ||
        (D.dqb_fhardlimit && D.dqb_curfiles>=D.dqb_fhardlimit)
       )
    {
      *dfree = 0;
      *dsize = D.dqb_curblocks;
    }
    else if (D.dqb_bsoftlimit==0 && D.dqb_bhardlimit==0)
    {
      return(False);
    }
    else 
    {
      *dfree = D.dqb_bsoftlimit - D.dqb_curblocks;
      *dsize = D.dqb_bsoftlimit;
    }

  }
  else if ( 0 == strcmp ( mnt->mnt_type, "xfs" ))
  {
    r=quotactl (Q_XGETQUOTA, mnt->mnt_fsname, euser_id, (caddr_t) &F);

    restore_re_uid();

    if (r==-1)
      return(False);
        
    /* Use softlimit to determine disk space, except when it has been exceeded */
    if (
        (F.d_blk_softlimit && F.d_bcount>=F.d_blk_softlimit) ||
        (F.d_blk_hardlimit && F.d_bcount>=F.d_blk_hardlimit) ||
        (F.d_ino_softlimit && F.d_icount>=F.d_ino_softlimit) ||
        (F.d_ino_hardlimit && F.d_icount>=F.d_ino_hardlimit)
       )
    {
      *dfree = 0;
      *dsize = F.d_bcount;
    }
    else if (F.d_blk_softlimit==0 && F.d_blk_hardlimit==0)
    {
      return(False);
    }
    else 
    {
      *dfree = (F.d_blk_softlimit - F.d_bcount);
      *dsize = F.d_blk_softlimit;
    }

  }
  else
  {
	  restore_re_uid();
	  return(False);
  }

  return (True);

}
Exemple #21
0
char *dos_GetWd(char *path)
{
  pstring s;
  static BOOL getwd_cache_init = False;
  SMB_STRUCT_STAT st, st2;
  int i;

  *s = 0;

  if (!use_getwd_cache)
    return(dos_getwd(path));

  /* init the cache */
  if (!getwd_cache_init)
  {
    getwd_cache_init = True;
    for (i=0;i<MAX_GETWDCACHE;i++)
    {
      string_set(&ino_list[i].dos_path,"");
      ino_list[i].valid = False;
    }
  }

  /*  Get the inode of the current directory, if this doesn't work we're
      in trouble :-) */

  if (sys_stat(".",&st) == -1)
  {
    DEBUG(0,("Very strange, couldn't stat \".\" path=%s\n", path));
    return(dos_getwd(path));
  }


  for (i=0; i<MAX_GETWDCACHE; i++)
    if (ino_list[i].valid)
    {

      /*  If we have found an entry with a matching inode and dev number
          then find the inode number for the directory in the cached string.
          If this agrees with that returned by the stat for the current
          directory then all is o.k. (but make sure it is a directory all
          the same...) */

      if (st.st_ino == ino_list[i].inode &&
          st.st_dev == ino_list[i].dev)
      {
        if (dos_stat(ino_list[i].dos_path,&st2) == 0)
        {
          if (st.st_ino == st2.st_ino &&
              st.st_dev == st2.st_dev &&
              (st2.st_mode & S_IFMT) == S_IFDIR)
          {
            pstrcpy (path, ino_list[i].dos_path);

            /* promote it for future use */
            array_promote((char *)&ino_list[0],sizeof(ino_list[0]),i);
            return (path);
          }
          else
          {
            /*  If the inode is different then something's changed,
                scrub the entry and start from scratch. */
            ino_list[i].valid = False;
          }
        }
      }
    }


  /*  We don't have the information to hand so rely on traditional methods.
      The very slow getcwd, which spawns a process on some systems, or the
      not quite so bad getwd. */

  if (!dos_getwd(s))
  {
    DEBUG(0,("dos_GetWd: dos_getwd call failed, errno %s\n",strerror(errno)));
    return (NULL);
  }

  pstrcpy(path,s);

  DEBUG(5,("dos_GetWd %s, inode %.0f, dev %.0f\n",s,(double)st.st_ino,(double)st.st_dev));

  /* add it to the cache */
  i = MAX_GETWDCACHE - 1;
  string_set(&ino_list[i].dos_path,s);
  ino_list[i].dev = st.st_dev;
  ino_list[i].inode = st.st_ino;
  ino_list[i].valid = True;

  /* put it at the top of the list */
  array_promote((char *)&ino_list[0],sizeof(ino_list[0]),i);

  return (path);
}
Exemple #22
0
int
gf_sqlite3_init (dict_t *args, void **db_conn) {
        int ret                         = -1;
        gf_sql_connection_t *sql_conn   = NULL;
        struct stat stbuf               = {0,};
        gf_boolean_t    is_dbfile_exist = _gf_false;
        char *temp_str                  = NULL;

        GF_ASSERT (args);
        GF_ASSERT (db_conn);

        if (*db_conn != NULL) {
                gf_msg (GFDB_STR_SQLITE3, GF_LOG_ERROR, 0,
                        LG_MSG_CONNECTION_ERROR, "DB Connection is not "
                        "empty!");
                return 0;
        }

        if (!sqlite3_threadsafe ()) {
                gf_msg (GFDB_STR_SQLITE3, GF_LOG_ERROR, 0,
                        LG_MSG_NOT_MULTITHREAD_MODE,
                        "sqlite3 is not in multithreaded mode");
                goto out;
        }

        sql_conn = gf_sql_connection_init ();
        if (!sql_conn) {
                goto out;
        }

        /*Extract sql db path from args*/
        temp_str = NULL;
        GET_DB_PARAM_FROM_DICT(GFDB_STR_SQLITE3, args,
                        GFDB_SQL_PARAM_DBPATH, temp_str, out);
        strncpy(sql_conn->sqlite3_db_path, temp_str, PATH_MAX-1);
        sql_conn->sqlite3_db_path[PATH_MAX-1] = 0;

        is_dbfile_exist = (sys_stat (sql_conn->sqlite3_db_path, &stbuf) == 0) ?
                                                _gf_true : _gf_false;

        /*Creates DB if not created*/
        sql_conn->sqlite3_db_conn = gf_open_sqlite3_conn (
                                        sql_conn->sqlite3_db_path,
                                        SQLITE_OPEN_READWRITE |
                                        SQLITE_OPEN_CREATE);
        if (!sql_conn->sqlite3_db_conn) {
                gf_msg (GFDB_STR_SQLITE3, GF_LOG_ERROR, 0,
                        LG_MSG_CONNECTION_ERROR,
                        "Failed creating db connection");
                goto out;
        }

        /* If the file exist we skip the config part
         * and creation of the schema */
        if (is_dbfile_exist)
                goto db_exists;


        /*Apply sqlite3 params to database*/
        ret = apply_sql_params_db (sql_conn, args);
        if (ret) {
                gf_msg (GFDB_STR_SQLITE3, GF_LOG_ERROR, 0,
                        LG_MSG_SET_PARAM_FAILED, "Failed applying sql params"
                        " to %s", sql_conn->sqlite3_db_path);
                goto out;
        }

        /*Create the schema if NOT present*/
        ret = create_filetable (sql_conn->sqlite3_db_conn);
        if (ret) {
                gf_msg (GFDB_STR_SQLITE3, GF_LOG_ERROR, 0,
                        LG_MSG_CREATE_FAILED, "Failed Creating %s Table",
                        GF_FILE_TABLE);
               goto out;
        }

db_exists:
        ret = 0;
out:
        if (ret) {
                gf_sqlite3_fini ((void **)&sql_conn);
        }

        *db_conn = sql_conn;

        return ret;
}
Exemple #23
0
BOOL disk_quotas(const char *path, SMB_BIG_UINT *bsize, SMB_BIG_UINT *dfree, SMB_BIG_UINT *dsize)
{
  int r;
  struct dqblk D;
  uid_t euser_id;
#if !defined(__FreeBSD__) && !defined(AIX) && !defined(__OpenBSD__)
  char dev_disk[256];
  SMB_STRUCT_STAT S;

  /* find the block device file */

#ifdef HPUX
  /* Need to set the cache flag to 1 for HPUX. Seems
   * to have a significant performance boost when
   * lstat calls on /dev access this function.
   */
  if ((sys_stat(path, &S)<0) || (devnm(S_IFBLK, S.st_dev, dev_disk, 256, 1)<0))
#else
  if ((sys_stat(path, &S)<0) || (devnm(S_IFBLK, S.st_dev, dev_disk, 256, 0)<0)) 
	return (False);
#endif /* ifdef HPUX */

#endif /* !defined(__FreeBSD__) && !defined(AIX) && !defined(__OpenBSD__) */

  euser_id = geteuid();

#ifdef HPUX
  /* for HPUX, real uid must be same as euid to execute quotactl for euid */
  save_re_uid();
  if (set_re_uid() != 0) return False;
  
  r=quotactl(Q_GETQUOTA, dev_disk, euser_id, &D);

  restore_re_uid();
#else 
#if defined(__FreeBSD__) || defined(__OpenBSD__)
  {
    /* FreeBSD patches from Marty Moll <*****@*****.**> */
    gid_t egrp_id;
 
    save_re_uid();
    set_effective_uid(0);

    egrp_id = getegid();
    r= quotactl(path,QCMD(Q_GETQUOTA,USRQUOTA),euser_id,(char *) &D);

    /* As FreeBSD has group quotas, if getting the user
       quota fails, try getting the group instead. */
    if (r) {
	    r= quotactl(path,QCMD(Q_GETQUOTA,GRPQUOTA),egrp_id,(char *) &D);
    }

    restore_re_uid();
  }
#elif defined(AIX)
  /* AIX has both USER and GROUP quotas: 
     Get the USER quota ([email protected]) */
  r= quotactl(path,QCMD(Q_GETQUOTA,USRQUOTA),euser_id,(char *) &D);
#else /* !__FreeBSD__ && !AIX && !__OpenBSD__ */
  r=quotactl(Q_GETQUOTA, dev_disk, euser_id, &D);
#endif /* !__FreeBSD__ && !AIX && !__OpenBSD__ */
#endif /* HPUX */

  /* Use softlimit to determine disk space, except when it has been exceeded */
#if defined(__FreeBSD__) || defined(__OpenBSD__)
  *bsize = DEV_BSIZE;
#else /* !__FreeBSD__ && !__OpenBSD__ */
  *bsize = 1024;
#endif /*!__FreeBSD__ && !__OpenBSD__ */

  if (r)
    {
      if (errno == EDQUOT) 
	{
 	  *dfree =0;
 	  *dsize =D.dqb_curblocks;
 	  return (True);
	}
      else return(False);
    }

  /* If softlimit is zero, set it equal to hardlimit.
   */

  if (D.dqb_bsoftlimit==0)
    D.dqb_bsoftlimit = D.dqb_bhardlimit;

  if (D.dqb_bsoftlimit==0)
    return(False);
  /* Use softlimit to determine disk space, except when it has been exceeded */
  if ((D.dqb_curblocks>D.dqb_bsoftlimit)
#if !defined(__FreeBSD__) && !defined(__OpenBSD__)
||((D.dqb_curfiles>D.dqb_fsoftlimit) && (D.dqb_fsoftlimit != 0))
#endif
    ) {
      *dfree = 0;
      *dsize = D.dqb_curblocks;
    }
  else {
    *dfree = D.dqb_bsoftlimit - D.dqb_curblocks;
    *dsize = D.dqb_bsoftlimit;
  }
  return (True);
}
Exemple #24
0
streampos filebuf::seekoff(streamoff offset, _seek_dir dir, int mode)
{
    streampos result, new_offset, delta;
    _G_ssize_t count;

    if (mode == 0) // Don't move any pointers.
	dir = ios::cur, offset = 0;

    // Flush unwritten characters.
    // (This may do an unneeded write if we seek within the buffer.
    // But to be able to switch to reading, we would need to set
    // egptr to ptr.  That can't be done in the current design,
    // which assumes file_ptr() is eGptr.  Anyway, since we probably
    // end up flushing when we close(), it doesn't make much difference.)
    if (pptr() > pbase() || put_mode())
	if (switch_to_get_mode()) return EOF;

    if (base() == NULL) {
	doallocbuf();
	setp(base(), base());
	setg(base(), base(), base());
    }
    switch (dir) {
      case ios::cur:
	if (_fb._offset < 0) {
	    _fb._offset = sys_seek(0, ios::cur);
	    if (_fb._offset < 0)
		return EOF;
	}
	// Make offset absolute, assuming current pointer is file_ptr().
	offset += _fb._offset;

	offset -= _egptr - _gptr;
	if (in_backup())
	    offset -= _other_egptr - _other_gbase;
	dir = ios::beg;
	break;
      case ios::beg:
	break;
      case ios::end:
	struct stat st;
	if (sys_stat(&st) == 0 && S_ISREG(st.st_mode)) {
	    offset += st.st_size;
	    dir = ios::beg;
	}
	else
	    goto dumb;
    }
    // At this point, dir==ios::beg.

    // If destination is within current buffer, optimize:
    if (_fb._offset >= 0 && _eback != NULL) {
	// Offset relative to start of main get area.
	fpos_t rel_offset = offset - _fb._offset
	    + (eGptr()-Gbase());
	if (rel_offset >= 0) {
	    if (in_backup())
		switch_to_main_get_area();
	    if (rel_offset <= _egptr - _eback) {
		setg(base(), base() + rel_offset, egptr());
		setp(base(), base());
		return offset;
	    }
	    // If we have streammarkers, seek forward by reading ahead.
	    if (have_markers()) {
		int to_skip = rel_offset - (_gptr - _eback);
		if (ignore(to_skip) != to_skip)
		    goto dumb;
		return offset;
	    }
	}
	if (rel_offset < 0 && rel_offset >= Bbase() - Bptr()) {
	    if (!in_backup())
		switch_to_backup_area();
	    gbump(_egptr + rel_offset - gptr());
	    return offset;
	}
    }

    unsave_markers();

    // Try to seek to a block boundary, to improve kernel page management.
    new_offset = offset & ~(ebuf() - base() - 1);
    delta = offset - new_offset;
    if (delta > ebuf() - base()) {
	new_offset = offset;
	delta = 0;
    }
    result = sys_seek(new_offset, ios::beg);
    if (result < 0)
	return EOF;
    if (delta == 0)
	count = 0;
    else {
	count = sys_read(base(), ebuf()-base());
	if (count < delta) {
	    // We weren't allowed to read, but try to seek the remainder.
	    offset = count == EOF ? delta : delta-count;
	    dir = ios::cur;
	    goto dumb;
	}
    }
    setg(base(), base()+delta, base()+count);
    setp(base(), base());
    _fb._offset = result + count;
    xflags(xflags() & ~ _S_EOF_SEEN);
    return offset;
  dumb:
    unsave_markers();
    result = sys_seek(offset, dir);
    if (result != EOF) {
	xflags(xflags() & ~_S_EOF_SEEN);
    }
    _fb._offset = result;
    setg(base(), base(), base());
    setp(base(), base());
    return result;
}
Exemple #25
0
/***************************************************************************
handle a file download
  ***************************************************************************/
static void cgi_download(char *file)
{
	SMB_STRUCT_STAT st;
	char buf[1024];
	int fd, l, i;
	char *p;
	char *lang;

	/* sanitise the filename */
	for (i=0;file[i];i++) {
		if (!isalnum((int)file[i]) && !strchr_m("/.-_", file[i])) {
			cgi_setup_error("404 File Not Found","",
					"Illegal character in filename");
		}
	}

	if (sys_stat(file, &st) != 0) 
	{
		cgi_setup_error("404 File Not Found","",
				"The requested file was not found");
	}

	if (S_ISDIR(st.st_mode))
	{
		snprintf(buf, sizeof(buf), "%s/index.html", file);
		if (!file_exist(buf, &st) || !S_ISREG(st.st_mode))
		{
			cgi_setup_error("404 File Not Found","",
					"The requested file was not found");
		}
	}
	else if (S_ISREG(st.st_mode))
	{
		snprintf(buf, sizeof(buf), "%s", file);
	}
	else
	{
		cgi_setup_error("404 File Not Found","",
				"The requested file was not found");
	}

	fd = web_open(buf,O_RDONLY,0);
	if (fd == -1) {
		cgi_setup_error("404 File Not Found","",
				"The requested file was not found");
	}
	printf("HTTP/1.0 200 OK\r\n");
	if ((p=strrchr_m(buf, '.'))) {
		if (strcmp(p,".gif")==0) {
			printf("Content-Type: image/gif\r\n");
		} else if (strcmp(p,".jpg")==0) {
			printf("Content-Type: image/jpeg\r\n");
		} else if (strcmp(p,".png")==0) {
			printf("Content-Type: image/png\r\n");
		} else if (strcmp(p,".css")==0) {
			printf("Content-Type: text/css\r\n");
		} else if (strcmp(p,".txt")==0) {
			printf("Content-Type: text/plain\r\n");
		} else {
			printf("Content-Type: text/html\r\n");
		}
	}
	printf("Expires: %s\r\n", http_timestring(time(NULL)+EXPIRY_TIME));

	lang = lang_tdb_current();
	if (lang) {
		printf("Content-Language: %s\r\n", lang);
	}

	printf("Content-Length: %d\r\n\r\n", (int)st.st_size);
	while ((l=read(fd,buf,sizeof(buf)))>0) {
		if (fwrite(buf, 1, l, stdout) != l) {
			break;
		}
	}
	close(fd);
	exit(0);
}
Exemple #26
0
BOOL disk_quotas(const char *path, SMB_BIG_UINT *bsize, SMB_BIG_UINT *dfree, SMB_BIG_UINT *dsize)
{
  int r;
  struct dqblk D;
  uid_t euser_id;
#if !defined(__FreeBSD__) && !defined(AIX) && !defined(__OpenBSD__) && !defined(__DragonFly__)
  char dev_disk[256];
  SMB_STRUCT_STAT S;

  /* find the block device file */

#ifdef HPUX
  /* Need to set the cache flag to 1 for HPUX. Seems
   * to have a significant performance boost when
   * lstat calls on /dev access this function.
   */
  if ((sys_stat(path, &S)<0) || (devnm(S_IFBLK, S.st_dev, dev_disk, 256, 1)<0))
#else
  if ((sys_stat(path, &S)<0) || (devnm(S_IFBLK, S.st_dev, dev_disk, 256, 0)<0)) 
	return (False);
#endif /* ifdef HPUX */

#endif /* !defined(__FreeBSD__) && !defined(AIX) && !defined(__OpenBSD__) && !defined(__DragonFly__) */

  euser_id = geteuid();

#ifdef HPUX
  /* for HPUX, real uid must be same as euid to execute quotactl for euid */
  save_re_uid();
  if (set_re_uid() != 0) return False;
  
  r=quotactl(Q_GETQUOTA, dev_disk, euser_id, &D);

  restore_re_uid();
#else 
#if defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__DragonFly__)
  {
    /* FreeBSD patches from Marty Moll <*****@*****.**> */
    gid_t egrp_id;
#if defined(__FreeBSD__) || defined(__DragonFly__)
    SMB_DEV_T devno;
    struct statfs *mnts;
    SMB_STRUCT_STAT st;
    int mntsize, i;
    
    if (sys_stat(path,&st) < 0)
        return False;
    devno = st.st_dev;

    mntsize = getmntinfo(&mnts,MNT_NOWAIT);
    if (mntsize <= 0)
        return False;

    for (i = 0; i < mntsize; i++) {
        if (sys_stat(mnts[i].f_mntonname,&st) < 0)
            return False;
        if (st.st_dev == devno)
            break;
    }
    if (i == mntsize)
        return False;
#endif
    
    become_root();

#if defined(__FreeBSD__) || defined(__DragonFly__)
    if (strcmp(mnts[i].f_fstypename,"nfs") == 0) {
        BOOL retval;
        retval = nfs_quotas(mnts[i].f_mntfromname,euser_id,bsize,dfree,dsize);
        unbecome_root();
        return retval;
    }
#endif

    egrp_id = getegid();
    r= quotactl(path,QCMD(Q_GETQUOTA,USRQUOTA),euser_id,(char *) &D);

    /* As FreeBSD has group quotas, if getting the user
       quota fails, try getting the group instead. */
    if (r) {
	    r= quotactl(path,QCMD(Q_GETQUOTA,GRPQUOTA),egrp_id,(char *) &D);
    }

    unbecome_root();
  }
#elif defined(AIX)
  /* AIX has both USER and GROUP quotas: 
     Get the USER quota ([email protected]) */
#ifdef _AIXVERSION_530
  {
    struct statfs statbuf;
    quota64_t user_quota;
    if (statfs(path,&statbuf) != 0)
      return False;
    if(statbuf.f_vfstype == MNT_J2)
    {
    /* For some reason we need to be root for jfs2 */
      become_root();
      r = quotactl(path,QCMD(Q_J2GETQUOTA,USRQUOTA),euser_id,(char *) &user_quota);
      unbecome_root();
    /* Copy results to old struct to let the following code work as before */
      D.dqb_curblocks  = user_quota.bused;
      D.dqb_bsoftlimit = user_quota.bsoft;
      D.dqb_bhardlimit = user_quota.bhard;
    }
    else if(statbuf.f_vfstype == MNT_JFS)
    {
#endif /* AIX 5.3 */
  save_re_uid();
  if (set_re_uid() != 0) 
    return False;
  r= quotactl(path,QCMD(Q_GETQUOTA,USRQUOTA),euser_id,(char *) &D);
  restore_re_uid();
#ifdef _AIXVERSION_530
    }
    else
      r = 1; /* Fail for other FS-types */
  }
#endif /* AIX 5.3 */
#else /* !__FreeBSD__ && !AIX && !__OpenBSD__ && !__DragonFly__ */
  r=quotactl(Q_GETQUOTA, dev_disk, euser_id, &D);
#endif /* !__FreeBSD__ && !AIX && !__OpenBSD__ && !__DragonFly__ */
#endif /* HPUX */

  /* Use softlimit to determine disk space, except when it has been exceeded */
#if defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__DragonFly__)
  *bsize = DEV_BSIZE;
#else /* !__FreeBSD__ && !__OpenBSD__ && !__DragonFly__ */
  *bsize = 1024;
#endif /*!__FreeBSD__ && !__OpenBSD__ && !__DragonFly__ */

  if (r)
    {
      if (errno == EDQUOT) 
	{
 	  *dfree =0;
 	  *dsize =D.dqb_curblocks;
 	  return (True);
	}
      else return(False);
    }

  /* If softlimit is zero, set it equal to hardlimit.
   */

  if (D.dqb_bsoftlimit==0)
    D.dqb_bsoftlimit = D.dqb_bhardlimit;

  if (D.dqb_bsoftlimit==0)
    return(False);
  /* Use softlimit to determine disk space, except when it has been exceeded */
  if ((D.dqb_curblocks>D.dqb_bsoftlimit)
#if !defined(__FreeBSD__) && !defined(__OpenBSD__) && !defined(__DragonFly__)
||((D.dqb_curfiles>D.dqb_fsoftlimit) && (D.dqb_fsoftlimit != 0))
#endif
    ) {
      *dfree = 0;
      *dsize = D.dqb_curblocks;
    }
  else {
    *dfree = D.dqb_bsoftlimit - D.dqb_curblocks;
    *dsize = D.dqb_bsoftlimit;
  }
  return (True);
}
Exemple #27
0
int wsys_stat(const smb_ucs2_t *wfname,SMB_STRUCT_STAT *sbuf)
{
	pstring fname;
	return sys_stat(unicode_to_unix(fname,wfname,sizeof(fname)), sbuf);
}
int stat(const char *file, struct stat *st)
{
    return sys_stat(file, st);
}