Пример #1
0
// Open a file (or directory).
//
// Returns:
// 	The file descriptor index on success
// 	-E_BAD_PATH if the path is too long (>= MAXPATHLEN)
// 	< 0 for other errors.
int
open(const char *path, int mode)
{
	// Find an unused file descriptor page using fd_alloc.
	// Then send a file-open request to the file server.
	// Include 'path' and 'omode' in request,
	// and map the returned file descriptor page
	// at the appropriate fd address.
	// FSREQ_OPEN returns 0 on success, < 0 on failure.
	//
	// (fd_alloc does not allocate a page, it just returns an
	// unused fd address.  Do you need to allocate a page?)
	//
	// Return the file descriptor index.
	// If any step after fd_alloc fails, use fd_close to free the
	// file descriptor.

	// LAB 5: Your code here.
	//panic("open not implemented");

	int r;
	struct Fd *fd;

	if (strlen(path) >= MAXPATHLEN)
		return -E_BAD_PATH;
	r = fd_alloc(&fd);
	if (r < 0)
		return r;
	strcpy(fsipcbuf.open.req_path, path);
	fsipcbuf.open.req_omode = mode;
	r = fsipc(FSREQ_OPEN, fd);
	if (r < 0) {
		fd_close(fd, 0);
		return r;
	}
	return fd2num(fd);
}
Пример #2
0
void _free_client(struct Client* client_p)
{
  assert(NULL != client_p);
  assert(&me != client_p);
  assert(NULL == client_p->prev);
  assert(NULL == client_p->next);

  if (MyConnect(client_p))
    {
      assert(IsClosing(client_p) && IsDead(client_p));
      
    /*
     * clean up extra sockets from P-lines which have been discarded.
     */
    if (client_p->localClient->listener)
    {
      assert(0 < client_p->localClient->listener->ref_count);
      if (0 == --client_p->localClient->listener->ref_count &&
          !client_p->localClient->listener->active) 
        free_listener(client_p->localClient->listener);
      client_p->localClient->listener = 0;
    }

      if (client_p->localClient->fd >= 0)
	fd_close(client_p->localClient->fd);

      BlockHeapFree(lclient_heap, client_p->localClient);
      --local_client_count;
      assert(local_client_count >= 0);
    }
  else
    {
      --remote_client_count;
    }

  BlockHeapFree(client_heap, client_p);
}
Пример #3
0
void close_all_connections(void)
{
  int i;
#ifndef NDEBUG
  int fd;
#endif

  /* XXX someone tell me why we care about 4 fd's ? */
  /* XXX btw, fd 3 is used for profiler ! */
#if 0
#ifndef VMS
  for (i = 0; i < MAXCONNECTIONS; ++i)
#else
  for (i = 3; i < MAXCONNECTIONS; ++i)
#endif
#endif

  for (i = 4; i < MAXCONNECTIONS; ++i)
    {
      if (fd_table[i].flags.open)
        fd_close(i);
      else
        close(i);
    }

  /* XXX should his hack be done in all cases? */
#ifndef NDEBUG
  /* fugly hack to reserve fd == 2 */
  (void)close(2);
  fd = open("stderr.log",O_WRONLY|O_CREAT|O_APPEND,0644);
  if( fd >= 0 )
    {
      dup2(fd, 2);
      close(fd);
    }
#endif
}
Пример #4
0
int ipc_accept_internal (int s, char *p, unsigned int l, int *trunc, unsigned int options)
{
  struct sockaddr_un sa ;
  socklen_t dummy = sizeof sa ;
  register int fd ;
  byte_zero((char*)&sa, (unsigned int)dummy) ;
  do
#ifdef SKALIBS_HASACCEPT4
    fd = accept4(s, (struct sockaddr *)&sa, &dummy, ((options & DJBUNIX_FLAG_NB) ? SOCK_NONBLOCK : 0) | ((options & DJBUNIX_FLAG_COE) ? SOCK_CLOEXEC : 0)) ;
#else
    fd = accept(s, (struct sockaddr *)&sa, &dummy) ;
#endif
  while ((fd == -1) && (errno == EINTR)) ;
  if (fd == -1) return -1 ;
#ifndef SKALIBS_HASACCEPT4
  if ((((options & DJBUNIX_FLAG_NB) ? ndelay_on(fd) : ndelay_off(fd)) < 0)
   || (((options & DJBUNIX_FLAG_COE) ? coe(fd) : uncoe(fd)) < 0))
  {
    register int e = errno ;
    fd_close(fd) ;
    errno = e ;
    return -1 ;
  }
#endif

  if (p)
  {
    dummy = byte_chr(sa.sun_path, dummy, 0) ;
    *trunc = 1 ;
    if (!l) return fd ;
    if (l < (dummy + 1)) dummy = l - 1 ;
    else *trunc = 0 ;
    byte_copy(p, dummy, sa.sun_path) ;
    p[dummy] = 0 ;
  }
  return fd ;
}
    void
host_ipc_init()
{
    int r;
//    cprintf("Inside host_ipc_init \n");
//    if ((r = fd_alloc(&host_fd)) < 0)
//        panic("Couldn't allocate an fd!");
    
//    r = sys_page_alloc(0, &host_fd, PTE_P | PTE_U | PTE_W);
/*    cprintf("R ==== %d\n", r);
    if (r < 0)
    {
        panic("Not Valid ALloc");
    }*/

    strcpy(host_fsipcbuf.open.req_path, HOST_FS_FILE);
    host_fsipcbuf.open.req_omode = O_RDWR;

    if ((r = host_fsipc(FSREQ_OPEN, host_fd)) < 0) {
        fd_close(host_fd, 0);
        panic("Couldn't open host file!");
    }

}
Пример #6
0
/** fobuf_newfd
 * @param b: the fobuf structure to modify
 * @param fd: the new file descriptor
 *
 * Like fobuf_close() except that the buffer and fobuf are not free'd but
 * attached to a new file descriptor.
 *
 * Return value: zero on error, non-zero on success.
 */
int fobuf_newfd(fobuf_t b, int fd)
{
	int ret=1;

	if ( b->fd == -1 )
		goto noflush;

	if ( !_fobuf_flush(b) )
		ret = 0;

	/* don't error if the output file is a special file
	 * which does not support fsync (eg: a pipe)
	 */
	if ( fsync(b->fd) && errno!=EROFS && errno!=EINVAL )
		ret = 0;

	if ( !fd_close(b->fd) )
		ret = 0;

noflush:
	b->fd = fd;

	return ret;
}
Пример #7
0
/**
 * Close stream opened to a file, along with the underlying FILE / fd.
 *
 * @return 0 on success, -1 on error.
 */
int
ostream_close_file(ostream_t *os)
{
	int ret = -1;

	g_assert(ostream_is_file(os));

	switch (os->type) {
	case OSTREAM_T_FILE:
		ret = fclose(os->u.f);
		os->u.f = NULL;
		break;
	case OSTREAM_T_FD:
		ret = fd_close(&os->u.fd);
		break;
	case OSTREAM_T_MEM:
	case OSTREAM_T_PMSG:
	case OSTREAM_T_MAX:
		g_assert_not_reached();
	}

	ostream_free(os);
	return ret;
}
Пример #8
0
// INT 80h Handler, kernel entry.
void int_80() {
	if(krn)	{
		return;
	}
	
	krn++;
	int systemCall = kernel_buffer[0];
	int fd         = kernel_buffer[1];
	int buffer     = kernel_buffer[2];
	int count      = kernel_buffer[3];

	
	int i, j;
	Process * current;
	Process * p;
	int inode;
	int _fd;
	// Yeah, wanna know why we don't access an array directly? ... Because of big bugs we might have.
	switch(systemCall) {
		case READY:
			kernel_buffer[KERNEL_RETURN] = kernel_ready();
			break;
		case WRITE:
 			current = getp();
			kernel_buffer[KERNEL_RETURN] = fd_write(current->file_descriptors[fd],(char *)buffer,count);
			break;
		case READ:
			current = getp();
			kernel_buffer[KERNEL_RETURN] = fd_read(current->file_descriptors[fd],(char *)buffer,count);
			break;
		case MKFIFO:
			_fd = process_getfreefd();
			fd = fd_open(_FD_FIFO, (void *)kernel_buffer[1],kernel_buffer[2]);
			if(_fd != -1 && fd != -1)	{
				getp()->file_descriptors[_fd] = fd;
				kernel_buffer[KERNEL_RETURN] = _fd;
			}
			else {
				kernel_buffer[KERNEL_RETURN] = -1;
			}
			break;
		case OPEN:
			_fd = process_getfreefd();
			fd = fd_open(_FD_FILE, (void *) kernel_buffer[1], kernel_buffer[2]);
			if(_fd != -1 && fd >= 0)
			{
				getp()->file_descriptors[_fd] = fd;
				kernel_buffer[KERNEL_RETURN] = _fd;
			}
			else {
				kernel_buffer[KERNEL_RETURN] = fd;
			}
			break;
		case CLOSE:
			kernel_buffer[KERNEL_RETURN] = fd_close(getp()->file_descriptors[fd]);
			break;
		case PCREATE:
			kernel_buffer[KERNEL_RETURN] = sched_pcreate(kernel_buffer[1],kernel_buffer[2],kernel_buffer[3]);
			break;
		case PRUN:
			kernel_buffer[KERNEL_RETURN] = sched_prun(kernel_buffer[1]);
			break;
		case PDUP2:
			kernel_buffer[KERNEL_RETURN] = sched_pdup2(kernel_buffer[1],kernel_buffer[2],kernel_buffer[3]);
			break;
		case GETPID:
			kernel_buffer[KERNEL_RETURN] = sched_getpid();
			break;
		case WAITPID:
			kernel_buffer[KERNEL_RETURN] = sched_waitpid(kernel_buffer[1]);
			break;
		case PTICKS:
			kernel_buffer[KERNEL_RETURN] = (int) storage_index();
			break;
		case PNAME:
			p = process_getbypid(kernel_buffer[1]);
			if(p == NULL)
			{
				kernel_buffer[KERNEL_RETURN] = (int) NULL;
			} else {
				kernel_buffer[KERNEL_RETURN] = (int) p->name;
			}
			break;
		case PSTATUS:
			p = process_getbypid(kernel_buffer[1]);
			if(p == NULL)
			{
				kernel_buffer[KERNEL_RETURN] = (int) -1;
			} else {
				kernel_buffer[KERNEL_RETURN] = (int) p->state;
			}
			break;
		case PPRIORITY:
			p = process_getbypid(kernel_buffer[1]);
			if(p == NULL)
			{
				kernel_buffer[KERNEL_RETURN] = (int) -1;
			} else {
				kernel_buffer[KERNEL_RETURN] = (int) p->priority;
			}
			break;
		case PGID:
			p = process_getbypid(kernel_buffer[1]);
			if(p == NULL)
			{
				kernel_buffer[KERNEL_RETURN] = (int) -1;
			} else {
				kernel_buffer[KERNEL_RETURN] = (int) p->gid;
			}
			break;
		case PGETPID_AT:
			p = process_getbypindex(kernel_buffer[1]);
			if (p->state != -1) {
				kernel_buffer[KERNEL_RETURN] = (int) p->pid;
			} else {
				kernel_buffer[KERNEL_RETURN] = -1;
			}
			break;
		case KILL:
			kernel_buffer[KERNEL_RETURN - 1] = kernel_buffer[1];
			kernel_buffer[KERNEL_RETURN - 2] = kernel_buffer[2];
			break;
		case PSETP:
			p = process_getbypid(kernel_buffer[1]);
			if(p == NULL)	{
				kernel_buffer[KERNEL_RETURN] = (int) -1;
			} else {
				if(kernel_buffer[2] <= 4 && kernel_buffer[2] >= 0)	{
					p->priority = kernel_buffer[2];
				}
				kernel_buffer[KERNEL_RETURN] = (int) p->gid;
			}
			break;
		case SETSCHED:
			sched_set_mode(kernel_buffer[1]);
			break;
		case PWD:
			kernel_buffer[KERNEL_RETURN] = (int) fs_pwd();
			break;
		case CD:
			kernel_buffer[KERNEL_RETURN] = (int) fs_cd(kernel_buffer[1]);
			break;
		case FINFO:
			fs_finfo(kernel_buffer[1], kernel_buffer[2]);
			break;
		case MOUNT:
			fs_init();
			break;
		case MKDIR:
			kernel_buffer[KERNEL_RETURN] = (int) fs_mkdir(kernel_buffer[1],current_ttyc()->pwd);
			break;
		case RM:
			inode = fs_indir(kernel_buffer[1],current_ttyc()->pwd);
			if (inode) {
				kernel_buffer[KERNEL_RETURN] = (int) fs_rm(inode,0);
			} else {
				kernel_buffer[KERNEL_RETURN] = ERR_NO_EXIST;
			}
			break;
		case GETUID:
			if(kernel_buffer[1] == 0)
			{
				kernel_buffer[KERNEL_RETURN] = (int) current_ttyc()->uid;
			} else {
				kernel_buffer[KERNEL_RETURN] = (int) user_exists(kernel_buffer[1]);
			}
			break;
		case GETGID:
			if(kernel_buffer[1] == 0)
			{
				kernel_buffer[KERNEL_RETURN] = (int) user_gid(current_ttyc()->uid);
			} else {
				kernel_buffer[KERNEL_RETURN] = (int) user_gid(kernel_buffer[1]);
			}

			break;
		case MAKEUSER:
			kernel_buffer[KERNEL_RETURN] = user_create(kernel_buffer[1],
							kernel_buffer[2], user_gid(current_ttyc()->uid));
			break;
		case SETGID:
			kernel_buffer[KERNEL_RETURN] = user_setgid(kernel_buffer[1], 
													   kernel_buffer[2]);
			break;
		case UDELETE:
			kernel_buffer[KERNEL_RETURN] = user_delete(kernel_buffer[1]);
			break;
		case UEXISTS:
			kernel_buffer[KERNEL_RETURN] = user_exists(kernel_buffer[1]);
			break;
		case ULOGIN:
			kernel_buffer[KERNEL_RETURN] = user_login(kernel_buffer[1], 
													  kernel_buffer[2]);
			break;
		case ULOGOUT:
			kernel_buffer[KERNEL_RETURN] = user_logout();
			break;
		case CHOWN:
			kernel_buffer[KERNEL_RETURN] = fs_chown(kernel_buffer[1],
													kernel_buffer[2]);
			break;
		case CHMOD:
			kernel_buffer[KERNEL_RETURN] = fs_chmod(kernel_buffer[1],
												    kernel_buffer[2]);
			break;
		case GETOWN:
			kernel_buffer[KERNEL_RETURN] = fs_getown(kernel_buffer[1]);
			break;
		case GETMOD:
			kernel_buffer[KERNEL_RETURN] = fs_getmod(kernel_buffer[1]);
			break;
		case CP:
			kernel_buffer[KERNEL_RETURN] = fs_cp(kernel_buffer[1], kernel_buffer[2], current_ttyc()->pwd, current_ttyc()->pwd);
			break;
		case MV:
			kernel_buffer[KERNEL_RETURN] = fs_mv(kernel_buffer[1], kernel_buffer[2], current_ttyc()->pwd);
			break;
		case LINK:
			kernel_buffer[KERNEL_RETURN] = fs_open_link(kernel_buffer[1], kernel_buffer[2], current_ttyc()->pwd);
			break;
		case FSSTAT:
			kernel_buffer[KERNEL_RETURN] = fs_stat(kernel_buffer[1]);
			break;
		case SLEEP:
			kernel_buffer[KERNEL_RETURN] = scheduler_sleep(kernel_buffer[1]);
			break;
		default:
			break;
	}
	
	krn--;
}
Пример #9
0
static NTSTATUS close_normal_file(files_struct *fsp, enum file_close_type close_type)
{
	NTSTATUS status = NT_STATUS_OK;
	NTSTATUS saved_status1 = NT_STATUS_OK;
	NTSTATUS saved_status2 = NT_STATUS_OK;
	NTSTATUS saved_status3 = NT_STATUS_OK;
	connection_struct *conn = fsp->conn;

	if (fsp->aio_write_behind) {
		/*
	 	 * If we're finishing write behind on a close we can get a write
		 * error here, we must remember this.
		 */
		int ret = wait_for_aio_completion(fsp);
		if (ret) {
			saved_status1 = map_nt_error_from_unix(ret);
		}
	} else {
		cancel_aio_by_fsp(fsp);
	}
 
	/*
	 * If we're flushing on a close we can get a write
	 * error here, we must remember this.
	 */

	saved_status2 = close_filestruct(fsp);

	if (fsp->print_file) {
		print_fsp_end(fsp, close_type);
		file_free(fsp);
		return NT_STATUS_OK;
	}

	/* If this is an old DOS or FCB open and we have multiple opens on
	   the same handle we only have one share mode. Ensure we only remove
	   the share mode on the last close. */

	if (fsp->fh->ref_count == 1) {
		/* Should we return on error here... ? */
		saved_status3 = close_remove_share_mode(fsp, close_type);
	}

	if(fsp->oplock_type) {
		release_file_oplock(fsp);
	}

	locking_close_file(fsp);

	status = fd_close(conn, fsp);

	/* check for magic scripts */
	if (close_type == NORMAL_CLOSE) {
		check_magic(fsp,conn);
	}

	/*
	 * Ensure pending modtime is set after close.
	 */

	if (fsp->pending_modtime_owner && !null_timespec(fsp->pending_modtime)) {
		set_filetime(conn, fsp->fsp_name, fsp->pending_modtime);
	} else if (!null_timespec(fsp->last_write_time)) {
		set_filetime(conn, fsp->fsp_name, fsp->last_write_time);
	}

	if (NT_STATUS_IS_OK(status)) {
		if (!NT_STATUS_IS_OK(saved_status1)) {
			status = saved_status1;
		} else if (!NT_STATUS_IS_OK(saved_status2)) {
			status = saved_status2;
		} else if (!NT_STATUS_IS_OK(saved_status3)) {
			status = saved_status3;
		}
	}

	DEBUG(2,("%s closed file %s (numopen=%d) %s\n",
		conn->user,fsp->fsp_name,
		conn->num_files_open,
		nt_errstr(status) ));

	file_free(fsp);
	return status;
}
Пример #10
0
static int tag_release_generic(const char *user_path, struct fuse_file_info *fi)
{
    struct file_descriptor *fd = (struct file_descriptor*) fi->fh;
    return fd_close(fd);
}
Пример #11
0
static BOOL open_file(files_struct *fsp,connection_struct *conn,
		      const char *fname1,SMB_STRUCT_STAT *psbuf,int flags,mode_t mode, uint32 desired_access)
{
	extern struct current_user current_user;
	pstring fname;
	int accmode = (flags & O_ACCMODE);
	int local_flags = flags;

	fsp->fd = -1;
	fsp->oplock_type = NO_OPLOCK;
	errno = EPERM;

	pstrcpy(fname,fname1);

	/* Check permissions */

	/*
	 * This code was changed after seeing a client open request 
	 * containing the open mode of (DENY_WRITE/read-only) with
	 * the 'create if not exist' bit set. The previous code
	 * would fail to open the file read only on a read-only share
	 * as it was checking the flags parameter  directly against O_RDONLY,
	 * this was failing as the flags parameter was set to O_RDONLY|O_CREAT.
	 * JRA.
	 */

	if (!CAN_WRITE(conn)) {
		/* It's a read-only share - fail if we wanted to write. */
		if(accmode != O_RDONLY) {
			DEBUG(3,("Permission denied opening %s\n",fname));
			check_for_pipe(fname);
			return False;
		} else if(flags & O_CREAT) {
			/* We don't want to write - but we must make sure that O_CREAT
			   doesn't create the file if we have write access into the
			   directory.
			*/
			flags &= ~O_CREAT;
		}
	}

	/*
	 * This little piece of insanity is inspired by the
	 * fact that an NT client can open a file for O_RDONLY,
	 * but set the create disposition to FILE_EXISTS_TRUNCATE.
	 * If the client *can* write to the file, then it expects to
	 * truncate the file, even though it is opening for readonly.
	 * Quicken uses this stupid trick in backup file creation...
	 * Thanks *greatly* to "David W. Chapman Jr." <*****@*****.**>
	 * for helping track this one down. It didn't bite us in 2.0.x
	 * as we always opened files read-write in that release. JRA.
	 */

	if ((accmode == O_RDONLY) && ((flags & O_TRUNC) == O_TRUNC)) {
		DEBUG(10,("open_file: truncate requested on read-only open for file %s\n",fname ));
		local_flags = (flags & ~O_ACCMODE)|O_RDWR;
	}

	/* actually do the open */

	if ((desired_access & (FILE_READ_DATA|FILE_WRITE_DATA|FILE_APPEND_DATA|FILE_EXECUTE)) ||
			(local_flags & O_CREAT) || ((local_flags & O_TRUNC) == O_TRUNC) ) {

		/*
		 * We can't actually truncate here as the file may be locked.
		 * open_file_shared will take care of the truncate later. JRA.
		 */

		local_flags &= ~O_TRUNC;

#if defined(O_NONBLOCK) && defined(S_ISFIFO)
		/*
		 * We would block on opening a FIFO with no one else on the
		 * other end. Do what we used to do and add O_NONBLOCK to the
		 * open flags. JRA.
		 */

		if (VALID_STAT(*psbuf) && S_ISFIFO(psbuf->st_mode))
			local_flags |= O_NONBLOCK;
#endif
		fsp->fd = fd_open(conn, fname, local_flags, mode);

		if (fsp->fd == -1)  {
			DEBUG(3,("Error opening file %s (%s) (local_flags=%d) (flags=%d)\n",
				 fname,strerror(errno),local_flags,flags));
			check_for_pipe(fname);
			return False;
		}
	} else
		fsp->fd = -1; /* What we used to call a stat open. */

	if (!VALID_STAT(*psbuf)) {
		int ret;

		if (fsp->fd == -1)
			ret = vfs_stat(conn, fname, psbuf);
		else {
			ret = vfs_fstat(fsp,fsp->fd,psbuf);
			/* If we have an fd, this stat should succeed. */
			if (ret == -1)
				DEBUG(0,("Error doing fstat on open file %s (%s)\n", fname,strerror(errno) ));
		}

		/* For a non-io open, this stat failing means file not found. JRA */
		if (ret == -1) {
			fd_close(conn, fsp);
			return False;
		}
	}

	/*
	 * POSIX allows read-only opens of directories. We don't
	 * want to do this (we use a different code path for this)
	 * so catch a directory open and return an EISDIR. JRA.
	 */

	if(S_ISDIR(psbuf->st_mode)) {
		fd_close(conn, fsp);
		errno = EISDIR;
		return False;
	}

	fsp->mode = psbuf->st_mode;
	fsp->inode = psbuf->st_ino;
	fsp->dev = psbuf->st_dev;
	fsp->vuid = current_user.vuid;
	fsp->size = psbuf->st_size;
	fsp->pos = -1;
	fsp->can_lock = True;
	fsp->can_read = ((flags & O_WRONLY)==0);
	fsp->can_write = ((flags & (O_WRONLY|O_RDWR))!=0);
	fsp->share_mode = 0;
	fsp->desired_access = desired_access;
	fsp->print_file = False;
	fsp->modified = False;
	fsp->oplock_type = NO_OPLOCK;
	fsp->sent_oplock_break = NO_BREAK_SENT;
	fsp->is_directory = False;
	fsp->directory_delete_on_close = False;
	fsp->conn = conn;
	/*
	 * Note that the file name here is the *untranslated* name
	 * ie. it is still in the DOS codepage sent from the client.
	 * All use of this filename will pass though the sys_xxxx
	 * functions which will do the dos_to_unix translation before
	 * mapping into a UNIX filename. JRA.
	 */
	string_set(&fsp->fsp_name,fname);
	fsp->wbmpx_ptr = NULL;      
	fsp->wcp = NULL; /* Write cache pointer. */

	DEBUG(2,("%s opened file %s read=%s write=%s (numopen=%d)\n",
		 *current_user_info.smb_name ? current_user_info.smb_name : conn->user,fsp->fsp_name,
		 BOOLSTR(fsp->can_read), BOOLSTR(fsp->can_write),
		 conn->num_files_open + 1));

	return True;
}
Пример #12
0
/* irc logs.. */
void ircd_log(int flags, char *format, ...)
{
static int last_log_file_warning = 0;
static char recursion_trap=0;

	va_list ap;
	ConfigItem_log *logs;
	char buf[2048], timebuf[128];
	struct stat fstats;
	int written = 0, write_failure = 0;
	int n;

	/* Trap infinite recursions to avoid crash if log file is unavailable,
	 * this will also avoid calling ircd_log from anything else called
	 */
	if (recursion_trap == 1)
		return;

	recursion_trap = 1;
	va_start(ap, format);
	ircvsnprintf(buf, sizeof(buf), format, ap);
	va_end(ap);
	snprintf(timebuf, sizeof(timebuf), "[%s] - ", myctime(TStime()));

	RunHook3(HOOKTYPE_LOG, flags, timebuf, buf);
	strlcat(buf, "\n", sizeof(buf));

	if (!loop.ircd_forked && (flags & LOG_ERROR))
		fprintf(stderr, "%s", buf);

	for (logs = conf_log; logs; logs = (ConfigItem_log *) logs->next) {
#ifdef HAVE_SYSLOG
		if (!stricmp(logs->file, "syslog") && logs->flags & flags) {
			syslog(LOG_INFO, "%s", buf);
			written++;
			continue;
		}
#endif
		if (logs->flags & flags)
		{
			if (stat(logs->file, &fstats) != -1 && logs->maxsize && fstats.st_size >= logs->maxsize)
			{
				char oldlog[512];
				if (logs->logfd != -1)
				{
					write(logs->logfd, "Max file size reached, starting new log file\n", 45);
					fd_close(logs->logfd);
				}
				
				/* Rename log file to xxxxxx.old */
				snprintf(oldlog, sizeof(oldlog), "%s.old", logs->file);
				rename(logs->file, oldlog);
				
				logs->logfd = fd_fileopen(logs->file, O_CREAT|O_WRONLY|O_TRUNC);
				if (logs->logfd == -1)
					continue;
			}
			else if (logs->logfd == -1) {
#ifndef _WIN32
				logs->logfd = fd_fileopen(logs->file, O_CREAT|O_APPEND|O_WRONLY);
#else
				logs->logfd = fd_fileopen(logs->file, O_CREAT|O_APPEND|O_WRONLY);
#endif
				if (logs->logfd == -1)
				{
					if (!loop.ircd_booted)
					{
						config_status("WARNING: Unable to write to '%s': %s", logs->file, strerror(ERRNO));
					} else {
						if (last_log_file_warning + 300 < TStime())
						{
							config_status("WARNING: Unable to write to '%s': %s. This warning will not re-appear for at least 5 minutes.", logs->file, strerror(ERRNO));
							last_log_file_warning = TStime();
						}
					}
					write_failure = 1;
					continue;
				}
			}
			/* this shouldn't happen, but lets not waste unnecessary syscalls... */
			if (logs->logfd == -1)
				continue;
			write(logs->logfd, timebuf, strlen(timebuf));
			n = write(logs->logfd, buf, strlen(buf));
			if (n == strlen(buf))
			{
				written++;
			}
			else
			{
				if (!loop.ircd_booted)
				{
					config_status("WARNING: Unable to write to '%s': %s", logs->file, strerror(ERRNO));
				} else {
					if (last_log_file_warning + 300 < TStime())
					{
						config_status("WARNING: Unable to write to '%s': %s. This warning will not re-appear for at least 5 minutes.", logs->file, strerror(ERRNO));
						last_log_file_warning = TStime();
					}
				}

				write_failure = 1;
			}
#ifndef _WIN32
			fsync(logs->logfd);
#endif
		}
	}

	recursion_trap = 0;
}
Пример #13
0
int
wisvc_Handle_I_and_J_options (int argc, char **argv,
			      char *s, int i, int autostart)
{
  int called_as_service = 0;
  size_t path_len;
  int start_now = 0;
  char *service_name = (*(s + 2) ? (s + 2) : WISVC_DEFAULT_SERVICE_NAME);
  char *progname = argv[0];
  char *last_of_path, *cutpnt;
  char BinaryPathName[(MAX_BINARY_PATH) + 10];

/*
   if(i > 1)
   {
   err_printf((
   "%s: If you give %s option, it MUST be the first argument on command line!",
   progname,s));
   kubl_main_exit(1);
   }
 */

/* Then construct absolute path to this binary executable
   by combining working directory path got with getcwd
   with the program name got from argv[0].
   Note that the program name itself can be relative or absolute path.
   getcwd returns a string that represents the path of
   the current working directory. If the current working
   directory is the root, the string ends with a backslash (\).
   If the current working directory is a directory
   other than the root, the string ends with the directory
   name and not with a backslash.
   Note that absolute paths with upward parts (..)
   like the one below seem to work equally well, so
   we do not need to worry about .. :s and .:s in any
   special way.
   D:\inetpub\wwwroot\..\..\ic\.\diskit\wi\windebug\wi.exe
 */

  if (is_abs_path (progname))
    {
      strncpy (BinaryPathName, progname, (MAX_BINARY_PATH));
    }
  else
    /* We have to combine pwd + relative starting path */
    {
      if (NULL == getcwd (BinaryPathName, _MAX_PATH))
	{
	  err_printf (("%s: Cannot getcwd because: %s",
		       progname, strerror (errno)));
	  exit (1);
	}
      path_len = strlen (BinaryPathName);
      last_of_path = (BinaryPathName + path_len - 1);
      if ((0 == path_len) || !is_abs_path (last_of_path))
	{			/* Add the missing path separator between if needed */
	  strncat_ck (BinaryPathName, "\\", (MAX_BINARY_PATH));
	}
      /* And then the progname itself. */
      strncat_ck (BinaryPathName, progname, (MAX_BINARY_PATH));
    }

  /* Add our own special .eXe extension to the program name, so that
     when service is started, the code in main can see from argv[0]
     that it was started as a service, not as an ordinary command
     line program.
   */
  strncat_ck (BinaryPathName, WISVC_EXE_EXTENSION_FOR_SERVICE, (MAX_BINARY_PATH));

  /* Do chdir to the same directory where the executable is, needed
     because of wi.cfg check soon performed. */
  if ((NULL != (cutpnt = strrchr (BinaryPathName, '\\'))))
    {				/* Search the last backslash. */
      unsigned char
        save_the_following_char = *(((unsigned char *) cutpnt) + 1);
      *(cutpnt + 1) = '\0';

      if (chdir (BinaryPathName))	/* Is not zero, i.e. -1, an error. */
	{			/* However, we do not exit yet. */
	  err_printf (("%s: Cannot chdir to \"%s\" because: %s",
		       argv[0], BinaryPathName, strerror (errno)));
	  exit (1);
	}

      *(((unsigned char *) cutpnt) + 1) = save_the_following_char;
    }


/* Add all command line arguments after the absolute program name
   itself, separated by spaces. The started service will see them
   in the elements of argv vector, in the normal way, that is
   argv[0] will contain just the absolute program name which ends with
   .eXe and arguments are in argv[1], argv[2], etc.

   Check also for options -S (start the service), and -W change working
   directory. The latter would not be actually necessary to do here,
   but, if the directory is invalid, then it is much more friendly
   to give an error message here, than let the service itself fail,
   and hide the same error message to god knows which log file.
   Check that the user does not try to give options -D, -U, -R or -d
   to the service to be installed.

 */

  for (i = 1; i < argc; i++)
    {
      s = argv[i];
      if ('-' == s[0])
	{
	  switch (s[1])
	    {			/* With -S ignore the possibility that a different service
				   name could be specified after it than after -I or -J
				   DON'T ADD OPTIONS -S, -I or -J to BinaryPathName, as
				   they would be ignored anyway in service. */
	    case 'S':
	      {
		start_now = 1;
		continue;
	      }
	    case 'I':
	    case 'J':
	      {
		continue;
	      }
	    case 'W':
	      {
		int stat
		= wisvc_Handle_W_option (argc, argv, s, &i, called_as_service);
		if (stat)
		  {
		    kubl_main_exit (stat);
		  }
		break;
	      }
	    case 'D':
	    case 'U':		/* case 'R': */
	    case 'd':
	      {
		err_printf ((
			      "%s: Sorry, the option %s can be used only from command line, not in service!\n",
			      argv[0], s));
		exit (1);
	      }
	    }
	}

      strncat_ck (BinaryPathName, " ", (MAX_BINARY_PATH));
      strncat_ck (BinaryPathName, argv[i], (MAX_BINARY_PATH));
    }

  {				/* Check already HERE that there is a config file in the final
				   working directory, for the same user-friendly reason as
				   checking the validity of -W option's argument. */
    int fd = open (CFG_FILE, O_RDWR);
    if (fd < 0)
      {
	err_printf ((
		      "There must be a %s file in the server's working directory. Exiting.\n",
		      CFG_FILE));
	exit (-1);
      }
    fd_close (fd, NULL);	/* Defined in widisk.h */
  }

  wisvc_CreateKublService (argc, argv, service_name, BinaryPathName,
			   autostart, start_now);

  return (0);
}
Пример #14
0
/**
 * Listen for events on a file descriptor
 *
 * @param fd     File descriptor
 * @param flags  Wanted event flags
 * @param fh     Event handler
 * @param arg    Handler argument
 *
 * @return 0 if success, otherwise errorcode
 */
int fd_listen(int fd, int flags, fd_h *fh, void *arg)
{
	struct re *re = re_get();
	int err = 0;

	DEBUG_INFO("fd_listen: fd=%d flags=0x%02x\n", fd, flags);

	if (fd < 0) {
		DEBUG_WARNING("fd_listen: corrupt fd %d\n", fd);
		return EBADF;
	}

	if (flags || fh) {
		err = poll_setup(re);
		if (err)
			return err;
	}

	if (fd >= re->maxfds) {
		if (flags) {
			DEBUG_WARNING("fd_listen: fd=%d flags=0x%02x"
				      " - Max %d fds\n",
				      fd, flags, re->maxfds);
		}
		return EMFILE;
	}

	/* Update fh set */
	if (re->fhs) {
		re->fhs[fd].flags = flags;
		re->fhs[fd].fh    = fh;
		re->fhs[fd].arg   = arg;
	}

	re->nfds = max(re->nfds, fd+1);

	switch (re->method) {

#ifdef HAVE_POLL
	case METHOD_POLL:
		err = set_poll_fds(re, fd, flags);
		break;
#endif

#ifdef HAVE_EPOLL
	case METHOD_EPOLL:
		if (re->epfd <= 0)
			return EBADFD;
		err = set_epoll_fds(re, fd, flags);
		break;
#endif
	default:
		break;
	}

	if (err) {
		if (flags && fh) {
			fd_close(fd);
			DEBUG_WARNING("fd_listen: fd=%d flags=0x%02x (%m)\n",
				      fd, flags, err);
		}
	}

	return err;
}
Пример #15
0
/*!
 * @brief セーブデータ書き込みのサブルーチン /
 * Medium level player saver
 * @return 成功すればtrue
 * @details
 * XXX XXX XXX Angband 2.8.0 will use "fd" instead of "fff" if possible
 */
static bool save_player_aux(char *name)
{
	bool    ok = FALSE;

	int             fd = -1;

	int             mode = 0644;


	/* No file yet */
	fff = NULL;


	/* File type is "SAVE" */
	FILE_TYPE(FILE_TYPE_SAVE);


	/* Grab permissions */
	safe_setuid_grab();

	/* Create the savefile */
	fd = fd_make(name, mode);

	/* Drop permissions */
	safe_setuid_drop();

	/* File is okay */
	if (fd >= 0)
	{
		/* Close the "fd" */
		(void)fd_close(fd);

		/* Grab permissions */
		safe_setuid_grab();

		/* Open the savefile */
		fff = my_fopen(name, "wb");

		/* Drop permissions */
		safe_setuid_drop();

		/* Successful open */
		if (fff)
		{
			/* Write the savefile */
			if (wr_savefile_new()) ok = TRUE;

			/* Attempt to close it */
			if (my_fclose(fff)) ok = FALSE;
		}

		/* Grab permissions */
		safe_setuid_grab();

		/* Remove "broken" files */
		if (!ok) (void)fd_kill(name);

		/* Drop permissions */
		safe_setuid_drop();
	}


	/* Failure */
	if (!ok) return (FALSE);

	counts_write(0, playtime);

	/* Successful save */
	character_saved = TRUE;

	/* Success */
	return (TRUE);
}
Пример #16
0
static NTSTATUS close_directory(struct smb_request *req, files_struct *fsp,
				enum file_close_type close_type)
{
	struct server_id self = messaging_server_id(fsp->conn->sconn->msg_ctx);
	struct share_mode_lock *lck = NULL;
	bool delete_dir = False;
	NTSTATUS status = NT_STATUS_OK;
	NTSTATUS status1 = NT_STATUS_OK;
	const struct security_token *del_nt_token = NULL;
	const struct security_unix_token *del_token = NULL;
	NTSTATUS notify_status;

	if (fsp->conn->sconn->using_smb2) {
		notify_status = STATUS_NOTIFY_CLEANUP;
	} else {
		notify_status = NT_STATUS_OK;
	}

	/*
	 * NT can set delete_on_close of the last open
	 * reference to a directory also.
	 */

	lck = get_existing_share_mode_lock(talloc_tos(), fsp->file_id);
	if (lck == NULL) {
		DEBUG(0, ("close_directory: Could not get share mode lock for "
			  "%s\n", fsp_str_dbg(fsp)));
		return NT_STATUS_INVALID_PARAMETER;
	}

	if (fsp->initial_delete_on_close) {
		bool became_user = False;

		/* Initial delete on close was set - for
		 * directories we don't care if anyone else
		 * wrote a real delete on close. */

		if (get_current_vuid(fsp->conn) != fsp->vuid) {
			become_user(fsp->conn, fsp->vuid);
			became_user = True;
		}
		send_stat_cache_delete_message(fsp->conn->sconn->msg_ctx,
					       fsp->fsp_name->base_name);
		set_delete_on_close_lck(fsp, lck,
				get_current_nttok(fsp->conn),
				get_current_utok(fsp->conn));
		fsp->delete_on_close = true;
		if (became_user) {
			unbecome_user();
		}
	}

	delete_dir = get_delete_on_close_token(lck, fsp->name_hash,
					&del_nt_token, &del_token);

	if (delete_dir) {
		int i;
		/* See if others still have the dir open. If this is the
		 * case, then don't delete. If all opens are POSIX delete now. */
		for (i=0; i<lck->data->num_share_modes; i++) {
			struct share_mode_entry *e = &lck->data->share_modes[i];
			if (is_valid_share_mode_entry(e) &&
					e->name_hash == fsp->name_hash) {
				if ((fsp->posix_flags & FSP_POSIX_FLAGS_OPEN) &&
				    (e->flags & SHARE_MODE_FLAG_POSIX_OPEN))
				{
					continue;
				}
				if (serverid_equal(&self, &e->pid) &&
				    (e->share_file_id == fsp->fh->gen_id)) {
					continue;
				}
				if (share_mode_stale_pid(lck->data, i)) {
					continue;
				}
				delete_dir = False;
				break;
			}
		}
	}

	if ((close_type == NORMAL_CLOSE || close_type == SHUTDOWN_CLOSE) &&
				delete_dir) {
	
		/* Become the user who requested the delete. */

		if (!push_sec_ctx()) {
			smb_panic("close_directory: failed to push sec_ctx.\n");
		}

		set_sec_ctx(del_token->uid,
				del_token->gid,
				del_token->ngroups,
				del_token->groups,
				del_nt_token);

		if (!del_share_mode(lck, fsp)) {
			DEBUG(0, ("close_directory: Could not delete share entry for "
				  "%s\n", fsp_str_dbg(fsp)));
		}

		TALLOC_FREE(lck);

		if ((fsp->conn->fs_capabilities & FILE_NAMED_STREAMS)
		    && !is_ntfs_stream_smb_fname(fsp->fsp_name)) {

			status = delete_all_streams(fsp->conn, fsp->fsp_name->base_name);
			if (!NT_STATUS_IS_OK(status)) {
				DEBUG(5, ("delete_all_streams failed: %s\n",
					  nt_errstr(status)));
				return status;
			}
		}

		status = rmdir_internals(talloc_tos(), fsp);

		DEBUG(5,("close_directory: %s. Delete on close was set - "
			 "deleting directory returned %s.\n",
			 fsp_str_dbg(fsp), nt_errstr(status)));

		/* unbecome user. */
		pop_sec_ctx();

		/*
		 * Ensure we remove any change notify requests that would
		 * now fail as the directory has been deleted.
		 */

		if (NT_STATUS_IS_OK(status)) {
			notify_status = NT_STATUS_DELETE_PENDING;
		}
	} else {
		if (!del_share_mode(lck, fsp)) {
			DEBUG(0, ("close_directory: Could not delete share entry for "
				  "%s\n", fsp_str_dbg(fsp)));
		}

		TALLOC_FREE(lck);
	}

	remove_pending_change_notify_requests_by_fid(fsp, notify_status);

	status1 = fd_close(fsp);

	if (!NT_STATUS_IS_OK(status1)) {
		DEBUG(0, ("Could not close dir! fname=%s, fd=%d, err=%d=%s\n",
			  fsp_str_dbg(fsp), fsp->fh->fd, errno,
			  strerror(errno)));
	}

	/*
	 * Do the code common to files and directories.
	 */
	close_filestruct(fsp);
	file_free(req, fsp);

	if (NT_STATUS_IS_OK(status) && !NT_STATUS_IS_OK(status1)) {
		status = status1;
	}
	return status;
}
Пример #17
0
static NTSTATUS close_normal_file(struct smb_request *req, files_struct *fsp,
				  enum file_close_type close_type)
{
	NTSTATUS status = NT_STATUS_OK;
	NTSTATUS tmp;
	connection_struct *conn = fsp->conn;
	bool is_durable = false;

	if (fsp->num_aio_requests != 0) {

		if (close_type != SHUTDOWN_CLOSE) {
			/*
			 * reply_close and the smb2 close must have
			 * taken care of this. No other callers of
			 * close_file should ever have created async
			 * I/O.
			 *
			 * We need to panic here because if we close()
			 * the fd while we have outstanding async I/O
			 * requests, in the worst case we could end up
			 * writing to the wrong file.
			 */
			DEBUG(0, ("fsp->num_aio_requests=%u\n",
				  fsp->num_aio_requests));
			smb_panic("can not close with outstanding aio "
				  "requests");
		}

		/*
		 * For shutdown close, just drop the async requests
		 * including a potential close request pending for
		 * this fsp. Drop the close request first, the
		 * destructor for the aio_requests would execute it.
		 */
		TALLOC_FREE(fsp->deferred_close);

		while (fsp->num_aio_requests != 0) {
			/*
			 * The destructor of the req will remove
			 * itself from the fsp.
			 * Don't use TALLOC_FREE here, this will overwrite
			 * what the destructor just wrote into
			 * aio_requests[0].
			 */
			talloc_free(fsp->aio_requests[0]);
		}
	}

	/*
	 * If we're flushing on a close we can get a write
	 * error here, we must remember this.
	 */

	tmp = close_filestruct(fsp);
	status = ntstatus_keeperror(status, tmp);

	if (NT_STATUS_IS_OK(status) && fsp->op != NULL) {
		is_durable = fsp->op->global->durable;
	}

	if (close_type != SHUTDOWN_CLOSE) {
		is_durable = false;
	}

	if (is_durable) {
		DATA_BLOB new_cookie = data_blob_null;

		tmp = SMB_VFS_DURABLE_DISCONNECT(fsp,
					fsp->op->global->backend_cookie,
					fsp->op,
					&new_cookie);
		if (NT_STATUS_IS_OK(tmp)) {
			struct timeval tv;
			NTTIME now;

			if (req != NULL) {
				tv = req->request_time;
			} else {
				tv = timeval_current();
			}
			now = timeval_to_nttime(&tv);

			data_blob_free(&fsp->op->global->backend_cookie);
			fsp->op->global->backend_cookie = new_cookie;

			fsp->op->compat = NULL;
			tmp = smbXsrv_open_close(fsp->op, now);
			if (!NT_STATUS_IS_OK(tmp)) {
				DEBUG(1, ("Failed to update smbXsrv_open "
					  "record when disconnecting durable "
					  "handle for file %s: %s - "
					  "proceeding with normal close\n",
					  fsp_str_dbg(fsp), nt_errstr(tmp)));
			}
			scavenger_schedule_disconnected(fsp);
		} else {
			DEBUG(1, ("Failed to disconnect durable handle for "
				  "file %s: %s - proceeding with normal "
				  "close\n", fsp_str_dbg(fsp), nt_errstr(tmp)));
		}
		if (!NT_STATUS_IS_OK(tmp)) {
			is_durable = false;
		}
	}

	if (is_durable) {
		/*
		 * This is the case where we successfully disconnected
		 * a durable handle and closed the underlying file.
		 * In all other cases, we proceed with a genuine close.
		 */
		DEBUG(10, ("%s disconnected durable handle for file %s\n",
			   conn->session_info->unix_info->unix_name,
			   fsp_str_dbg(fsp)));
		file_free(req, fsp);
		return NT_STATUS_OK;
	}

	if (fsp->op != NULL) {
		/*
		 * Make sure the handle is not marked as durable anymore
		 */
		fsp->op->global->durable = false;
	}

	if (fsp->print_file) {
		/* FIXME: return spool errors */
		print_spool_end(fsp, close_type);
		file_free(req, fsp);
		return NT_STATUS_OK;
	}

	/* Remove the oplock before potentially deleting the file. */
	if(fsp->oplock_type) {
		remove_oplock(fsp);
	}

	/* If this is an old DOS or FCB open and we have multiple opens on
	   the same handle we only have one share mode. Ensure we only remove
	   the share mode on the last close. */

	if (fsp->fh->ref_count == 1) {
		/* Should we return on error here... ? */
		tmp = close_remove_share_mode(fsp, close_type);
		status = ntstatus_keeperror(status, tmp);
	}

	locking_close_file(conn->sconn->msg_ctx, fsp, close_type);

	tmp = fd_close(fsp);
	status = ntstatus_keeperror(status, tmp);

	/* check for magic scripts */
	if (close_type == NORMAL_CLOSE) {
		tmp = check_magic(fsp);
		status = ntstatus_keeperror(status, tmp);
	}

	/*
	 * Ensure pending modtime is set after close.
	 */

	tmp = update_write_time_on_close(fsp);
	if (NT_STATUS_EQUAL(tmp, NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
		/* Someone renamed the file or a parent directory containing
		 * this file. We can't do anything about this, we don't have
		 * an "update timestamp by fd" call in POSIX. Eat the error. */

		tmp = NT_STATUS_OK;
	}

	status = ntstatus_keeperror(status, tmp);

	DEBUG(2,("%s closed file %s (numopen=%d) %s\n",
		conn->session_info->unix_info->unix_name, fsp_str_dbg(fsp),
		conn->num_files_open - 1,
		nt_errstr(status) ));

	file_free(req, fsp);
	return status;
}
Пример #18
0
static NTSTATUS close_normal_file(struct smb_request *req, files_struct *fsp,
				  enum file_close_type close_type)
{
	NTSTATUS status = NT_STATUS_OK;
	NTSTATUS tmp;
	connection_struct *conn = fsp->conn;

	if (close_type == ERROR_CLOSE) {
		cancel_aio_by_fsp(fsp);
	} else {
		/*
	 	 * If we're finishing async io on a close we can get a write
		 * error here, we must remember this.
		 */
		int ret = wait_for_aio_completion(fsp);
		if (ret) {
			status = ntstatus_keeperror(
				status, map_nt_error_from_unix(ret));
		}
	}

	/*
	 * If we're flushing on a close we can get a write
	 * error here, we must remember this.
	 */

	tmp = close_filestruct(fsp);
	status = ntstatus_keeperror(status, tmp);

	if (fsp->print_file) {
		/* FIXME: return spool errors */
		print_spool_end(fsp, close_type);
		file_free(req, fsp);
		return NT_STATUS_OK;
	}

	/* Remove the oplock before potentially deleting the file. */
	if(fsp->oplock_type) {
		release_file_oplock(fsp);
	}

	/* If this is an old DOS or FCB open and we have multiple opens on
	   the same handle we only have one share mode. Ensure we only remove
	   the share mode on the last close. */

	if (fsp->fh->ref_count == 1) {
		/* Should we return on error here... ? */
		tmp = close_remove_share_mode(fsp, close_type);
		status = ntstatus_keeperror(status, tmp);
	}

	locking_close_file(conn->sconn->msg_ctx, fsp, close_type);

	tmp = fd_close(fsp);
	status = ntstatus_keeperror(status, tmp);

	/* check for magic scripts */
	if (close_type == NORMAL_CLOSE) {
		tmp = check_magic(fsp);
		status = ntstatus_keeperror(status, tmp);
	}

	/*
	 * Ensure pending modtime is set after close.
	 */

	tmp = update_write_time_on_close(fsp);
	if (NT_STATUS_EQUAL(tmp, NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
		/* Someone renamed the file or a parent directory containing
		 * this file. We can't do anything about this, we don't have
		 * an "update timestamp by fd" call in POSIX. Eat the error. */

		tmp = NT_STATUS_OK;
	}

	status = ntstatus_keeperror(status, tmp);

	DEBUG(2,("%s closed file %s (numopen=%d) %s\n",
		conn->session_info->unix_info->unix_name, fsp_str_dbg(fsp),
		conn->num_files_open - 1,
		nt_errstr(status) ));

	file_free(req, fsp);
	return status;
}
Пример #19
0
/**
 * Handler for incoming TCP connections.
 *
 * @param flags  Event flags.
 * @param arg    Handler argument.
 */
static void tcp_conn_handler(int flags, void *arg)
{
	struct sa peer;
	struct tcp_sock *ts = arg;
	int err;

	(void)flags;

	sa_init(&peer, AF_UNSPEC);

	if (ts->fdc >= 0)
		(void)close(ts->fdc);

	ts->fdc = SOK_CAST accept(ts->fd, &peer.u.sa, &peer.len);
	if (-1 == ts->fdc) {

#if TARGET_OS_IPHONE
		if (EAGAIN == errno) {

			struct tcp_sock *ts_new;
			struct sa laddr;

			err = tcp_sock_local_get(ts, &laddr);
			if (err)
				return;

			if (ts->fd >= 0) {
				fd_close(ts->fd);
				(void)close(ts->fd);
				ts->fd = -1;
			}

			err = tcp_listen(&ts_new, &laddr, NULL, NULL);
			if (err)
				return;

			ts->fd = ts_new->fd;
			ts_new->fd = -1;

			mem_deref(ts_new);

			fd_listen(ts->fd, FD_READ, tcp_conn_handler, ts);
		}
#endif

		return;
	}

	err = net_sockopt_blocking_set(ts->fdc, false);
	if (err) {
		DEBUG_WARNING("conn handler: nonblock set: %m\n", err);
		(void)close(ts->fdc);
		ts->fdc = -1;
		return;
	}

	tcp_sockopt_set(ts->fdc);

	if (ts->connh)
		ts->connh(&peer, ts->arg);
}
Пример #20
0
void skaclientin_end (skaclientin_t_ref in)
{
  fd_close(in->b.fd) ;
  skaclientin_free(in) ;
}
Пример #21
0
/*!
 * @brief ゲームプレイ中のフロア一時保存出力処理メインルーチン / Attempt to save the temporally saved-floor data
 * @param sf_ptr 保存フロア参照ポインタ
 * @param mode 保存オプション
 * @return なし
 */
bool save_floor(saved_floor_type *sf_ptr, u32b mode)
{
	FILE *old_fff = NULL;
	byte old_xor_byte = 0;
	u32b old_v_stamp = 0;
	u32b old_x_stamp = 0;

	char floor_savefile[1024];
	int fd = -1;
	bool ok = FALSE;

	if (!(mode & SLF_SECOND))
	{
#ifdef SET_UID
# ifdef SECURE
		/* Get "games" permissions */
		beGames();
# endif
#endif
	}

	/* We have one file already opened */
	else
	{
		/* Backup original values */
		old_fff = fff;
		old_xor_byte = xor_byte;
		old_v_stamp = v_stamp;
		old_x_stamp = x_stamp;
	}

	/* New savefile */
	sprintf(floor_savefile, "%s.F%02d", savefile, (int)sf_ptr->savefile_id);

	/* Grab permissions */
	safe_setuid_grab();

	/* Remove it */
	fd_kill(floor_savefile);

	/* Drop permissions */
	safe_setuid_drop();


	/* Attempt to save the player */

	/* No file yet */
	fff = NULL;

	/* File type is "SAVE" */
	FILE_TYPE(FILE_TYPE_SAVE);

	/* Grab permissions */
	safe_setuid_grab();

	/* Create the savefile */
	fd = fd_make(floor_savefile, 0644);

	/* Drop permissions */
	safe_setuid_drop();

	/* File is okay */
	if (fd >= 0)
	{
		/* Close the "fd" */
		(void)fd_close(fd);

		/* Grab permissions */
		safe_setuid_grab();

		/* Open the savefile */
		fff = my_fopen(floor_savefile, "wb");

		/* Drop permissions */
		safe_setuid_drop();

		/* Successful open */
		if (fff)
		{
			/* Write the savefile */
			if (save_floor_aux(sf_ptr)) ok = TRUE;

			/* Attempt to close it */
			if (my_fclose(fff)) ok = FALSE;
		}

		/* Remove "broken" files */
		if (!ok)
		{
			/* Grab permissions */
			safe_setuid_grab();

			(void)fd_kill(floor_savefile);

			/* Drop permissions */
			safe_setuid_drop();
		}
	}

	if (!(mode & SLF_SECOND))
	{
#ifdef SET_UID
# ifdef SECURE
		/* Drop "games" permissions */
		bePlayer();
# endif
#endif
	}

	/* We have one file already opened */
	else
	{
		/* Restore original values */
		fff = old_fff;
		xor_byte = old_xor_byte;
		v_stamp = old_v_stamp;
		x_stamp = old_x_stamp;
	}

	/* Return the result */
	return ok;
}
Пример #22
0
/*!
 * @brief セーブデータ読み込みのメインルーチン /
 * Attempt to Load a "savefile"
 * @return 成功すればtrue
 * @details
 * <pre>
 * Version 2.7.0 introduced a slightly different "savefile" format from
 * older versions, requiring a completely different parsing method.
 *
 * Note that savefiles from 2.7.0 - 2.7.2 are completely obsolete.
 *
 * Pre-2.8.0 savefiles lose some data, see "load2.c" for info.
 *
 * Pre-2.7.0 savefiles lose a lot of things, see "load1.c" for info.
 *
 * On multi-user systems, you may only "read" a savefile if you will be
 * allowed to "write" it later, this prevents painful situations in which
 * the player loads a savefile belonging to someone else, and then is not
 * allowed to save his game when he quits.
 *
 * We return "TRUE" if the savefile was usable, and we set the global
 * flag "character_loaded" if a real, living, character was loaded.
 *
 * Note that we always try to load the "current" savefile, even if
 * there is no such file, so we must check for "empty" savefile names.
 * </pre>
 */
bool load_player(void)
{
	int             fd = -1;

	errr    err = 0;

	byte    vvv[4];

#ifdef VERIFY_TIMESTAMP
	struct stat     statbuf;
#endif

	cptr    what = "generic";


	/* Paranoia */
	turn = 0;

	/* Paranoia */
	p_ptr->is_dead = FALSE;


	/* Allow empty savefile name */
	if (!savefile[0]) return (TRUE);


#if !defined(MACINTOSH) && !defined(WINDOWS) && !defined(VM)

	/* XXX XXX XXX Fix this */

	/* Verify the existance of the savefile */
	if (access(savefile, 0) < 0)
	{
		/* Give a message */
		msg_print(_("セーブファイルがありません。", "Savefile does not exist."));

		msg_print(NULL);

		/* Allow this */
		return (TRUE);
	}

#endif


#ifdef VERIFY_SAVEFILE

	/* Verify savefile usage */
	if (!err)
	{
		FILE *fkk;

		char temp[1024];

		/* Extract name of lock file */
		strcpy(temp, savefile);
		strcat(temp, ".lok");

		/* Check for lock */
		fkk = my_fopen(temp, "r");

		/* Oops, lock exists */
		if (fkk)
		{
			/* Close the file */
			my_fclose(fkk);

			/* Message */
			msg_print(_("セーブファイルは現在使用中です。", "Savefile is currently in use."));
			msg_print(NULL);

			/* Oops */
			return (FALSE);
		}

		/* Create a lock file */
		fkk = my_fopen(temp, "w");

		/* Dump a line of info */
		fprintf(fkk, "Lock file for savefile '%s'\n", savefile);

		/* Close the lock file */
		my_fclose(fkk);
	}

#endif


	/* Okay */
	if (!err)
	{
		/* Open the savefile */
		fd = fd_open(savefile, O_RDONLY);

		/* No file */
		if (fd < 0) err = -1;

		/* Message (below) */
		if (err) what = _("セーブファイルを開けません。", "Cannot open savefile");
	}

	/* Process file */
	if (!err)
	{

#ifdef VERIFY_TIMESTAMP
		/* Get the timestamp */
		(void)fstat(fd, &statbuf);
#endif

		/* Read the first four bytes */
		if (fd_read(fd, (char*)(vvv), 4)) err = -1;

		/* What */
		if (err) what = _("セーブファイルを読めません。", "Cannot read savefile");

		/* Close the file */
		(void)fd_close(fd);
	}

	/* Process file */
	if (!err)
	{

		/* Extract version */
		z_major = vvv[0];
		z_minor = vvv[1];
		z_patch = vvv[2];
		sf_extra = vvv[3];


		/* Clear screen */
		Term_clear();

		/* Attempt to load */
		err = rd_savefile_new();

		/* Message (below) */
		if (err) what = _("セーブファイルを解析出来ません。", "Cannot parse savefile");
	}

	/* Paranoia */
	if (!err)
	{
		/* Invalid turn */
		if (!turn) err = -1;

		/* Message (below) */
		if (err) what = _("セーブファイルが壊れています", "Broken savefile");
	}

#ifdef VERIFY_TIMESTAMP
	/* Verify timestamp */
	if (!err && !arg_wizard)
	{
		/* Hack -- Verify the timestamp */
		if (sf_when > (statbuf.st_ctime + 100) ||
		    sf_when < (statbuf.st_ctime - 100))
		{
			/* Message */
			what = _("無効なタイム・スタンプです", "Invalid timestamp");

			/* Oops */
			err = -1;
		}
	}
#endif


	/* Okay */
	if (!err)
	{
		/* Give a conversion warning */
		if ((FAKE_VER_MAJOR != z_major) ||
		    (FAKE_VER_MINOR != z_minor) ||
		    (FAKE_VER_PATCH != z_patch))
		{
			if (z_major == 2 && z_minor == 0 && z_patch == 6)
			{
				msg_print(_("バージョン 2.0.* 用のセーブファイルを変換しました。", "Converted a 2.0.* savefile."));
			}
			else
			{
				/* Message */
#ifdef JP
				msg_format("バージョン %d.%d.%d 用のセーブ・ファイルを変換しました。",
				    (z_major > 9) ? z_major-10 : z_major , z_minor, z_patch);
#else
				msg_format("Converted a %d.%d.%d savefile.",
				    (z_major > 9) ? z_major-10 : z_major , z_minor, z_patch);
#endif
			}
			msg_print(NULL);
		}

		/* Player is dead */
		if (p_ptr->is_dead)
		{
			/* Cheat death */
			if (arg_wizard)
			{
				/* A character was loaded */
				character_loaded = TRUE;

				/* Done */
				return (TRUE);
			}

			/* Player is no longer "dead" */
			p_ptr->is_dead = FALSE;

			/* Count lives */
			sf_lives++;

			/* Done */
			return (TRUE);
		}

		/* A character was loaded */
		character_loaded = TRUE;

		{
			u32b tmp = counts_read(2);
			if (tmp > p_ptr->count)
				p_ptr->count = tmp;
			if (counts_read(0) > playtime || counts_read(1) == playtime)
				counts_write(2, ++p_ptr->count);
			counts_write(1, playtime);
		}

		/* Success */
		return (TRUE);
	}


#ifdef VERIFY_SAVEFILE

	/* Verify savefile usage */
	if (TRUE)
	{
		char temp[1024];

		/* Extract name of lock file */
		strcpy(temp, savefile);
		strcat(temp, ".lok");

		/* Remove lock */
		fd_kill(temp);
	}

#endif


	/* Message */
#ifdef JP
	msg_format("エラー(%s)がバージョン%d.%d.%d 用セーブファイル読み込中に発生。",
		   what, (z_major>9) ? z_major - 10 : z_major, z_minor, z_patch);
#else
	msg_format("Error (%s) reading %d.%d.%d savefile.",
		   what, (z_major>9) ? z_major - 10 : z_major, z_minor, z_patch);
#endif
	msg_print(NULL);

	/* Oops */
	return (FALSE);
}
Пример #23
0
static void f_ultraparse( INT32 args )
{
  FD f = -1;
  int lines=0, cls, c=0, my_fd=1, tzs=0, state=0, next;
  unsigned char *char_pointer=0;
  /* array with offsets for fields in the string buffer */
  int buf_points[16];
  INT32 v=0, offs0=0, len=0, bytes=0, gotdate=0;
  INT32 last_hour=0, last_date=0, last_year=0, last_month=0,
    this_date=0, broken_lines=0, tmpinteger=0, field_position=0;
  time_t start;
  unsigned char *read_buf;
  struct svalue *statfun, *daily, *pagexts=0, *file,  *refsval, *log_format;
  unsigned char *buf;
  char *field_buf;
#ifdef BROKEN_LINE_DEBUG
  INT32 broken_line_pos=0;
  unsigned char *broken_line;
#endif
  INT32 *state_list, *save_field_num, *field_endings, num_states;

  char *notref = 0;
  INT32 state_pos=0, bufpos=0, i, fieldnum=0;
  struct pike_string *url_str = 0,  *ref_str = 0, *rfc_str = 0, *hst_str = 0, *tmpagent = 0;
  struct svalue *url_sval;
  ONERROR unwind_protect;
  unsigned INT32 hits_per_hour[24];
  unsigned INT32 hosts_per_hour[24];
  unsigned INT32 pages_per_hour[24];
  unsigned INT32 sessions_per_hour[24];
  double kb_per_hour[24];
  unsigned INT32 session_length[24];
  /*  struct mapping *unique_per_hour  = allocate_mapping(1);*/
  struct mapping *hits_per_error  = allocate_mapping(10);
  struct mapping *error_urls      = allocate_mapping(10);
  struct mapping *error_refs      = allocate_mapping(10);
  struct mapping *user_agents     = allocate_mapping(10);
  struct mapping *directories     = allocate_mapping(20);
  struct mapping *referrers       = allocate_mapping(1);
  struct mapping *refsites        = allocate_mapping(1);
  struct mapping *referredto      = allocate_mapping(1);
  struct mapping *pages           = allocate_mapping(1);
  struct mapping *hosts           = allocate_mapping(1);
  struct mapping *hits            = allocate_mapping(1);
  struct mapping *session_start   = allocate_mapping(1);
  struct mapping *session_end     = allocate_mapping(1);
  struct mapping *hits20x    	  = allocate_mapping(300);
  struct mapping *hits302    	  = allocate_mapping(2);
  struct mapping *sites    	  = allocate_mapping(1);
  struct mapping *domains    	  = allocate_mapping(1);
  struct mapping *topdomains   	  = allocate_mapping(1);
  struct mapping *tmpdest = NULL;
  /*  struct mapping *hits30x     = allocate_mapping(2);*/
  
  if(args>6 && sp[-1].type == T_INT) {
    offs0 = sp[-1].u.integer;
    pop_n_elems(1);
    --args;
  }
  if(args>5 && sp[-1].type == T_STRING) {
    notref = sp[-1].u.string->str;
    pop_n_elems(1);
    --args;
  }
  lmu = 0;
  get_all_args("UltraLog.ultraparse", args, "%*%*%*%*%*", &log_format, &statfun, &daily, &file,
	       &pagexts);
  if(log_format->type != T_STRING) 
    Pike_error("Bad argument 1 to Ultraparse.ultraparse, expected string.\n");
  if(statfun->type != T_FUNCTION)  
    Pike_error("Bad argument 2 to Ultraparse.ultraparse, expected function.\n");
  if(daily->type != T_FUNCTION)    
    Pike_error("Bad argument 3 to Ultraparse.ultraparse, expected function.\n");
  if(pagexts->type != T_MULTISET)  
    Pike_error("Bad argument 5 to Ultraparse.ultraparse, expected multiset.\n");
  
  if(file->type == T_OBJECT)
  {
    f = fd_from_object(file->u.object);
    
    if(f == -1)
      Pike_error("UltraLog.ultraparse: File is not open.\n");
    my_fd = 0;
  } else if(file->type == T_STRING &&
	    file->u.string->size_shift == 0) {
    do {
      f=fd_open(file->u.string->str, fd_RDONLY, 0);
    } while(f < 0 && errno == EINTR);
    
    if(errno < 0)
      Pike_error("UltraLog.ultraparse(): Failed to open file for reading (errno=%d).\n",
	    errno);
  } else 
    Pike_error("Bad argument 4 to UltraLog.ultraparse, expected string or object .\n");

  state_list = malloc((log_format->u.string->len +3) * sizeof(INT32));
  save_field_num = malloc((log_format->u.string->len +3) * sizeof(INT32));
  field_endings = malloc((log_format->u.string->len +3) * sizeof(INT32));

  num_states = parse_log_format(log_format->u.string, state_list, field_endings, save_field_num);
  if(num_states < 1)
  {
    free(state_list);
    free(save_field_num);
    free(field_endings);
    Pike_error("UltraLog.ultraparse(): Failed to parse log format.\n");
  }
  
  fd_lseek(f, offs0, SEEK_SET);
  read_buf = malloc(READ_BLOCK_SIZE+1);
  buf = malloc(MAX_LINE_LEN+2);
#ifdef BROKEN_LINE_DEBUG
  broken_line = malloc(MAX_LINE_LEN*10);
#endif
  MEMSET(hits_per_hour, 0, sizeof(hits_per_hour));
  MEMSET(hosts_per_hour, 0, sizeof(hosts_per_hour));
  MEMSET(session_length, 0, sizeof(session_length));
  MEMSET(pages_per_hour, 0, sizeof(pages_per_hour));
  MEMSET(sessions_per_hour, 0, sizeof(sessions_per_hour));
  MEMSET(kb_per_hour, 0, sizeof(kb_per_hour));

  /*url_sval.u.type = TYPE_STRING;*/
  BUFSET(0);
  field_position = bufpos;
  buf_points[0] = buf_points[1] = buf_points[2] = buf_points[3] = 
    buf_points[4] = buf_points[5] = buf_points[6] = buf_points[7] = 
    buf_points[8] = buf_points[9] = buf_points[10] = buf_points[11] = 
    buf_points[12] = buf_points[13] = buf_points[14] = buf_points[15] = 0;
  while(1) {
    /*    THREADS_ALLOW();*/
    do {
      len = fd_read(f, read_buf, READ_BLOCK_SIZE);
    } while(len < 0 && errno == EINTR);
    /*    THREADS_DISALLOW();*/
    if(len <= 0)  break; /* nothing more to read or error. */
    offs0 += len;
    char_pointer = read_buf+len - 1;
    while(len--) {
      c = char_pointer[-len]; 
      cls = char_class[c];
#if 0
      fprintf(stdout, "DFA(%d:%d): '%c' (%d) ", state, state_pos, c, (int)c);
      switch(cls) {
       case CLS_WSPACE: fprintf(stdout, "CLS_WSPACE\n"); break;
       case CLS_CRLF: fprintf(stdout, "CLS_CRLF\n"); break;
       case CLS_TOKEN: fprintf(stdout, "CLS_TOKEN\n"); break;
       case CLS_DIGIT: fprintf(stdout, "CLS_DIGIT\n"); break;
       case CLS_QUOTE: fprintf(stdout, "CLS_QUOTE\n"); break;
       case CLS_LBRACK: fprintf(stdout, "CLS_LBRACK\n"); break;
       case CLS_RBRACK: fprintf(stdout, "CLS_RBRACK\n"); break;
       case CLS_SLASH: fprintf(stdout, "CLS_SLASH\n"); break;
       case CLS_COLON: fprintf(stdout, "CLS_COLON\n"); break;
       case CLS_HYPHEN: fprintf(stdout, "CLS_HYPHEN/CLS_MINUS\n"); break;
       case CLS_PLUS: fprintf(stdout, "CLS_PLUS\n"); break;
       default: fprintf(stdout, "??? %d ???\n", cls);
      }
#endif
#ifdef BROKEN_LINE_DEBUG
      broken_line[broken_line_pos++] = c;
#endif
      if(cls == field_endings[state_pos]) {
	/* Field is done. Nullify. */
      process_field:
	/*	printf("Processing field %d of %d\n", state_pos, num_states);*/
	switch(save_field_num[state_pos]) {
	 case DATE:
	 case HOUR:
	 case MINUTE:
	 case UP_SEC:
	 case CODE:
	   /*	  BUFSET(0);*/
	  tmpinteger = 0;
	  for(v = field_position; v < bufpos; v++) {
	    if(char_class[buf[v]] == CLS_DIGIT)
	      tmpinteger = tmpinteger*10 + (buf[v]&0xf);
	    else {
	      goto skip;
	      
	    }
	  }
	  BUFPOINT = tmpinteger;
	  break;
	  
	 case YEAR:
	  tmpinteger = 0;
	  for(v = field_position; v < bufpos; v++) {
	    if(char_class[buf[v]] == CLS_DIGIT)
	      tmpinteger = tmpinteger*10 + (buf[v]&0xf);
	    else {
	      goto skip;
	    }
	  }
	  if(tmpinteger < 100) {
	    if(tmpinteger < 60)
	      tmpinteger += 2000;
	    else
	      tmpinteger += 1900;
	  }
	  BUFPOINT = tmpinteger;	  
	  break;

	 case BYTES:
	  v = field_position;
	  switch(char_class[buf[v++]]) {
	   case CLS_QUESTION:
	   case CLS_HYPHEN:
	    if(v == bufpos)
	      tmpinteger = 0;
	    else {
	      goto skip;
	    }
	    break;
	   case CLS_DIGIT:
	    tmpinteger = (buf[field_position]&0xf);
	    for(; v < bufpos; v++) {
	      if(char_class[buf[v]] == CLS_DIGIT)
		tmpinteger = tmpinteger*10 + (buf[v]&0xf);
	      else {
		goto skip;
	      }		
	    }
	    /*	    printf("Digit: %d\n", tmpinteger);*/
	    break;
	   default:
	    goto skip;
	  }
	  BUFPOINT = tmpinteger;
	  /*	  bufpos++;*/
	  break;	  
	 case MONTH:
	  /* Month */
	  /*	  BUFSET(0);*/
	  /*	  field_buf = buf + field_positions[state_pos];*/
	  switch(bufpos - field_position)
	  {
	   case 2:
	    tmpinteger = 0;
	    for(v = field_position; v < bufpos; v++) {
	      if(char_class[buf[v]] == CLS_DIGIT)
		tmpinteger = tmpinteger*10 + (buf[v]&0xf);
	      else {
		goto skip;
	      }
	    }
	    break;

	   case 3:
	    switch(((buf[field_position]|0x20)<<16)|((buf[field_position+1]|0x20)<<8)|
		   (buf[field_position+2]|0x20))
	    {
	     case ('j'<<16)|('a'<<8)|'n': tmpinteger = 1;   break;
	     case ('f'<<16)|('e'<<8)|'b': tmpinteger = 2;   break;
	     case ('m'<<16)|('a'<<8)|'r': tmpinteger = 3;   break;
	     case ('a'<<16)|('p'<<8)|'r': tmpinteger = 4;   break;
	     case ('m'<<16)|('a'<<8)|'y': tmpinteger = 5;   break;
	     case ('j'<<16)|('u'<<8)|'n': tmpinteger = 6;   break;
	     case ('j'<<16)|('u'<<8)|'l': tmpinteger = 7;   break;
	     case ('a'<<16)|('u'<<8)|'g': tmpinteger = 8;   break;
	     case ('s'<<16)|('e'<<8)|'p': tmpinteger = 9;   break;
	     case ('o'<<16)|('c'<<8)|'t': tmpinteger = 10;  break;
	     case ('n'<<16)|('o'<<8)|'v': tmpinteger = 11;  break;
	     case ('d'<<16)|('e'<<8)|'c': tmpinteger = 12;  break;
	    }
	    break;

	   default:
	    goto skip;
	  }
	  /*printf("Month: %0d\n", mm);*/

	  if(tmpinteger < 1 || tmpinteger > 12)
	    goto skip; /* Broken Month */
	  BUFPOINT = tmpinteger;
	  /*	  bufpos++;*/
	  break;
	  
	 case ADDR:
	 case REFER:
	 case AGENT:
	 case TZ:
	 case METHOD:
	 case URL:
	 case RFC:
	 case PROTO:
	  BUFSET(0);
	  SETPOINT();
	  /*	  printf("Field %d, pos %d, %s\n", save_field_num[state_pos],BUFPOINT,*/
	  /*		 buf + BUFPOINT);	 */
	  break;
	  
	}	  
	state_pos++;
	field_position = bufpos;
	if(cls != CLS_CRLF)		  
	  continue;
      } else if(cls != CLS_CRLF) {
	BUFSET(c);
	continue;
      } else {
	/*	printf("Processing last field (%d).\n", state_pos);*/
	goto process_field; /* End of line - process what we got */
      }
      /*	printf("%d %d\n", state_pos, num_states);*/
      /*      buf_points[8] = buf_points[9] = buf_points[10] = buf_points[11] = buf;*/
      /*      buf_points[12] = buf_points[13] = buf_points[14] = buf_points[15] = buf;*/
#if 0
      if(!((lines+broken_lines)%100000)) {
	push_int(lines+broken_lines);
	push_int((int)((float)offs0/1024.0/1024.0));
	apply_svalue(statfun, 2);
	pop_stack();
	/*printf("%5dk lines, %5d MB\n", lines/1000, (int)((float)offs0/1024.0/1024.0));*/
      }
#endif
      if(state_pos < num_states)
      {
#ifdef BROKEN_LINE_DEBUG
	broken_line[broken_line_pos] = 0;
	printf("too few states (pos=%d): %s\n", state_pos, broken_line);
#endif
	broken_lines++;
	goto ok;
      }
      
#define yy 	buf_points[YEAR] 
#define mm 	buf_points[MONTH] 
#define dd 	buf_points[DATE] 
#define h  	buf_points[HOUR] 
#define m  	buf_points[MINUTE] 
#define s  	buf_points[UP_SEC] 
#define v  	buf_points[CODE] 
#define bytes	buf_points[BYTES] 

      this_date = (yy*10000) + (mm*100) + dd;
      if(!this_date) {
	broken_lines++;
	goto ok;
      }
#if 1
      if(!last_date) { /* First loop w/o a value.*/
	last_date = this_date;
	last_hour = h;
      } else {
	if(last_hour != h ||
	   last_date != this_date)
	{
	  pages_per_hour[last_hour] +=
	    hourly_page_hits(hits20x, pages, hits, pagexts->u.multiset, 200);
	  /*	    pages_per_hour[last_hour] +=*/
	  /*	      hourly_page_hits(hits304, pages, hits, pagexts->u.multiset, 300);*/
	  
	  /*	    printf("%5d %5d for %d %02d:00\n",*/
	  /*		   pages_per_hour[last_hour], hits_per_hour[last_hour],*/
	  /*last_date, last_hour);*/
	  if(m_sizeof(session_start)) {
	    summarize_sessions(last_hour, sessions_per_hour,
			       session_length, session_start, session_end);
	    free_mapping(session_start); 
	    free_mapping(session_end); 
	    session_start = allocate_mapping(1);
	    session_end   = allocate_mapping(1);
	  }
	  hosts_per_hour[last_hour] += m_sizeof(sites);
	  do_map_addition(hosts, sites);
	  free_mapping(sites);
	  sites = allocate_mapping(100);
	  last_hour = h;
	  free_mapping(hits20x); /* Reset this one */
	  /*	    free_mapping(hits304);  Reset this one */
	  /*	    hits304   = allocate_mapping(2);*/
	  hits20x   = allocate_mapping(2);
	}
#if 1
	if(last_date != this_date) {
	  /*	  printf("%d   %d\n", last_date, this_date);*/
	  tmpdest = allocate_mapping(1);
	  summarize_refsites(refsites, referrers, tmpdest);
	  free_mapping(referrers);
	  referrers = tmpdest;

	  tmpdest = allocate_mapping(1);
	  clean_refto(referredto, tmpdest, pagexts->u.multiset);
	  free_mapping(referredto);
	  referredto = tmpdest;
	  
	  summarize_directories(directories, pages);
	  summarize_directories(directories, hits);

	  tmpdest = allocate_mapping(1);
	  http_decode_mapping(user_agents, tmpdest);
	  free_mapping(user_agents);
	  user_agents = tmpdest;

	  tmpdest = allocate_mapping(1);
	  summarize_hosts(hosts, domains, topdomains, tmpdest);
	  free_mapping(hosts);
	  hosts = tmpdest;
#if 1
	  push_int(last_date / 10000);
	  push_int((last_date % 10000)/100);
	  push_int((last_date % 10000)%100);
	  push_mapping(pages);
	  push_mapping(hits);
	  push_mapping(hits302);
	  push_mapping(hits_per_error);
	  push_mapping(error_urls);
	  push_mapping(error_refs);
	  push_mapping(referredto);
	  push_mapping(refsites); 
	  push_mapping(referrers); 
	  push_mapping(directories); 
	  push_mapping(user_agents); 
	  push_mapping(hosts); 
	  push_mapping(domains); 
	  push_mapping(topdomains); 
	  for(i = 0; i < 24; i++) {
	    push_int(sessions_per_hour[i]);
	  }
	  f_aggregate(24);
	  for(i = 0; i < 24; i++) {
	    push_int(hits_per_hour[i]);
	    hits_per_hour[i] = 0;
	  }
	  f_aggregate(24);
	  for(i = 0; i < 24; i++) {
	    push_int(pages_per_hour[i]);
	    pages_per_hour[i] = 0;
	  }
	  f_aggregate(24);
	  for(i = 0; i < 24; i++) {
	    /* KB per hour.*/
	    push_float(kb_per_hour[i]);
	    kb_per_hour[i] = 0.0;
	  }
	  f_aggregate(24);
	  for(i = 0; i < 24; i++) {
	    push_float(sessions_per_hour[i] ?
		       ((float)session_length[i] /
			(float)sessions_per_hour[i]) / 60.0 : 0.0);
	    sessions_per_hour[i] = 0;
	    session_length[i] = 0;
	  }
	  f_aggregate(24);
	  for(i = 0; i < 24; i++) {
	    push_int(hosts_per_hour[i]);
	    hosts_per_hour[i] = 0;
	  }
	  f_aggregate(24);
	  apply_svalue(daily, 23);
	  pop_stack();
#else
	  free_mapping(error_refs);
	  free_mapping(referredto); 
	  free_mapping(refsites); 
	  free_mapping(directories); 
	  free_mapping(error_urls);
	  free_mapping(hits);
	  free_mapping(hits_per_error);
	  free_mapping(pages);
	  free_mapping(hosts);
	  free_mapping(domains);
	  free_mapping(topdomains);
	  free_mapping(referrers); 
	  free_mapping(hits302);
#endif
	  user_agents 	 = allocate_mapping(10);
	  hits302 	 = allocate_mapping(1);
	  hits_per_error = allocate_mapping(10);
	  error_urls     = allocate_mapping(10);
	  error_refs     = allocate_mapping(10);
	  directories    = allocate_mapping(20);
	  referrers      = allocate_mapping(1);
	  referredto     = allocate_mapping(1);
	  refsites       = allocate_mapping(1);
	  pages  	 = allocate_mapping(1);
	  hits 	         = allocate_mapping(1);
	  sites	         = allocate_mapping(1);
	  hosts	         = allocate_mapping(1);
	  domains	 = allocate_mapping(1);
	  topdomains     = allocate_mapping(1);
	  last_date = this_date;
	}
#endif
      }
#endif
#if 1
      process_session(buf+buf_points[ADDR], h*3600+m*60+s, h, 
		      sessions_per_hour, session_length, session_start,
		      session_end, sites);
      url_str = make_shared_binary_string((char *)(buf + buf_points[URL]),
					  strlen((char *)(buf + buf_points[URL])));
#if 1
      switch(v) {
      /* Do error-code specific logging. Error urls that are
	   specially treated do not include auth required, service
	   unavailable etc. They are only included in the return
	   code summary.
	*/
       case 200: case 201: case 202: case 203: 
       case 204: case 205: case 206: case 207:
       case 304:
	mapaddstr(hits20x, url_str);
	DO_REFERRER();
	break;

       case 300: case 301: case 302:
       case 303: case 305:
	mapaddstr(hits302, url_str);
	DO_REFERRER();
	break;

       case 400: case 404: case 405: case 406: case 408:
       case 409: case 410: case 411: case 412: case 413:
       case 414: case 415: case 416: case 500: case 501:
	DO_ERREF();
	map2addint(error_urls, v, url_str);
	break;
      }
      /*rfc_str = http_decode_string(buf + buf_points[RFC]);*/
      /*hst_str = make_shared_binary_string(buf, strlen(buf));*/
#endif	
      free_string(url_str);
      mapaddint(hits_per_error, v);
      kb_per_hour[h] += (float)bytes / 1024.0;
      hits_per_hour[h]++;
      /*#endif*/
      if(strlen((char *)(buf + buf_points[AGENT]))>1) {
	/* Got User Agent */
	tmpagent = make_shared_string((char *)(buf + buf_points[AGENT]));
	mapaddstr(user_agents, tmpagent);
	free_string(tmpagent);
      }
#endif
      lines++;
#if 0
      printf("%s  %s  %s\n%s  %s  %s\n%04d-%02d-%02d  %02d:%02d:%02d  \n%d   %d\n",
	     buf + buf_points[ADDR], buf + buf_points[REFER], buf + buf_points[ RFC ],
	     buf + buf_points[METHOD], buf + buf_points[ URL ], buf + buf_points[PROTO],
	     yy, mm, dd, h, m, s, v, bytes);
      /*      if(lines > 10)
	      exit(0);*/
#endif
    ok:
      gotdate = /* v = bytes =h = m = s = tz = tzs = dd = mm = yy =  */
	buf_points[0] = buf_points[1] = buf_points[2] = buf_points[3] = 
	buf_points[4] = buf_points[5] = buf_points[6] = buf_points[7] = 
	/*buf_points[8] = buf_points[9] = buf_points[10] =*/
	buf_points[11] = 
	buf_points[12] = buf_points[13] = buf_points[14] = buf_points[15] = 
	bufpos = state_pos = 0;
      field_position = 1;
#ifdef BROKEN_LINE_DEBUG
      broken_line_pos = 0;
#endif
      BUFSET(0);
      
    }    
  }  
 cleanup:
  free(save_field_num);
  free(state_list);
  free(field_endings);
  free(buf);
  push_int(lines);
  push_int((int)((float)offs0 / 1024.0/1024.0));
  push_int(1);
  apply_svalue(statfun, 3);
  pop_stack();
  free(read_buf);
#ifdef BROKEN_LINE_DEBUG
  free(broken_line);
#endif
  if(my_fd)
    /* If my_fd == 0, the second argument was an object and thus we don't
     * want to free it.
     */
    fd_close(f);
  /*  push_int(offs0);  */
  /*  printf("Done: %d %d %d ", yy, mm, dd);*/
  if(yy && mm && dd) { 
    /*    printf("\nLast Summary for %d-%02d-%02d %02d:%02d\n", yy, mm, dd, h, m);*/
    pages_per_hour[last_hour] += 
      hourly_page_hits(hits20x, pages, hits, pagexts->u.multiset, 200);
    if(m_sizeof(session_start)) {
      summarize_sessions(last_hour, sessions_per_hour,
			 session_length, session_start, session_end);
    }
    hosts_per_hour[last_hour] += m_sizeof(sites);
    do_map_addition(hosts, sites);
    free_mapping(sites);
	  
    tmpdest = allocate_mapping(1);
    summarize_refsites(refsites, referrers, tmpdest);
    free_mapping(referrers);
    referrers = tmpdest;
    summarize_directories(directories, pages);
    summarize_directories(directories, hits);
    tmpdest = allocate_mapping(1);
    clean_refto(referredto, tmpdest, pagexts->u.multiset);
    free_mapping(referredto);
    referredto = tmpdest;

    tmpdest = allocate_mapping(1);
    http_decode_mapping(user_agents, tmpdest);
    free_mapping(user_agents);
    user_agents = tmpdest;

    tmpdest = allocate_mapping(1);
    summarize_hosts(hosts, domains, topdomains, tmpdest);
    free_mapping(hosts);
    hosts = tmpdest;

    push_int(yy);
    push_int(mm);
    push_int(dd);
    push_mapping(pages);
    push_mapping(hits);
    push_mapping(hits302);
    push_mapping(hits_per_error);
    push_mapping(error_urls);
    push_mapping(error_refs);
    push_mapping(referredto); 
    push_mapping(refsites); 
    push_mapping(referrers); 
    push_mapping(directories); 
    push_mapping(user_agents); 
    push_mapping(hosts); 
    push_mapping(domains); 
    push_mapping(topdomains); 

    for(i = 0; i < 24; i++) {  push_int(sessions_per_hour[i]);  }
    f_aggregate(24);

    for(i = 0; i < 24; i++) {  push_int(hits_per_hour[i]);      }
    f_aggregate(24);

    for(i = 0; i < 24; i++) {  push_int(pages_per_hour[i]);     }
    f_aggregate(24);
    
    for(i = 0; i < 24; i++) {  push_float(kb_per_hour[i]);      }
    f_aggregate(24);

    for(i = 0; i < 24; i++) {
      push_float(sessions_per_hour[i] ?
		 ((float)session_length[i] /
		  (float)sessions_per_hour[i]) / 60.0 : 0.0);
    }
    f_aggregate(24);

    for(i = 0; i < 24; i++) {
      push_int(hosts_per_hour[i]);
      hosts_per_hour[i] = 0;
    }
    f_aggregate(24);

    apply_svalue(daily, 23);
    pop_stack();
  } else {
    free_mapping(error_refs);
    free_mapping(referredto); 
    free_mapping(refsites); 
    free_mapping(directories); 
    free_mapping(error_urls);
    free_mapping(hits);
    free_mapping(hits_per_error);
    free_mapping(pages);
    free_mapping(referrers); 
    free_mapping(hits302); 
    free_mapping(user_agents); 
    free_mapping(hosts);
    free_mapping(domains);
    free_mapping(topdomains);
  }
  free_mapping(hits20x); 
  free_mapping(session_start); 
  free_mapping(session_end); 
  /*  free_mapping(hits30x); */
  printf("\nTotal lines: %d, broken lines: %d, mapping lookups: %d\n\n", lines,
	 broken_lines, lmu);
  fflush(stdout);
  pop_n_elems(args);  
  push_int(offs0);
  return; 
      
 skip:
  broken_lines++;
  while(1) 
  {
    while(len--) {
#ifdef BROKEN_LINE_DEBUG
      broken_line[broken_line_pos] = char_pointer[-len];
#endif
      if(char_class[char_pointer[-len]] == CLS_CRLF) {
#ifdef BROKEN_LINE_DEBUG
	broken_line[broken_line_pos] = 0;
	printf("Broken Line (pos=%d): %s\n", state_pos, broken_line);
#endif
	goto ok;
      }
    }
    do {
      len = fd_read(f, read_buf, READ_BLOCK_SIZE);
    } while(len < 0 && errno == EINTR);
    if(len <= 0)
      break; /* nothing more to read. */
    offs0 += len;
    char_pointer = read_buf+len - 1;
  }
  goto cleanup;
}
Пример #24
0
/*
 * scamper_fds_cleanup
 *
 * tidy up the state allocated to maintain fd records.
 */
void scamper_fds_cleanup()
{
  scamper_fd_t *fdn;

  /* clean up the lists */
  cleanup_list(read_fds);    read_fds = NULL;
  cleanup_list(write_fds);   write_fds = NULL;
  cleanup_list(read_queue);  read_queue = NULL;
  cleanup_list(write_queue); write_queue = NULL;

  /* reap anything on the reap list */
  if(refcnt_0 != NULL)
    {
      while((fdn = (scamper_fd_t *)dlist_head_get(refcnt_0)) != NULL)
	{
	  fd_close(fdn);
	  fd_free(fdn);
	}
      dlist_free(refcnt_0);
      refcnt_0 = NULL;
    }

  /* clean up the tree */
  if(fd_tree != NULL)
    {
      splaytree_free(fd_tree, NULL);
      fd_tree = NULL;
    }

  /* clean up the list */
  if(fd_list != NULL)
    {
      dlist_free(fd_list);
      fd_list = NULL;
    }

  /* clean up the array */
  if(fd_array != NULL)
    {
      free(fd_array);
      fd_array = NULL;
    }

#ifdef HAVE_POLL
  if(poll_fds != NULL)
    {
      free(poll_fds);
      poll_fds = NULL;
    }
#endif

#ifdef HAVE_KQUEUE
  if(kq != -1)
    {
      close(kq);
      kq = -1;
    }
  if(kevlist != NULL)
    {
      free(kevlist);
      kevlist = NULL;
    }
#endif

#ifdef HAVE_EPOLL
  if(ep != -1)
    {
      close(ep);
      ep = -1;
    }
  if(ep_events != NULL)
    {
      free(ep_events);
      ep_events = NULL;
    }
#endif

  return;
}
Пример #25
0
static NTSTATUS close_remove_share_mode(files_struct *fsp,
					enum file_close_type close_type)
{
	connection_struct *conn = fsp->conn;
	struct server_id self = messaging_server_id(conn->sconn->msg_ctx);
	bool delete_file = false;
	bool changed_user = false;
	struct share_mode_lock *lck = NULL;
	NTSTATUS status = NT_STATUS_OK;
	NTSTATUS tmp_status;
	struct file_id id;
	const struct security_unix_token *del_token = NULL;
	const struct security_token *del_nt_token = NULL;
	bool got_tokens = false;
	bool normal_close;
	int ret_flock, retries = 1;

	/* Ensure any pending write time updates are done. */
	if (fsp->update_write_time_event) {
		update_write_time_handler(fsp->conn->sconn->ev_ctx,
					fsp->update_write_time_event,
					timeval_current(),
					(void *)fsp);
	}

	/*
	 * Lock the share entries, and determine if we should delete
	 * on close. If so delete whilst the lock is still in effect.
	 * This prevents race conditions with the file being created. JRA.
	 */

	lck = get_existing_share_mode_lock(talloc_tos(), fsp->file_id);
	if (lck == NULL) {
		DEBUG(0, ("close_remove_share_mode: Could not get share mode "
			  "lock for file %s\n", fsp_str_dbg(fsp)));
		return NT_STATUS_INVALID_PARAMETER;
	}

	if (fsp->write_time_forced) {
		DEBUG(10,("close_remove_share_mode: write time forced "
			"for file %s\n",
			fsp_str_dbg(fsp)));
		set_close_write_time(fsp, lck->data->changed_write_time);
	} else if (fsp->update_write_time_on_close) {
		/* Someone had a pending write. */
		if (null_timespec(fsp->close_write_time)) {
			DEBUG(10,("close_remove_share_mode: update to current time "
				"for file %s\n",
				fsp_str_dbg(fsp)));
			/* Update to current time due to "normal" write. */
			set_close_write_time(fsp, timespec_current());
		} else {
			DEBUG(10,("close_remove_share_mode: write time pending "
				"for file %s\n",
				fsp_str_dbg(fsp)));
			/* Update to time set on close call. */
			set_close_write_time(fsp, fsp->close_write_time);
		}
	}

	if (fsp->initial_delete_on_close &&
			!is_delete_on_close_set(lck, fsp->name_hash)) {
		bool became_user = False;

		/* Initial delete on close was set and no one else
		 * wrote a real delete on close. */

		if (get_current_vuid(conn) != fsp->vuid) {
			become_user(conn, fsp->vuid);
			became_user = True;
		}
		fsp->delete_on_close = true;
		set_delete_on_close_lck(fsp, lck,
				get_current_nttok(conn),
				get_current_utok(conn));
		if (became_user) {
			unbecome_user();
		}
	}

	delete_file = is_delete_on_close_set(lck, fsp->name_hash);

	if (delete_file) {
		int i;
		/* See if others still have the file open via this pathname.
		   If this is the case, then don't delete. If all opens are
		   POSIX delete now. */
		for (i=0; i<lck->data->num_share_modes; i++) {
			struct share_mode_entry *e = &lck->data->share_modes[i];

			if (!is_valid_share_mode_entry(e)) {
				continue;
			}
			if (e->name_hash != fsp->name_hash) {
				continue;
			}
			if ((fsp->posix_flags & FSP_POSIX_FLAGS_OPEN)
			    && (e->flags & SHARE_MODE_FLAG_POSIX_OPEN)) {
				continue;
			}
			if (serverid_equal(&self, &e->pid) &&
			    (e->share_file_id == fsp->fh->gen_id)) {
				continue;
			}
			if (share_mode_stale_pid(lck->data, i)) {
				continue;
			}
			delete_file = False;
			break;
		}
	}

	/*
	 * NT can set delete_on_close of the last open
	 * reference to a file.
	 */

	normal_close = (close_type == NORMAL_CLOSE || close_type == SHUTDOWN_CLOSE);

	if (!normal_close || !delete_file) {
		status = NT_STATUS_OK;
		goto done;
	}

	/*
	 * Ok, we have to delete the file
	 */

	DEBUG(5,("close_remove_share_mode: file %s. Delete on close was set "
		 "- deleting file.\n", fsp_str_dbg(fsp)));

	/*
	 * Don't try to update the write time when we delete the file
	 */
	fsp->update_write_time_on_close = false;

	got_tokens = get_delete_on_close_token(lck, fsp->name_hash,
					&del_nt_token, &del_token);
	SMB_ASSERT(got_tokens);

	if (!unix_token_equal(del_token, get_current_utok(conn))) {
		/* Become the user who requested the delete. */

		DEBUG(5,("close_remove_share_mode: file %s. "
			"Change user to uid %u\n",
			fsp_str_dbg(fsp),
			(unsigned int)del_token->uid));

		if (!push_sec_ctx()) {
			smb_panic("close_remove_share_mode: file %s. failed to push "
				  "sec_ctx.\n");
		}

		set_sec_ctx(del_token->uid,
			    del_token->gid,
			    del_token->ngroups,
			    del_token->groups,
			    del_nt_token);

		changed_user = true;
	}

	/* We can only delete the file if the name we have is still valid and
	   hasn't been renamed. */

	tmp_status = vfs_stat_fsp(fsp);
	if (!NT_STATUS_IS_OK(tmp_status)) {
		DEBUG(5,("close_remove_share_mode: file %s. Delete on close "
			 "was set and stat failed with error %s\n",
			 fsp_str_dbg(fsp), nt_errstr(tmp_status)));
		/*
		 * Don't save the errno here, we ignore this error
		 */
		goto done;
	}

	id = vfs_file_id_from_sbuf(conn, &fsp->fsp_name->st);

	if (!file_id_equal(&fsp->file_id, &id)) {
		DEBUG(5,("close_remove_share_mode: file %s. Delete on close "
			 "was set and dev and/or inode does not match\n",
			 fsp_str_dbg(fsp)));
		DEBUG(5,("close_remove_share_mode: file %s. stored file_id %s, "
			 "stat file_id %s\n",
			 fsp_str_dbg(fsp),
			 file_id_string_tos(&fsp->file_id),
			 file_id_string_tos(&id)));
		/*
		 * Don't save the errno here, we ignore this error
		 */
		goto done;
	}

	if ((conn->fs_capabilities & FILE_NAMED_STREAMS)
	    && !is_ntfs_stream_smb_fname(fsp->fsp_name)) {

		status = delete_all_streams(conn, fsp->fsp_name->base_name);

		if (!NT_STATUS_IS_OK(status)) {
			DEBUG(5, ("delete_all_streams failed: %s\n",
				  nt_errstr(status)));
			goto done;
		}
	}

retry_delete:
	/* temporary files with delete on close set will not be deleted on a
	 * cifs share using a netapp backend since they are opened with
	 * read + write access mask.
	 * close the file to allow the delete.
	 */
	if (fsp->can_write && !S_ISDIR(fsp->fsp_name->st.st_ex_mode) &&
	    fsp->fh->ref_count == 1 && retries) {
		status = fd_close(fsp);
		if (!NT_STATUS_IS_OK(status)) {
			DEBUG(3, ("close_remove_share_mode: Error %s closing %s\n",
				nt_errstr(status),
				smb_fname_str_dbg(fsp->fsp_name)));
			goto skip_retry;
		}
		if (SMB_VFS_UNLINK(conn, fsp->fsp_name) != 0) {
			/*
			* This call can potentially fail as another smbd may
			* have had the file open with delete on close set and
			* deleted it when its last reference to this file
			* went away. Hence we log this but not at debug level
			* zero.
			*/

			DEBUG(5,("close_remove_share_mode: file %s. Delete on close "
				 "was set and unlink failed with error %s\n",
				 fsp_str_dbg(fsp), strerror(errno)));

			status = map_nt_error_from_unix(errno);
			retries = 0;
			goto retry_delete;
		}
	} else {
		if (SMB_VFS_UNLINK(conn, fsp->fsp_name) != 0) {
			/*
			 * This call can potentially fail as another smbd may
			 * have had the file open with delete on close set and
			 * deleted it when its last reference to this file
			 * went away. Hence we log this but not at debug level
			 * zero.
			 */

			DEBUG(5,("close_remove_share_mode: file %s. Delete on close "
				 "was set and unlink failed with error %s\n",
				 fsp_str_dbg(fsp), strerror(errno)));

			status = map_nt_error_from_unix(errno);
		}
	}

	/* As we now have POSIX opens which can unlink
 	 * with other open files we may have taken
 	 * this code path with more than one share mode
 	 * entry - ensure we only delete once by resetting
 	 * the delete on close flag. JRA.
 	 */

skip_retry:
	fsp->delete_on_close = false;
	reset_delete_on_close_lck(fsp, lck);

 done:

	if (changed_user) {
		/* unbecome user. */
		pop_sec_ctx();
	}

	/* remove filesystem sharemodes */
	ret_flock = SMB_VFS_KERNEL_FLOCK(fsp, 0, 0);
	if (ret_flock == -1) {
		DEBUG(2, ("close_remove_share_mode: removing kernel flock for "
					"%s failed: %s\n", fsp_str_dbg(fsp),
					strerror(errno)));
	}

	if (!del_share_mode(lck, fsp)) {
		DEBUG(0, ("close_remove_share_mode: Could not delete share "
			  "entry for file %s\n", fsp_str_dbg(fsp)));
	}

	TALLOC_FREE(lck);

	if (delete_file) {
		/*
		 * Do the notification after we released the share
		 * mode lock. Inside notify_fname we take out another
		 * tdb lock. With ctdb also accessing our databases,
		 * this can lead to deadlocks. Putting this notify
		 * after the TALLOC_FREE(lck) above we avoid locking
		 * two records simultaneously. Notifies are async and
		 * informational only, so calling the notify_fname
		 * without holding the share mode lock should not do
		 * any harm.
		 */
		notify_fname(conn, NOTIFY_ACTION_REMOVED,
			     FILE_NOTIFY_CHANGE_FILE_NAME,
			     fsp->fsp_name->base_name);
	}

	return status;
}
Пример #26
0
/* irc logs.. */
void ircd_log(int flags, char *format, ...)
{
static int last_log_file_warning = 0;

	va_list ap;
	ConfigItem_log *logs;
	char buf[2048], timebuf[128];
	struct stat fstats;
	int written = 0, write_failure = 0;

	va_start(ap, format);
	ircvsnprintf(buf, sizeof(buf), format, ap);
	va_end(ap);
	snprintf(timebuf, sizeof(timebuf), "[%s] - ", myctime(TStime()));
	RunHook3(HOOKTYPE_LOG, flags, timebuf, buf);
	strlcat(buf, "\n", sizeof(buf));

	for (logs = conf_log; logs; logs = (ConfigItem_log *) logs->next) {
#ifdef HAVE_SYSLOG
		if (!stricmp(logs->file, "syslog") && logs->flags & flags) {
			syslog(LOG_INFO, "%s", buf);
			written++;
			continue;
		}
#endif
		if (logs->flags & flags)
		{
			if (stat(logs->file, &fstats) != -1 && logs->maxsize && fstats.st_size >= logs->maxsize)
			{
				if (logs->logfd != -1)
					fd_close(logs->logfd);
				logs->logfd = fd_fileopen(logs->file, O_CREAT|O_WRONLY|O_TRUNC);
				if (logs->logfd == -1)
					continue;
				if (write(logs->logfd, "Max file size reached, starting new log file\n", 45) < 0)
				{
					write_failure = 1;
					continue;
				}
			}
			else if (logs->logfd == -1) {
				logs->logfd = fd_fileopen(logs->file, O_CREAT|O_APPEND|O_WRONLY);
				if (logs->logfd == -1)
				{
					if (!loop.ircd_booted)
					{
						config_status("WARNING: Unable to write to '%s': %s", logs->file, strerror(ERRNO));
					}
					else
					{
						if (last_log_file_warning + 300 < TStime())
						{
							config_status("WARNING: Unable to write to '%s': %s. This warning will not re-appear for at least 5 minutes.", logs->file, strerror(ERRNO));
							last_log_file_warning = TStime();
						}
					}
					write_failure = 1;
					continue;
				}
			}
			/* this shouldn't happen, but lets not waste unnecessary syscalls... */
			if (logs->logfd == -1)
				continue;
			if (write(logs->logfd, timebuf, strlen(timebuf)) < 0)
			{
				if (!loop.ircd_booted)
				{
					config_status("WARNING: Unable to write to '%s': %s", logs->file, strerror(ERRNO));
				}
				else
				{
					if (last_log_file_warning + 300 < TStime())
					{
						config_status("WARNING: Unable to write to '%s': %s. This warning will not re-appear for at least 5 minutes.", logs->file, strerror(ERRNO));
						last_log_file_warning = TStime();
					}
				}
				write_failure = 1;
			}
			if (write(logs->logfd, buf, strlen(buf)) == strlen(buf))
			{
				written++;
			}
			else
			{
				if (!loop.ircd_booted)
				{
					config_status("WARNING: Unable to write to '%s': %s", logs->file, strerror(ERRNO));
				}
				else
				{
					if (last_log_file_warning + 300 < TStime())
					{
						config_status("WARNING: Unable to write to '%s': %s. This warning will not re-appear for at least 5 minutes.", logs->file, strerror(ERRNO));
						last_log_file_warning = TStime();
					}
				}
				write_failure = 1;
			}
			fsync(logs->logfd);
		}
	}

	/* If nothing got written at all AND we had a write failure AND we are booting, then exit.
	 * Note that we can't just fail when nothing got written, as we might have been called for
	 * 'tkl' for example, which might not be in our log block.
	 */
	if (!written && write_failure && !loop.ircd_booted)
	{
		config_status("ERROR: Unable to write to any log file. Please check your log { } blocks and file permissions!");
		exit(9);
	}
}
Пример #27
0
/*
 * Initialization function for an X Athena Widget module to Angband
 *
 * We should accept "-d<dpy>" requests in the "argv" array.  XXX XXX XXX
 */
errr init_xaw(int argc, char *argv[])
{
	int i;
	Widget topLevel;
	Display *dpy;

	cptr dpy_name = "";


#ifdef USE_GRAPHICS

	char filename[1024];

	int pict_wid = 0;
	int pict_hgt = 0;

#ifdef USE_TRANSPARENCY

	char *TmpData;
#endif /* USE_TRANSPARENCY */

#endif /* USE_GRAPHICS */

	/* Parse args */
	for (i = 1; i < argc; i++)
	{
		if (prefix(argv[i], "-d"))
		{
			dpy_name = &argv[i][2];
			continue;
		}

#ifdef USE_GRAPHICS
		if (prefix(argv[i], "-s"))
		{
			smoothRescaling = FALSE;
			continue;
		}
#endif /* USE_GRAPHICS */

		if (prefix(argv[i], "-n"))
		{
			num_term = atoi(&argv[i][2]);
			if (num_term > MAX_TERM_DATA) num_term = MAX_TERM_DATA;
			else if (num_term < 1) num_term = 1;
			continue;
		}

		plog_fmt("Ignoring option: %s", argv[i]);
	}


	/* Attempt to open the local display */
	dpy = XOpenDisplay(dpy_name);

	/* Failure -- assume no X11 available */
	if (!dpy) return (-1);

	/* Close the local display */
	XCloseDisplay(dpy);


#ifdef USE_XAW_LANG

	/* Support locale processing */
	XtSetLanguageProc(NULL, NULL, NULL);

#endif /* USE_XAW_LANG */


	/* Initialize the toolkit */
	topLevel = XtAppInitialize(&appcon, "Angband", NULL, 0, &argc, argv,
	                           fallback, NULL, 0);


	/* Initialize the windows */
	for (i = 0; i < num_term; i++)
	{
		term_data *td = &data[i];

		term_data_init(td, topLevel, 1024, termNames[i],
		               (i == 0) ? specialArgs : defaultArgs,
		               TERM_FALLBACKS, i);

		angband_term[i] = Term;
	}

	/* Activate the "Angband" window screen */
	Term_activate(&data[0].t);

	/* Raise the "Angband" window */
	term_raise(&data[0]);


#ifdef USE_GRAPHICS

	/* Try graphics */
	if (arg_graphics)
	{
		/* Try the "16x16.bmp" file */
		path_build(filename, 1024, ANGBAND_DIR_XTRA, "graf/16x16.bmp");

		/* Use the "16x16.bmp" file if it exists */
		if (0 == fd_close(fd_open(filename, O_RDONLY)))
		{
			/* Use graphics */
			use_graphics = TRUE;

			use_transparency = TRUE;

			pict_wid = pict_hgt = 16;

			ANGBAND_GRAF = "new";
		}
		else
		{
			/* Try the "8x8.bmp" file */
			path_build(filename, 1024, ANGBAND_DIR_XTRA, "graf/8x8.bmp");

			/* Use the "8x8.bmp" file if it exists */
			if (0 == fd_close(fd_open(filename, O_RDONLY)))
			{
				/* Use graphics */
				use_graphics = TRUE;

				pict_wid = pict_hgt = 8;

				ANGBAND_GRAF = "old";
			}
		}
	}

	/* Load graphics */
	if (use_graphics)
	{
		/* Hack -- Get the Display */
		term_data *td = &data[0];
		Widget widget = (Widget)(td->widget);
		Display *dpy = XtDisplay(widget);

		XImage *tiles_raw;

		/* Load the graphical tiles */
		tiles_raw = ReadBMP(dpy, filename);

		/* Initialize the windows */
		for (i = 0; i < num_term; i++)
		{
			term_data *td = &data[i];

			term *t = &td->t;

			t->pict_hook = Term_pict_xaw;

			t->higher_pict = TRUE;

			/* Resize tiles */
			td->widget->angband.tiles =
			ResizeImage(dpy, tiles_raw,
			            pict_wid, pict_hgt,
			            td->widget->angband.fontwidth,
			            td->widget->angband.fontheight);
		}

#ifdef USE_TRANSPARENCY
		/* Initialize the transparency temp storage*/
		for (i = 0; i < num_term; i++)
		{
			term_data *td = &data[i];
			int ii, jj;
			int depth = DefaultDepth(dpy, DefaultScreen(dpy));
			Visual *visual = DefaultVisual(dpy, DefaultScreen(dpy));
			int total;


			/* Determine total bytes needed for image */
			ii = 1;
			jj = (depth - 1) >> 2;
			while (jj >>= 1) ii <<= 1;
			total = td->widget->angband.fontwidth *
				 td->widget->angband.fontheight * ii;


			TmpData = (char *)malloc(total);

			td->widget->angband.TmpImage = XCreateImage(dpy,
				visual,depth,
				ZPixmap, 0, TmpData,
				td->widget->angband.fontwidth,
			        td->widget->angband.fontheight, 8, 0);

		}
#endif /* USE_TRANSPARENCY */


		/* Free tiles_raw? XXX XXX */
	}

#endif /* USE_GRAPHICS */

	/* Success */
	return (0);
}
Пример #28
0
static NTSTATUS close_directory(struct smb_request *req, files_struct *fsp,
                                enum file_close_type close_type)
{
    struct share_mode_lock *lck = NULL;
    bool delete_dir = False;
    NTSTATUS status = NT_STATUS_OK;
    NTSTATUS status1 = NT_STATUS_OK;

    /*
     * NT can set delete_on_close of the last open
     * reference to a directory also.
     */

    lck = get_share_mode_lock(talloc_tos(), fsp->file_id, NULL, NULL,
                              NULL);

    if (lck == NULL) {
        DEBUG(0, ("close_directory: Could not get share mode lock for "
                  "%s\n", fsp_str_dbg(fsp)));
        status = NT_STATUS_INVALID_PARAMETER;
        goto out;
    }

    if (!del_share_mode(lck, fsp)) {
        DEBUG(0, ("close_directory: Could not delete share entry for "
                  "%s\n", fsp_str_dbg(fsp)));
    }

    if (fsp->initial_delete_on_close) {
        bool became_user = False;

        /* Initial delete on close was set - for
         * directories we don't care if anyone else
         * wrote a real delete on close. */

        if (current_user.vuid != fsp->vuid) {
            become_user(fsp->conn, fsp->vuid);
            became_user = True;
        }
        send_stat_cache_delete_message(fsp->fsp_name->base_name);
        set_delete_on_close_lck(lck, True, &current_user.ut);
        fsp->delete_on_close = true;
        if (became_user) {
            unbecome_user();
        }
    }

    delete_dir = lck->delete_on_close;

    if (delete_dir) {
        int i;
        /* See if others still have the dir open. If this is the
         * case, then don't delete. If all opens are POSIX delete now. */
        for (i=0; i<lck->num_share_modes; i++) {
            struct share_mode_entry *e = &lck->share_modes[i];
            if (is_valid_share_mode_entry(e)) {
                if (fsp->posix_open && (e->flags & SHARE_MODE_FLAG_POSIX_OPEN)) {
                    continue;
                }
                delete_dir = False;
                break;
            }
        }
    }

    if ((close_type == NORMAL_CLOSE || close_type == SHUTDOWN_CLOSE) &&
            delete_dir &&
            lck->delete_token) {

        /* Become the user who requested the delete. */

        if (!push_sec_ctx()) {
            smb_panic("close_directory: failed to push sec_ctx.\n");
        }

        set_sec_ctx(lck->delete_token->uid,
                    lck->delete_token->gid,
                    lck->delete_token->ngroups,
                    lck->delete_token->groups,
                    NULL);

        TALLOC_FREE(lck);

        status = rmdir_internals(talloc_tos(), fsp);

        DEBUG(5,("close_directory: %s. Delete on close was set - "
                 "deleting directory returned %s.\n",
                 fsp_str_dbg(fsp), nt_errstr(status)));

        /* unbecome user. */
        pop_sec_ctx();

        /*
         * Ensure we remove any change notify requests that would
         * now fail as the directory has been deleted.
         */

        if(NT_STATUS_IS_OK(status)) {
            remove_pending_change_notify_requests_by_fid(fsp, NT_STATUS_DELETE_PENDING);
        }
    } else {
        TALLOC_FREE(lck);
        remove_pending_change_notify_requests_by_fid(
            fsp, NT_STATUS_OK);
    }

    status1 = fd_close(fsp);

    if (!NT_STATUS_IS_OK(status1)) {
        DEBUG(0, ("Could not close dir! fname=%s, fd=%d, err=%d=%s\n",
                  fsp_str_dbg(fsp), fsp->fh->fd, errno,
                  strerror(errno)));
    }

    if (fsp->dptr) {
        dptr_CloseDir(fsp->dptr);
    }

    /*
     * Do the code common to files and directories.
     */
    close_filestruct(fsp);
    file_free(req, fsp);

out:
    TALLOC_FREE(lck);
    if (NT_STATUS_IS_OK(status) && !NT_STATUS_IS_OK(status1)) {
        status = status1;
    }
    return status;
}
Пример #29
0
/*
 * Attempt to Load a "savefile"
 *
 * On multi-user systems, you may only "read" a savefile if you will be
 * allowed to "write" it later, this prevents painful situations in which
 * the player loads a savefile belonging to someone else, and then is not
 * allowed to save his game when he quits.
 *
 * We return "TRUE" if the savefile was usable, and we set the global
 * flag "character_loaded" if a real, living, character was loaded.
 *
 * Note that we always try to load the "current" savefile, even if
 * there is no such file, so we must check for "empty" savefile names.
 */
bool load_player(void)
{
	int fd = -1;

	errr err = 0;

	byte vvv[4];

#ifdef VERIFY_TIMESTAMP
	struct stat	statbuf;
#endif /* VERIFY_TIMESTAMP */

	cptr what = "generic";


	/* Paranoia */
	turn = 0;

	/* Paranoia */
	p_ptr->is_dead = FALSE;


	/* Allow empty savefile name */
	if (!savefile[0]) return (TRUE);

	/* Grab permissions */
	safe_setuid_grab();

	/* Open the savefile */
	fd = fd_open(savefile, O_RDONLY);

	/* Drop permissions */
	safe_setuid_drop();

	/* No file */
	if (fd < 0)
	{
		/* Give a message */
		msg_print("Savefile does not exist.");
		message_flush();

		/* Allow this */
		return (TRUE);
	}

	/* Close the file */
	fd_close(fd);


#ifdef VERIFY_SAVEFILE

	/* Verify savefile usage */
	if (!err)
	{
		FILE *fkk;

		char temp[1024];

		/* Extract name of lock file */
		strcpy(temp, savefile);
		strcat(temp, ".lok");

		/* Grab permissions */
		safe_setuid_grab();

		/* Check for lock */
		fkk = my_fopen(temp, "r");

		/* Drop permissions */
		safe_setuid_drop();

		/* Oops, lock exists */
		if (fkk)
		{
			/* Close the file */
			my_fclose(fkk);

			/* Message */
			msg_print("Savefile is currently in use.");
			message_flush();

			/* Oops */
			return (FALSE);
		}

		/* Grab permissions */
		safe_setuid_grab();

		/* Create a lock file */
		fkk = my_fopen(temp, "w");

		/* Drop permissions */
		safe_setuid_drop();

		/* Dump a line of info */
		fprintf(fkk, "Lock file for savefile '%s'\n", savefile);

		/* Close the lock file */
		my_fclose(fkk);
	}

#endif /* VERIFY_SAVEFILE */


	/* Okay */
	if (!err)
	{
		/* Grab permissions */
		safe_setuid_grab();

		/* Open the savefile */
		fd = fd_open(savefile, O_RDONLY);

		/* Drop permissions */
		safe_setuid_drop();

		/* No file */
		if (fd < 0) err = -1;

		/* Message (below) */
		if (err) what = "Cannot open savefile";
	}

	/* Process file */
	if (!err)
	{

#ifdef VERIFY_TIMESTAMP

		/* Grab permissions */
		safe_setuid_grab();

		/* Get the timestamp */
		(void)fstat(fd, &statbuf);

		/* Drop permissions */
		safe_setuid_drop();

#endif /* VERIFY_TIMESTAMP */

		/* Read the first four bytes */
		if (fd_read(fd, (char*)(vvv), sizeof(vvv))) err = -1;

		/* What */
		if (err) what = "Cannot read savefile";

		/* Close the file */
		fd_close(fd);
	}

	/* Process file */
	if (!err)
	{
		/* Extract version */
		sf_major = vvv[0];
		sf_minor = vvv[1];
		sf_patch = vvv[2];
		sf_extra = vvv[3];

		/* Clear screen */
		Term_clear();

		if (older_than(OLD_VERSION_MAJOR, OLD_VERSION_MINOR, OLD_VERSION_PATCH))
		{
			err = -1;
			what = "Savefile is too old";
		}
		else if (!older_than(VERSION_MAJOR, VERSION_MINOR, VERSION_PATCH + 1))
		{
			err = -1;
			what = "Savefile is from the future";
		}
		else
		{
			/* Attempt to load */
			err = rd_savefile();

			/* Message (below) */
			if (err) what = "Cannot parse savefile";
		}
	}

	/* Paranoia */
	if (!err)
	{
		/* Invalid turn */
		if (!turn) err = -1;

		/* Message (below) */
		if (err) what = "Broken savefile";
	}

#ifdef VERIFY_TIMESTAMP
	/* Verify timestamp */
	if (!err && !arg_wizard)
	{
		/* Hack -- Verify the timestamp */
		if (sf_when > (statbuf.st_ctime + 100) ||
		    sf_when < (statbuf.st_ctime - 100))
		{
			/* Message */
			what = "Invalid timestamp";

			/* Oops */
			err = -1;
		}
	}
#endif /* VERIFY_TIMESTAMP */


	/* Okay */
	if (!err)
	{
		/* Give a conversion warning */
		if ((version_major != sf_major) ||
		    (version_minor != sf_minor) ||
		    (version_patch != sf_patch))
		{
			/* Message */
			msg_format("Converted a %d.%d.%d savefile.",
			   sf_major, sf_minor, sf_patch);
			message_flush();
		}

		/* Player is dead */
		if (p_ptr->is_dead)
		{
			/* Forget death */
			p_ptr->is_dead = FALSE;

			/* Cheat death */
			if (arg_wizard)
			{
				/* A character was loaded */
				character_loaded = TRUE;

				/* Done */
				return (TRUE);
			}

			/* Count lives */
			sf_lives++;

			/* Forget turns */
			turn = old_turn = 0;

			/* Done */
			return (TRUE);
		}

		/* A character was loaded */
		character_loaded = TRUE;

		/* Still alive */
		if (p_ptr->chp >= 0)
		{
			/* Reset cause of death */
			strcpy(p_ptr->died_from, "(alive and well)");
		}

		/* Success */
		return (TRUE);
	}


#ifdef VERIFY_SAVEFILE

	/* Verify savefile usage */
	if (TRUE)
	{
		char temp[1024];

		/* Extract name of lock file */
		strcpy(temp, savefile);
		strcat(temp, ".lok");

		/* Grab permissions */
		safe_setuid_grab();

		/* Remove lock */
		fd_kill(temp);

		/* Drop permissions */
		safe_setuid_drop();
	}

#endif /* VERIFY_SAVEFILE */


	/* Message */
	msg_format("Error (%s) reading %d.%d.%d savefile.",
	   what, sf_major, sf_minor, sf_patch);
	message_flush();

	/* Oops */
	return (FALSE);
}
Пример #30
0
gint send_message_local(const gchar *command, FILE *fp)
{
	gchar **argv;
	GPid pid;
	gint child_stdin;
	gchar buf[BUFFSIZE];
	gboolean err = FALSE;

	cm_return_val_if_fail(command != NULL, -1);
	cm_return_val_if_fail(fp != NULL, -1);

	log_message(LOG_PROTOCOL, _("Sending message using command: %s\n"), command);

	argv = strsplit_with_quote(command, " ", 0);

	if (g_spawn_async_with_pipes(NULL, argv, NULL,
#ifdef G_OS_WIN32
                                     0,
#else
				     G_SPAWN_DO_NOT_REAP_CHILD,
#endif
                                     NULL, NULL,
				     &pid, &child_stdin, NULL, NULL,
				     NULL) == FALSE) {
		g_snprintf(buf, sizeof(buf),
			   _("Couldn't execute command: %s"), command);
		log_warning(LOG_PROTOCOL, "%s\n", buf);
		alertpanel_error("%s", buf);
		g_strfreev(argv);
		return -1;
	}
	g_strfreev(argv);

	while (claws_fgets(buf, sizeof(buf), fp) != NULL) {
		strretchomp(buf);
		if (buf[0] == '.' && buf[1] == '\0') {
			if (fd_write_all(child_stdin, ".", 1) < 0) {
				err = TRUE;
				break;
			}
		}
		if (fd_write_all(child_stdin, buf, strlen(buf)) < 0 ||
		    fd_write_all(child_stdin, "\n", 1) < 0) {
			err = TRUE;
			break;
		}
	}

	fd_close(child_stdin);

#ifndef G_OS_WIN32
	gint status;
	waitpid(pid, &status, 0);
	if (!WIFEXITED(status) || WEXITSTATUS(status) != 0)
		err = TRUE;
#endif

	g_spawn_close_pid(pid);

	if (err) {
		g_snprintf(buf, sizeof(buf),
			   _("Error occurred while executing command: %s"),
			   command);
		log_warning(LOG_PROTOCOL, "%s\n", buf);
		alertpanel_error("%s", buf);
		return -1;
	}

	return 0;
}