text:
/* $OpenBSD: sftp-server.c,v 1.103 2014/01/17 06:23:24 dtucker Exp $ */
/*
 * Copyright (c) 2000-2004 Markus Friedl.  All rights reserved.
 *
 * Permission to use, copy, modify, and distribute this software for any
 * purpose with or without fee is hereby granted, provided that the above
 * copyright notice and this permission notice appear in all copies.
 *
 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 */

#include "includes.h"

#include <sys/types.h>
#include <sys/param.h>
#include <sys/stat.h>
#ifdef HAVE_SYS_TIME_H
# include <sys/time.h>
#endif
#ifdef HAVE_SYS_MOUNT_H
#include <sys/mount.h>
#endif
#ifdef HAVE_SYS_STATVFS_H
#include <sys/statvfs.h>
#endif

#include <dirent.h>
#include <errno.h>
#include <fcntl.h>
#include <pwd.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <pwd.h>
#include <time.h>
#include <unistd.h>
#include <stdarg.h>

#include "xmalloc.h"
#include "buffer.h"
#include "log.h"
#include "misc.h"
#include "match.h"
#include "uidswap.h"

#include "sftp.h"
#include "sftp-common.h"

/* helper */
#define get_int64()			buffer_get_int64(&iqueue);
#define get_int()			buffer_get_int(&iqueue);
#define get_string(lenp)		buffer_get_string(&iqueue, lenp);

/* Our verbosity */
static LogLevel log_level = SYSLOG_LEVEL_ERROR;

/* Our client */
static struct passwd *pw = NULL;
static char *client_addr = NULL;

/* input and output queue */
static Buffer iqueue;
static Buffer oqueue;

/* Version of client */
static u_int version;

/* SSH2_FXP_INIT received */
static int init_done;

/* Disable writes */
static int readonly;

/* Requests that are allowed/denied */
static char *request_whitelist, *request_blacklist;

/* portable attributes, etc. */
typedef struct Stat Stat;

struct Stat {
	char *name;
	char *long_name;
	Attrib attrib;
};

/* Packet handlers */
static void process_open(u_int32_t id);
static void process_close(u_int32_t id);
static void process_read(u_int32_t id);
static void process_write(u_int32_t id);
static void process_stat(u_int32_t id);
static void process_lstat(u_int32_t id);
static void process_fstat(u_int32_t id);
static void process_setstat(u_int32_t id);
static void process_fsetstat(u_int32_t id);
static void process_opendir(u_int32_t id);
static void process_readdir(u_int32_t id);
static void process_remove(u_int32_t id);
static void process_mkdir(u_int32_t id);
static void process_rmdir(u_int32_t id);
static void process_realpath(u_int32_t id);
static void process_rename(u_int32_t id);
static void process_readlink(u_int32_t id);
static void process_symlink(u_int32_t id);
static void process_extended_posix_rename(u_int32_t id);
static void process_extended_statvfs(u_int32_t id);
static void process_extended_fstatvfs(u_int32_t id);
static void process_extended_hardlink(u_int32_t id);
static void process_extended_fsync(u_int32_t id);
static void process_extended(u_int32_t id);

struct sftp_handler {
	const char *name;	/* user-visible name for fine-grained perms */
	const char *ext_name;	/* extended request name */
	u_int type;		/* packet type, for non extended packets */
	void (*handler)(u_int32_t);
	int does_write;		/* if nonzero, banned for readonly mode */
};

struct sftp_handler handlers[] = {
	/* NB. SSH2_FXP_OPEN does the readonly check in the handler itself */
	{ "open", NULL, SSH2_FXP_OPEN, process_open, 0 },
	{ "close", NULL, SSH2_FXP_CLOSE, process_close, 0 },
	{ "read", NULL, SSH2_FXP_READ, process_read, 0 },
	{ "write", NULL, SSH2_FXP_WRITE, process_write, 1 },
	{ "lstat", NULL, SSH2_FXP_LSTAT, process_lstat, 0 },
	{ "fstat", NULL, SSH2_FXP_FSTAT, process_fstat, 0 },
	{ "setstat", NULL, SSH2_FXP_SETSTAT, process_setstat, 1 },
	{ "fsetstat", NULL, SSH2_FXP_FSETSTAT, process_fsetstat, 1 },
	{ "opendir", NULL, SSH2_FXP_OPENDIR, process_opendir, 0 },
	{ "readdir", NULL, SSH2_FXP_READDIR, process_readdir, 0 },
	{ "remove", NULL, SSH2_FXP_REMOVE, process_remove, 1 },
	{ "mkdir", NULL, SSH2_FXP_MKDIR, process_mkdir, 1 },
	{ "rmdir", NULL, SSH2_FXP_RMDIR, process_rmdir, 1 },
	{ "realpath", NULL, SSH2_FXP_REALPATH, process_realpath, 0 },
	{ "stat", NULL, SSH2_FXP_STAT, process_stat, 0 },
	{ "rename", NULL, SSH2_FXP_RENAME, process_rename, 1 },
	{ "readlink", NULL, SSH2_FXP_READLINK, process_readlink, 0 },
	{ "symlink", NULL, SSH2_FXP_SYMLINK, process_symlink, 1 },
	{ NULL, NULL, 0, NULL, 0 }
};

/* SSH2_FXP_EXTENDED submessages */
struct sftp_handler extended_handlers[] = {
	{ "posix-rename", "posix-rename@openssh.com", 0,
	   process_extended_posix_rename, 1 },
	{ "statvfs", "statvfs@openssh.com", 0, process_extended_statvfs, 0 },
	{ "fstatvfs", "fstatvfs@openssh.com", 0, process_extended_fstatvfs, 0 },
	{ "hardlink", "hardlink@openssh.com", 0, process_extended_hardlink, 1 },
	{ "fsync", "fsync@openssh.com", 0, process_extended_fsync, 1 },
	{ NULL, NULL, 0, NULL, 0 }
};

static int
request_permitted(struct sftp_handler *h)
{
	char *result;

	if (readonly && h->does_write) {
		verbose("Refusing %s request in read-only mode", h->name);
		return 0;
	}
	if (request_blacklist != NULL &&
	    ((result = match_list(h->name, request_blacklist, NULL))) != NULL) {
		free(result);
		verbose("Refusing blacklisted %s request", h->name);
		return 0;
	}
	if (request_whitelist != NULL &&
	    ((result = match_list(h->name, request_whitelist, NULL))) != NULL) {
		free(result);
		debug2("Permitting whitelisted %s request", h->name);
		return 1;
	}
	if (request_whitelist != NULL) {
		verbose("Refusing non-whitelisted %s request", h->name);
		return 0;
	}
	return 1;
}

static int
errno_to_portable(int unixerrno)
{
	int ret = 0;

	switch (unixerrno) {
	case 0:
		ret = SSH2_FX_OK;
		break;
	case ENOENT:
	case ENOTDIR:
	case EBADF:
	case ELOOP:
		ret = SSH2_FX_NO_SUCH_FILE;
		break;
	case EPERM:
	case EACCES:
	case EFAULT:
		ret = SSH2_FX_PERMISSION_DENIED;
		break;
	case ENAMETOOLONG:
	case EINVAL:
		ret = SSH2_FX_BAD_MESSAGE;
		break;
	case ENOSYS:
		ret = SSH2_FX_OP_UNSUPPORTED;
		break;
	default:
		ret = SSH2_FX_FAILURE;
		break;
	}
	return ret;
}

static int
flags_from_portable(int pflags)
{
	int flags = 0;

	if ((pflags & SSH2_FXF_READ) &&
	    (pflags & SSH2_FXF_WRITE)) {
		flags = O_RDWR;
	} else if (pflags & SSH2_FXF_READ) {
		flags = O_RDONLY;
	} else if (pflags & SSH2_FXF_WRITE) {
		flags = O_WRONLY;
	}
	if (pflags & SSH2_FXF_APPEND)
		flags |= O_APPEND;
	if (pflags & SSH2_FXF_CREAT)
		flags |= O_CREAT;
	if (pflags & SSH2_FXF_TRUNC)
		flags |= O_TRUNC;
	if (pflags & SSH2_FXF_EXCL)
		flags |= O_EXCL;
	return flags;
}

static const char *
string_from_portable(int pflags)
{
	static char ret[128];

	*ret = '\0';

#define PAPPEND(str)	{				\
		if (*ret != '\0')			\
			strlcat(ret, ",", sizeof(ret));	\
		strlcat(ret, str, sizeof(ret));		\
	}

	if (pflags & SSH2_FXF_READ)
		PAPPEND("READ")
	if (pflags & SSH2_FXF_WRITE)
		PAPPEND("WRITE")
	if (pflags & SSH2_FXF_APPEND)
		PAPPEND("APPEND")
	if (pflags & SSH2_FXF_CREAT)
		PAPPEND("CREATE")
	if (pflags & SSH2_FXF_TRUNC)
		PAPPEND("TRUNCATE")
	if (pflags & SSH2_FXF_EXCL)
		PAPPEND("EXCL")

	return ret;
}

static Attrib *
get_attrib(void)
{
	return decode_attrib(&iqueue);
}

/* handle handles */

typedef struct Handle Handle;
struct Handle {
	int use;
	DIR *dirp;
	int fd;
	int flags;
	char *name;
	u_int64_t bytes_read, bytes_write;
	int next_unused;
};

enum {
	HANDLE_UNUSED,
	HANDLE_DIR,
	HANDLE_FILE
};

Handle *handles = NULL;
u_int num_handles = 0;
int first_unused_handle = -1;

static void handle_unused(int i)
{
	handles[i].use = HANDLE_UNUSED;
	handles[i].next_unused = first_unused_handle;
	first_unused_handle = i;
}

static int
handle_new(int use, const char *name, int fd, int flags, DIR *dirp)
{
	int i;

	if (first_unused_handle == -1) {
		if (num_handles + 1 <= num_handles)
			return -1;
		num_handles++;
		handles = xrealloc(handles, num_handles, sizeof(Handle));
		handle_unused(num_handles - 1);
	}

	i = first_unused_handle;
	first_unused_handle = handles[i].next_unused;

	handles[i].use = use;
	handles[i].dirp = dirp;
	handles[i].fd = fd;
	handles[i].flags = flags;
	handles[i].name = xstrdup(name);
	handles[i].bytes_read = handles[i].bytes_write = 0;

	return i;
}

static int
handle_is_ok(int i, int type)
{
	return i >= 0 && (u_int)i < num_handles && handles[i].use == type;
}

static int
handle_to_string(int handle, char **stringp, int *hlenp)
{
	if (stringp == NULL || hlenp == NULL)
		return -1;
	*stringp = xmalloc(sizeof(int32_t));
	put_u32(*stringp, handle);
	*hlenp = sizeof(int32_t);
	return 0;
}

static int
handle_from_string(const char *handle, u_int hlen)
{
	int val;

	if (hlen != sizeof(int32_t))
		return -1;
	val = get_u32(handle);
	if (handle_is_ok(val, HANDLE_FILE) ||
	    handle_is_ok(val, HANDLE_DIR))
		return val;
	return -1;
}

static char *
handle_to_name(int handle)
{
	if (handle_is_ok(handle, HANDLE_DIR)||
	    handle_is_ok(handle, HANDLE_FILE))
		return handles[handle].name;
	return NULL;
}

static DIR *
handle_to_dir(int handle)
{
	if (handle_is_ok(handle, HANDLE_DIR))
		return handles[handle].dirp;
	return NULL;
}

static int
handle_to_fd(int handle)
{
	if (handle_is_ok(handle, HANDLE_FILE))
		return handles[handle].fd;
	return -1;
}

static int
handle_to_flags(int handle)
{
	if (handle_is_ok(handle, HANDLE_FILE))
		return handles[handle].flags;
	return 0;
}

static void
handle_update_read(int handle, ssize_t bytes)
{
	if (handle_is_ok(handle, HANDLE_FILE) && bytes > 0)
		handles[handle].bytes_read += bytes;
}

static void
handle_update_write(int handle, ssize_t bytes)
{
	if (handle_is_ok(handle, HANDLE_FILE) && bytes > 0)
		handles[handle].bytes_write += bytes;
}

static u_int64_t
handle_bytes_read(int handle)
{
	if (handle_is_ok(handle, HANDLE_FILE))
		return (handles[handle].bytes_read);
	return 0;
}

static u_int64_t
handle_bytes_write(int handle)
{
	if (handle_is_ok(handle, HANDLE_FILE))
		return (handles[handle].bytes_write);
	return 0;
}

static int
handle_close(int handle)
{
	int ret = -1;

	if (handle_is_ok(handle, HANDLE_FILE)) {
		ret = close(handles[handle].fd);
		free(handles[handle].name);
		handle_unused(handle);
	} else if (handle_is_ok(handle, HANDLE_DIR)) {
		ret = closedir(handles[handle].dirp);
		free(handles[handle].name);
		handle_unused(handle);
	} else {
		errno = ENOENT;
	}
	return ret;
}

static void
handle_log_close(int handle, char *emsg)
{
	if (handle_is_ok(handle, HANDLE_FILE)) {
		logit("%s%sclose \"%s\" bytes read %llu written %llu",
		    emsg == NULL ? "" : emsg, emsg == NULL ? "" : " ",
		    handle_to_name(handle),
		    (unsigned long long)handle_bytes_read(handle),
		    (unsigned long long)handle_bytes_write(handle));
	} else {
		logit("%s%sclosedir \"%s\"",
		    emsg == NULL ? "" : emsg, emsg == NULL ? "" : " ",
		    handle_to_name(handle));
	}
}

static void
handle_log_exit(void)
{
	u_int i;

	for (i = 0; i < num_handles; i++)
		if (handles[i].use != HANDLE_UNUSED)
			handle_log_close(i, "forced");
}

static int
get_handle(void)
{
	char *handle;
	int val = -1;
	u_int hlen;

	handle = get_string(&hlen);
	if (hlen < 256)
		val = handle_from_string(handle, hlen);
	free(handle);
	return val;
}

/* send replies */

static void
send_msg(Buffer *m)
{
	int mlen = buffer_len(m);

	buffer_put_int(&oqueue, mlen);
	buffer_append(&oqueue, buffer_ptr(m), mlen);
	buffer_consume(m, mlen);
}

static const char *
status_to_message(u_int32_t status)
{
	const char *status_messages[] = {
		"Success",			/* SSH_FX_OK */
		"End of file",			/* SSH_FX_EOF */
		"No such file",			/* SSH_FX_NO_SUCH_FILE */
		"Permission denied",		/* SSH_FX_PERMISSION_DENIED */
		"Failure",			/* SSH_FX_FAILURE */
		"Bad message",			/* SSH_FX_BAD_MESSAGE */
		"No connection",		/* SSH_FX_NO_CONNECTION */
		"Connection lost",		/* SSH_FX_CONNECTION_LOST */
		"Operation unsupported",	/* SSH_FX_OP_UNSUPPORTED */
		"Unknown error"			/* Others */
	};
	return (status_messages[MIN(status,SSH2_FX_MAX)]);
}

static void
send_status(u_int32_t id, u_int32_t status)
{
	Buffer msg;

	debug3("request %u: sent status %u", id, status);
	if (log_level > SYSLOG_LEVEL_VERBOSE ||
	    (status != SSH2_FX_OK && status != SSH2_FX_EOF))
		logit("sent status %s", status_to_message(status));
	buffer_init(&msg);
	buffer_put_char(&msg, SSH2_FXP_STATUS);
	buffer_put_int(&msg, id);
	buffer_put_int(&msg, status);
	if (version >= 3) {
		buffer_put_cstring(&msg, status_to_message(status));
		buffer_put_cstring(&msg, "");
	}
	send_msg(&msg);
	buffer_free(&msg);
}
static void
send_data_or_handle(char type, u_int32_t id, const char *data, int dlen)
{
	Buffer msg;

	buffer_init(&msg);
	buffer_put_char(&msg, type);
	buffer_put_int(&msg, id);
	buffer_put_string(&msg, data, dlen);
	send_msg(&msg);
	buffer_free(&msg);
}

static void
send_data(u_int32_t id, const char *data, int dlen)
{
	debug("request %u: sent data len %d", id, dlen);
	send_data_or_handle(SSH2_FXP_DATA, id, data, dlen);
}

static void
send_handle(u_int32_t id, int handle)
{
	char *string;
	int hlen;

	handle_to_string(handle, &string, &hlen);
	debug("request %u: sent handle handle %d", id, handle);
	send_data_or_handle(SSH2_FXP_HANDLE, id, string, hlen);
	free(string);
}

static void
send_names(u_int32_t id, int count, const Stat *stats)
{
	Buffer msg;
	int i;

	buffer_init(&msg);
	buffer_put_char(&msg, SSH2_FXP_NAME);
	buffer_put_int(&msg, id);
	buffer_put_int(&msg, count);
	debug("request %u: sent names count %d", id, count);
	for (i = 0; i < count; i++) {
		buffer_put_cstring(&msg, stats[i].name);
		buffer_put_cstring(&msg, stats[i].long_name);
		encode_attrib(&msg, &stats[i].attrib);
	}
	send_msg(&msg);
	buffer_free(&msg);
}

static void
send_attrib(u_int32_t id, const Attrib *a)
{
	Buffer msg;

	debug("request %u: sent attrib have 0x%x", id, a->flags);
	buffer_init(&msg);
	buffer_put_char(&msg, SSH2_FXP_ATTRS);
	buffer_put_int(&msg, id);
	encode_attrib(&msg, a);
	send_msg(&msg);
	buffer_free(&msg);
}

static void
send_statvfs(u_int32_t id, struct statvfs *st)
{
	Buffer msg;
	u_int64_t flag;

	flag = (st->f_flag & ST_RDONLY) ? SSH2_FXE_STATVFS_ST_RDONLY : 0;
	flag |= (st->f_flag & ST_NOSUID) ? SSH2_FXE_STATVFS_ST_NOSUID : 0;

	buffer_init(&msg);
	buffer_put_char(&msg, SSH2_FXP_EXTENDED_REPLY);
	buffer_put_int(&msg, id);
	buffer_put_int64(&msg, st->f_bsize);
	buffer_put_int64(&msg, st->f_frsize);
	buffer_put_int64(&msg, st->f_blocks);
	buffer_put_int64(&msg, st->f_bfree);
	buffer_put_int64(&msg, st->f_bavail);
	buffer_put_int64(&msg, st->f_files);
	buffer_put_int64(&msg, st->f_ffree);
	buffer_put_int64(&msg, st->f_favail);
	buffer_put_int64(&msg, FSID_TO_ULONG(st->f_fsid));
	buffer_put_int64(&msg, flag);
	buffer_put_int64(&msg, st->f_namemax);
	send_msg(&msg);
	buffer_free(&msg);
}

/* parse incoming */

static void
process_init(void)
{
	Buffer msg;

	version = get_int();
	verbose("received client version %u", version);
	buffer_init(&msg);
	buffer_put_char(&msg, SSH2_FXP_VERSION);
	buffer_put_int(&msg, SSH2_FILEXFER_VERSION);
	/* POSIX rename extension */
	buffer_put_cstring(&msg, "posix-rename@openssh.com");
	buffer_put_cstring(&msg, "1"); /* version */
	/* statvfs extension */
	buffer_put_cstring(&msg, "statvfs@openssh.com");
	buffer_put_cstring(&msg, "2"); /* version */
	/* fstatvfs extension */
	buffer_put_cstring(&msg, "fstatvfs@openssh.com");
	buffer_put_cstring(&msg, "2"); /* version */
	/* hardlink extension */
	buffer_put_cstring(&msg, "hardlink@openssh.com");
	buffer_put_cstring(&msg, "1"); /* version */
	/* fsync extension */
	buffer_put_cstring(&msg, "fsync@openssh.com");
	buffer_put_cstring(&msg, "1"); /* version */
	send_msg(&msg);
	buffer_free(&msg);
}

static void
process_open(u_int32_t id)
{
	u_int32_t pflags;
	Attrib *a;
	char *name;
	int handle, fd, flags, mode, status = SSH2_FX_FAILURE;

	name = get_string(NULL);
	pflags = get_int();		/* portable flags */
	debug3("request %u: open flags %d", id, pflags);
	a = get_attrib();
	flags = flags_from_portable(pflags);
	mode = (a->flags & SSH2_FILEXFER_ATTR_PERMISSIONS) ? a->perm : 0666;
	logit("open \"%s\" flags %s mode 0%o",
	    name, string_from_portable(pflags), mode);
	if (readonly &&
	    ((flags & O_ACCMODE) == O_WRONLY ||
	    (flags & O_ACCMODE) == O_RDWR)) {
		verbose("Refusing open request in read-only mode");
	  	status = SSH2_FX_PERMISSION_DENIED;
	} else {
		fd = open(name, flags, mode);
		if (fd < 0) {
			status = errno_to_portable(errno);
		} else {
			handle = handle_new(HANDLE_FILE, name, fd, flags, NULL);
			if (handle < 0) {
				close(fd);
			} else {
				send_handle(id, handle);
				status = SSH2_FX_OK;
			}
		}
	}
	if (status != SSH2_FX_OK)
		send_status(id, status);
	free(name);
}

static void
process_close(u_int32_t id)
{
	int handle, ret, status = SSH2_FX_FAILURE;

	handle = get_handle();
	debug3("request %u: close handle %u", id, handle);
	handle_log_close(handle, NULL);
	ret = handle_close(handle);
	status = (ret == -1) ? errno_to_portable(errno) : SSH2_FX_OK;
	send_status(id, status);
}

static void
process_read(u_int32_t id)
{
	char buf[64*1024];
	u_int32_t len;
	int handle, fd, ret, status = SSH2_FX_FAILURE;
	u_int64_t off;

	handle = get_handle();
	off = get_int64();
	len = get_int();

	debug("request %u: read \"%s\" (handle %d) off %llu len %d",
	    id, handle_to_name(handle), handle, (unsigned long long)off, len);
	if (len > sizeof buf) {
		len = sizeof buf;
		debug2("read change len %d", len);
	}
	fd = handle_to_fd(handle);
	if (fd >= 0) {
		if (lseek(fd, off, SEEK_SET) < 0) {
			error("process_read: seek failed");
			status = errno_to_portable(errno);
		} else {
			ret = read(fd, buf, len);
			if (ret < 0) {
				status = errno_to_portable(errno);
			} else if (ret == 0) {
				status = SSH2_FX_EOF;
			} else {
				send_data(id, buf, ret);
				status = SSH2_FX_OK;
				handle_update_read(handle, ret);
			}
		}
	}
	if (status != SSH2_FX_OK)
		send_status(id, status);
}

static void
process_write(u_int32_t id)
{
	u_int64_t off;
	u_int len;
	int handle, fd, ret, status;
	char *data;

	handle = get_handle();
	off = get_int64();
	data = get_string(&len);

	debug("request %u: write \"%s\" (handle %d) off %llu len %d",
	    id, handle_to_name(handle), handle, (unsigned long long)off, len);
	fd = handle_to_fd(handle);

	if (fd < 0)
		status = SSH2_FX_FAILURE;
	else {
		if (!(handle_to_flags(handle) & O_APPEND) &&
				lseek(fd, off, SEEK_SET) < 0) {
			status = errno_to_portable(errno);
			error("process_write: seek failed");
		} else {
/* XXX ATOMICIO ? */
			ret = write(fd, data, len);
			if (ret < 0) {
				error("process_write: write failed");
				status = errno_to_portable(errno);
			} else if ((size_t)ret == len) {
				status = SSH2_FX_OK;
				handle_update_write(handle, ret);
			} else {
				debug2("nothing at all written");
				status = SSH2_FX_FAILURE;
			}
		}
	}
	send_status(id, status);
	free(data);
}

static void
process_do_stat(u_int32_t id, int do_lstat)
{
	Attrib a;
	struct stat st;
	char *name;
	int ret, status = SSH2_FX_FAILURE;

	name = get_string(NULL);
	debug3("request %u: %sstat", id, do_lstat ? "l" : "");
	verbose("%sstat name \"%s\"", do_lstat ? "l" : "", name);
	ret = do_lstat ? lstat(name, &st) : stat(name, &st);
	if (ret < 0) {
		status = errno_to_portable(errno);
	} else {
		stat_to_attrib(&st, &a);
		send_attrib(id, &a);
		status = SSH2_FX_OK;
	}
	if (status != SSH2_FX_OK)
		send_status(id, status);
	free(name);
}

static void
process_stat(u_int32_t id)
{
	process_do_stat(id, 0);
}

static void
process_lstat(u_int32_t id)
{
	process_do_stat(id, 1);
}

static void
process_fstat(u_int32_t id)
{
	Attrib a;
	struct stat st;
	int fd, ret, handle, status = SSH2_FX_FAILURE;

	handle = get_handle();
	debug("request %u: fstat \"%s\" (handle %u)",
	    id, handle_to_name(handle), handle);
	fd = handle_to_fd(handle);
	if (fd >= 0) {
		ret = fstat(fd, &st);
		if (ret < 0) {
			status = errno_to_portable(errno);
		} else {
			stat_to_attrib(&st, &a);
			send_attrib(id, &a);
			status = SSH2_FX_OK;
		}
	}
	if (status != SSH2_FX_OK)
		send_status(id, status);
}

static struct timeval *
attrib_to_tv(const Attrib *a)
{
	static struct timeval tv[2];

	tv[0].tv_sec = a->atime;
	tv[0].tv_usec = 0;
	tv[1].tv_sec = a->mtime;
	tv[1].tv_usec = 0;
	return tv;
}

static void
process_setstat(u_int32_t id)
{
	Attrib *a;
	char *name;
	int status = SSH2_FX_OK, ret;

	name = get_string(NULL);
	a = get_attrib();
	debug("request %u: setstat name \"%s\"", id, name);
	if (a->flags & SSH2_FILEXFER_ATTR_SIZE) {
		logit("set \"%s\" size %llu",
		    name, (unsigned long long)a->size);
		ret = truncate(name, a->size);
		if (ret == -1)
			status = errno_to_portable(errno);
	}
	if (a->flags & SSH2_FILEXFER_ATTR_PERMISSIONS) {
		logit("set \"%s\" mode %04o", name, a->perm);
		ret = chmod(name, a->perm & 07777);
		if (ret == -1)
			status = errno_to_portable(errno);
	}
	if (a->flags & SSH2_FILEXFER_ATTR_ACMODTIME) {
		char buf[64];
		time_t t = a->mtime;

		strftime(buf, sizeof(buf), "%Y%m%d-%H:%M:%S",
		    localtime(&t));
		logit("set \"%s\" modtime %s", name, buf);
		ret = utimes(name, attrib_to_tv(a));
		if (ret == -1)
			status = errno_to_portable(errno);
	}
	if (a->flags & SSH2_FILEXFER_ATTR_UIDGID) {
		logit("set \"%s\" owner %lu group %lu", name,
		    (u_long)a->uid, (u_long)a->gid);
		ret = chown(name, a->uid, a->gid);
		if (ret == -1)
			status = errno_to_portable(errno);
	}
	send_status(id, status);
	free(name);
}

static void
process_fsetstat(u_int32_t id)
{
	Attrib *a;
	int handle, fd, ret;
	int status = SSH2_FX_OK;

	handle = get_handle();
	a = get_attrib();
	debug("request %u: fsetstat handle %d", id, handle);
	fd = handle_to_fd(handle);
	if (fd < 0)
		status = SSH2_FX_FAILURE;
	else {
		char *name = handle_to_name(handle);

		if (a->flags & SSH2_FILEXFER_ATTR_SIZE) {
			logit("set \"%s\" size %llu",
			    name, (unsigned long long)a->size);
			ret = ftruncate(fd, a->size);
			if (ret == -1)
				status = errno_to_portable(errno);
		}
		if (a->flags & SSH2_FILEXFER_ATTR_PERMISSIONS) {
			logit("set \"%s\" mode %04o", name, a->perm);
#ifdef HAVE_FCHMOD
			ret = fchmod(fd, a->perm & 07777);
#else
			ret = chmod(name, a->perm & 07777);
#endif
			if (ret == -1)
				status = errno_to_portable(errno);
		}
		if (a->flags & SSH2_FILEXFER_ATTR_ACMODTIME) {
			char buf[64];
			time_t t = a->mtime;

			strftime(buf, sizeof(buf), "%Y%m%d-%H:%M:%S",
			    localtime(&t));
			logit("set \"%s\" modtime %s", name, buf);
#ifdef HAVE_FUTIMES
			ret = futimes(fd, attrib_to_tv(a));
#else
			ret = utimes(name, attrib_to_tv(a));
#endif
			if (ret == -1)
				status = errno_to_portable(errno);
		}
		if (a->flags & SSH2_FILEXFER_ATTR_UIDGID) {
			logit("set \"%s\" owner %lu group %lu", name,
			    (u_long)a->uid, (u_long)a->gid);
#ifdef HAVE_FCHOWN
			ret = fchown(fd, a->uid, a->gid);
#else
			ret = chown(name, a->uid, a->gid);
#endif
			if (ret == -1)
				status = errno_to_portable(errno);
		}
	}
	send_status(id, status);
}

static void
process_opendir(u_int32_t id)
{
	DIR *dirp = NULL;
	char *path;
	int handle, status = SSH2_FX_FAILURE;

	path = get_string(NULL);
	debug3("request %u: opendir", id);
	logit("opendir \"%s\"", path);
	dirp = opendir(path);
	if (dirp == NULL) {
		status = errno_to_portable(errno);
	} else {
		handle = handle_new(HANDLE_DIR, path, 0, 0, dirp);
		if (handle < 0) {
			closedir(dirp);
		} else {
			send_handle(id, handle);
			status = SSH2_FX_OK;
		}

	}
	if (status != SSH2_FX_OK)
		send_status(id, status);
	free(path);
}

static void
process_readdir(u_int32_t id)
{
	DIR *dirp;
	struct dirent *dp;
	char *path;
	int handle;

	handle = get_handle();
	debug("request %u: readdir \"%s\" (handle %d)", id,
	    handle_to_name(handle), handle);
	dirp = handle_to_dir(handle);
	path = handle_to_name(handle);
	if (dirp == NULL || path == NULL) {
		send_status(id, SSH2_FX_FAILURE);
	} else {
		struct stat st;
		char pathname[MAXPATHLEN];
		Stat *stats;
		int nstats = 10, count = 0, i;

		stats = xcalloc(nstats, sizeof(Stat));
		while ((dp = readdir(dirp)) != NULL) {
			if (count >= nstats) {
				nstats *= 2;
				stats = xrealloc(stats, nstats, sizeof(Stat));
			}
/* XXX OVERFLOW ? */
			snprintf(pathname, sizeof pathname, "%s%s%s", path,
			    strcmp(path, "/") ? "/" : "", dp->d_name);
			if (lstat(pathname, &st) < 0)
				continue;
			stat_to_attrib(&st, &(stats[count].attrib));
			stats[count].name = xstrdup(dp->d_name);
			stats[count].long_name = ls_file(dp->d_name, &st, 0, 0);
			count++;
			/* send up to 100 entries in one message */
			/* XXX check packet size instead */
			if (count == 100)
				break;
		}
		if (count > 0) {
			send_names(id, count, stats);
			for (i = 0; i < count; i++) {
				free(stats[i].name);
				free(stats[i].long_name);
			}
		} else {
			send_status(id, SSH2_FX_EOF);
		}
		free(stats);
	}
}

static void
process_remove(u_int32_t id)
{
	char *name;
	int status = SSH2_FX_FAILURE;
	int ret;

	name = get_string(NULL);
	debug3("request %u: remove", id);
	logit("remove name \"%s\"", name);
	ret = unlink(name);
	status = (ret == -1) ? errno_to_portable(errno) : SSH2_FX_OK;
	send_status(id, status);
	free(name);
}

static void
process_mkdir(u_int32_t id)
{
	Attrib *a;
	char *name;
	int ret, mode, status = SSH2_FX_FAILURE;

	name = get_string(NULL);
	a = get_attrib();
	mode = (a->flags & SSH2_FILEXFER_ATTR_PERMISSIONS) ?
	    a->perm & 07777 : 0777;
	debug3("request %u: mkdir", id);
	logit("mkdir name \"%s\" mode 0%o", name, mode);
	ret = mkdir(name, mode);
	status = (ret == -1) ? errno_to_portable(errno) : SSH2_FX_OK;
	send_status(id, status);
	free(name);
}

static void
process_rmdir(u_int32_t id)
{
	char *name;
	int ret, status;

	name = get_string(NULL);
	debug3("request %u: rmdir", id);
	logit("rmdir name \"%s\"", name);
	ret = rmdir(name);
	status = (ret == -1) ? errno_to_portable(errno) : SSH2_FX_OK;
	send_status(id, status);
	free(name);
}

static void
process_realpath(u_int32_t id)
{
	char resolvedname[MAXPATHLEN];
	char *path;

	path = get_string(NULL);
	if (path[0] == '\0') {
		free(path);
		path = xstrdup(".");
	}
	debug3("request %u: realpath", id);
	verbose("realpath \"%s\"", path);
	if (realpath(path, resolvedname) == NULL) {
		send_status(id, errno_to_portable(errno));
	} else {
		Stat s;
		attrib_clear(&s.attrib);
		s.name = s.long_name = resolvedname;
		send_names(id, 1, &s);
	}
	free(path);
}

static void
process_rename(u_int32_t id)
{
	char *oldpath, *newpath;
	int status;
	struct stat sb;

	oldpath = get_string(NULL);
	newpath = get_string(NULL);
	debug3("request %u: rename", id);
	logit("rename old \"%s\" new \"%s\"", oldpath, newpath);
	status = SSH2_FX_FAILURE;
	if (lstat(oldpath, &sb) == -1)
		status = errno_to_portable(errno);
	else if (S_ISREG(sb.st_mode)) {
		/* Race-free rename of regular files */
		if (link(oldpath, newpath) == -1) {
			if (errno == EOPNOTSUPP || errno == ENOSYS
#ifdef EXDEV
			    || errno == EXDEV
#endif
#ifdef LINK_OPNOTSUPP_ERRNO
			    || errno == LINK_OPNOTSUPP_ERRNO
#endif
			    ) {
				struct stat st;

				/*
				 * fs doesn't support links, so fall back to
				 * stat+rename.  This is racy.
				 */
				if (stat(newpath, &st) == -1) {
					if (rename(oldpath, newpath) == -1)
						status =
						    errno_to_portable(errno);
					else
						status = SSH2_FX_OK;
				}
			} else {
				status = errno_to_portable(errno);
			}
		} else if (unlink(oldpath) == -1) {
			status = errno_to_portable(errno);
			/* clean spare link */
			unlink(newpath);
		} else
			status = SSH2_FX_OK;
	} else if (stat(newpath, &sb) == -1) {
		if (rename(oldpath, newpath) == -1)
			status = errno_to_portable(errno);
		else
			status = SSH2_FX_OK;
	}
	send_status(id, status);
	free(oldpath);
	free(newpath);
}

static void
process_readlink(u_int32_t id)
{
	int len;
	char buf[MAXPATHLEN];
	char *path;

	path = get_string(NULL);
	debug3("request %u: readlink", id);
	verbose("readlink \"%s\"", path);
	if ((len = readlink(path, buf, sizeof(buf) - 1)) == -1)
		send_status(id, errno_to_portable(errno));
	else {
		Stat s;

		buf[len] = '\0';
		attrib_clear(&s.attrib);
		s.name = s.long_name = buf;
		send_names(id, 1, &s);
	}
	free(path);
}

static void
process_symlink(u_int32_t id)
{
	char *oldpath, *newpath;
	int ret, status;

	oldpath = get_string(NULL);
	newpath = get_string(NULL);
	debug3("request %u: symlink", id);
	logit("symlink old \"%s\" new \"%s\"", oldpath, newpath);
	/* this will fail if 'newpath' exists */
	ret = symlink(oldpath, newpath);
	status = (ret == -1) ? errno_to_portable(errno) : SSH2_FX_OK;
	send_status(id, status);
	free(oldpath);
	free(newpath);
}

static void
process_extended_posix_rename(u_int32_t id)
{
	char *oldpath, *newpath;
	int ret, status;

	oldpath = get_string(NULL);
	newpath = get_string(NULL);
	debug3("request %u: posix-rename", id);
	logit("posix-rename old \"%s\" new \"%s\"", oldpath, newpath);
	ret = rename(oldpath, newpath);
	status = (ret == -1) ? errno_to_portable(errno) : SSH2_FX_OK;
	send_status(id, status);
	free(oldpath);
	free(newpath);
}

static void
process_extended_statvfs(u_int32_t id)
{
	char *path;
	struct statvfs st;

	path = get_string(NULL);
	debug3("request %u: statvfs", id);
	logit("statvfs \"%s\"", path);

	if (statvfs(path, &st) != 0)
		send_status(id, errno_to_portable(errno));
	else
		send_statvfs(id, &st);
        free(path);
}

static void
process_extended_fstatvfs(u_int32_t id)
{
	int handle, fd;
	struct statvfs st;

	handle = get_handle();
	debug("request %u: fstatvfs \"%s\" (handle %u)",
	    id, handle_to_name(handle), handle);
	if ((fd = handle_to_fd(handle)) < 0) {
		send_status(id, SSH2_FX_FAILURE);
		return;
	}
	if (fstatvfs(fd, &st) != 0)
		send_status(id, errno_to_portable(errno));
	else
		send_statvfs(id, &st);
}

static void
process_extended_hardlink(u_int32_t id)
{
	char *oldpath, *newpath;
	int ret, status;

	oldpath = get_string(NULL);
	newpath = get_string(NULL);
	debug3("request %u: hardlink", id);
	logit("hardlink old \"%s\" new \"%s\"", oldpath, newpath);
	ret = link(oldpath, newpath);
	status = (ret == -1) ? errno_to_portable(errno) : SSH2_FX_OK;
	send_status(id, status);
	free(oldpath);
	free(newpath);
}

static void
process_extended_fsync(u_int32_t id)
{
	int handle, fd, ret, status = SSH2_FX_OP_UNSUPPORTED;

	handle = get_handle();
	debug3("request %u: fsync (handle %u)", id, handle);
	verbose("fsync \"%s\"", handle_to_name(handle));
	if ((fd = handle_to_fd(handle)) < 0)
		status = SSH2_FX_NO_SUCH_FILE;
	else if (handle_is_ok(handle, HANDLE_FILE)) {
		ret = fsync(fd);
		status = (ret == -1) ? errno_to_portable(errno) : SSH2_FX_OK;
	}
	send_status(id, status);
}

static void
process_extended(u_int32_t id)
{
	char *request;
	u_int i;

	request = get_string(NULL);
	for (i = 0; extended_handlers[i].handler != NULL; i++) {
		if (strcmp(request, extended_handlers[i].ext_name) == 0) {
			if (!request_permitted(&extended_handlers[i]))
				send_status(id, SSH2_FX_PERMISSION_DENIED);
			else
				extended_handlers[i].handler(id);
			break;
		}
	}
	if (extended_handlers[i].handler == NULL) {
		error("Unknown extended request \"%.100s\"", request);
		send_status(id, SSH2_FX_OP_UNSUPPORTED);	/* MUST */
	}
	free(request);
}

/* stolen from ssh-agent */

static void
process(void)
{
	u_int msg_len, buf_len, consumed, type, i;
	u_char *cp;
	u_int32_t id;

	buf_len = buffer_len(&iqueue);
	if (buf_len < 5)
		return;		/* Incomplete message. */
	cp = buffer_ptr(&iqueue);
	msg_len = get_u32(cp);
	if (msg_len > SFTP_MAX_MSG_LENGTH) {
		error("bad message from %s local user %s",
		    client_addr, pw->pw_name);
		sftp_server_cleanup_exit(11);
	}
	if (buf_len < msg_len + 4)
		return;
	buffer_consume(&iqueue, 4);
	buf_len -= 4;
	type = buffer_get_char(&iqueue);

	switch (type) {
	case SSH2_FXP_INIT:
		process_init();
		init_done = 1;
		break;
	case SSH2_FXP_EXTENDED:
		if (!init_done)
			fatal("Received extended request before init");
		id = get_int();
		process_extended(id);
		break;
	default:
		if (!init_done)
			fatal("Received %u request before init", type);
		id = get_int();
		for (i = 0; handlers[i].handler != NULL; i++) {
			if (type == handlers[i].type) {
				if (!request_permitted(&handlers[i])) {
					send_status(id,
					    SSH2_FX_PERMISSION_DENIED);
				} else {
					handlers[i].handler(id);
				}
				break;
			}
		}
		if (handlers[i].handler == NULL)
			error("Unknown message %u", type);
	}
	/* discard the remaining bytes from the current packet */
	if (buf_len < buffer_len(&iqueue)) {
		error("iqueue grew unexpectedly");
		sftp_server_cleanup_exit(255);
	}
	consumed = buf_len - buffer_len(&iqueue);
	if (msg_len < consumed) {
		error("msg_len %u < consumed %u", msg_len, consumed);
		sftp_server_cleanup_exit(255);
	}
	if (msg_len > consumed)
		buffer_consume(&iqueue, msg_len - consumed);
}

/* Cleanup handler that logs active handles upon normal exit */
void
sftp_server_cleanup_exit(int i)
{
	if (pw != NULL && client_addr != NULL) {
		handle_log_exit();
		logit("session closed for local user %s from [%s]",
		    pw->pw_name, client_addr);
	}
	_exit(i);
}

static void
sftp_server_usage(void)
{
	extern char *__progname;

	fprintf(stderr,
	    "usage: %s [-ehR] [-d start_directory] [-f log_facility] "
	    "[-l log_level]\n\t[-P blacklisted_requests] "
	    "[-p whitelisted_requests] [-u umask]\n"
	    "       %s -Q protocol_feature\n",
	    __progname, __progname);
	exit(1);
}

int
sftp_server_main(int argc, char **argv, struct passwd *user_pw)
{
	fd_set *rset, *wset;
	int i, in, out, max, ch, skipargs = 0, log_stderr = 0;
	ssize_t len, olen, set_size;
	SyslogFacility log_facility = SYSLOG_FACILITY_AUTH;
	char *cp, *homedir = NULL, buf[4*4096];
	long mask;

	extern char *optarg;
	extern char *__progname;

	__progname = ssh_get_progname(argv[0]);
	log_init(__progname, log_level, log_facility, log_stderr);

	pw = pwcopy(user_pw);

	while (!skipargs && (ch = getopt(argc, argv,
	    "d:f:l:P:p:Q:u:cehR")) != -1) {
		switch (ch) {
		case 'Q':
			if (strcasecmp(optarg, "requests") != 0) {
				fprintf(stderr, "Invalid query type\n");
				exit(1);
			}
			for (i = 0; handlers[i].handler != NULL; i++)
				printf("%s\n", handlers[i].name);
			for (i = 0; extended_handlers[i].handler != NULL; i++)
				printf("%s\n", extended_handlers[i].name);
			exit(0);
			break;
		case 'R':
			readonly = 1;
			break;
		case 'c':
			/*
			 * Ignore all arguments if we are invoked as a
			 * shell using "sftp-server -c command"
			 */
			skipargs = 1;
			break;
		case 'e':
			log_stderr = 1;
			break;
		case 'l':
			log_level = log_level_number(optarg);
			if (log_level == SYSLOG_LEVEL_NOT_SET)
				error("Invalid log level \"%s\"", optarg);
			break;
		case 'f':
			log_facility = log_facility_number(optarg);
			if (log_facility == SYSLOG_FACILITY_NOT_SET)
				error("Invalid log facility \"%s\"", optarg);
			break;
		case 'd':
			cp = tilde_expand_filename(optarg, user_pw->pw_uid);
			homedir = percent_expand(cp, "d", user_pw->pw_dir,
			    "u", user_pw->pw_name, (char *)NULL);
			free(cp);
			break;
		case 'p':
			if (request_whitelist != NULL)
				fatal("Permitted requests already set");
			request_whitelist = xstrdup(optarg);
			break;
		case 'P':
			if (request_blacklist != NULL)
				fatal("Refused requests already set");
			request_blacklist = xstrdup(optarg);
			break;
		case 'u':
			errno = 0;
			mask = strtol(optarg, &cp, 8);
			if (mask < 0 || mask > 0777 || *cp != '\0' ||
			    cp == optarg || (mask == 0 && errno != 0))
				fatal("Invalid umask \"%s\"", optarg);
			(void)umask((mode_t)mask);
			break;
		case 'h':
		default:
			sftp_server_usage();
		}
	}

	log_init(__progname, log_level, log_facility, log_stderr);

	if ((cp = getenv("SSH_CONNECTION")) != NULL) {
		client_addr = xstrdup(cp);
		if ((cp = strchr(client_addr, ' ')) == NULL) {
			error("Malformed SSH_CONNECTION variable: \"%s\"",
			    getenv("SSH_CONNECTION"));
			sftp_server_cleanup_exit(255);
		}
		*cp = '\0';
	} else
		client_addr = xstrdup("UNKNOWN");

	logit("session opened for local user %s from [%s]",
	    pw->pw_name, client_addr);

	in = STDIN_FILENO;
	out = STDOUT_FILENO;

#ifdef HAVE_CYGWIN
	setmode(in, O_BINARY);
	setmode(out, O_BINARY);
#endif

	max = 0;
	if (in > max)
		max = in;
	if (out > max)
		max = out;

	buffer_init(&iqueue);
	buffer_init(&oqueue);

	set_size = howmany(max + 1, NFDBITS) * sizeof(fd_mask);
	rset = (fd_set *)xmalloc(set_size);
	wset = (fd_set *)xmalloc(set_size);

	if (homedir != NULL) {
		if (chdir(homedir) != 0) {
			error("chdir to \"%s\" failed: %s", homedir,
			    strerror(errno));
		}
	}

	for (;;) {
		memset(rset, 0, set_size);
		memset(wset, 0, set_size);

		/*
		 * Ensure that we can read a full buffer and handle
		 * the worst-case length packet it can generate,
		 * otherwise apply backpressure by stopping reads.
		 */
		if (buffer_check_alloc(&iqueue, sizeof(buf)) &&
		    buffer_check_alloc(&oqueue, SFTP_MAX_MSG_LENGTH))
			FD_SET(in, rset);

		olen = buffer_len(&oqueue);
		if (olen > 0)
			FD_SET(out, wset);

		if (select(max+1, rset, wset, NULL, NULL) < 0) {
			if (errno == EINTR)
				continue;
			error("select: %s", strerror(errno));
			sftp_server_cleanup_exit(2);
		}

		/* copy stdin to iqueue */
		if (FD_ISSET(in, rset)) {
			len = read(in, buf, sizeof buf);
			if (len == 0) {
				debug("read eof");
				sftp_server_cleanup_exit(0);
			} else if (len < 0) {
				error("read: %s", strerror(errno));
				sftp_server_cleanup_exit(1);
			} else {
				buffer_append(&iqueue, buf, len);
			}
		}
		/* send oqueue to stdout */
		if (FD_ISSET(out, wset)) {
			len = write(out, buffer_ptr(&oqueue), olen);
			if (len < 0) {
				error("write: %s", strerror(errno));
				sftp_server_cleanup_exit(1);
			} else {
				buffer_consume(&oqueue, len);
			}
		}

		/*
		 * Process requests from client if we can fit the results
		 * into the output buffer, otherwise stop processing input
		 * and let the output queue drain.
		 */
		if (buffer_check_alloc(&oqueue, SFTP_MAX_MSG_LENGTH))
			process();
	}
}

redpajama_set_name: RedPajamaGithub


text:
Probletomus maculipennis är en insektsart som beskrevs av Gerstaecker 1895. Probletomus maculipennis ingår i släktet Probletomus och familjen Nogodinidae. Inga underarter finns listade i Catalogue of Life.

Källor

Halvvingar
maculipennis

redpajama_set_name: RedPajamaWikipedia


text:
PAIN OF BEING REJECTED
Between two cultures: What happens to the psyche of an Indian child born and raised in the West
Indian children born in the US sometimes face criticism for stepping outside the bounds of what's normally acceptable in their heritage culture.
Image: AP Photo/Channi Anand
Nelli Ferenczi
What is the recipe for long-term happiness? One crucial ingredient cited by many people is closeness in their social relationships. Very happy people have strong and fulfilling relationships. But if we feel rejected by those who are closest to us—our family and friends—it can sour our attempts to master the recipe for happiness.
Bi-cultural people, who identify with two cultures simultaneously, are particularly vulnerable to this kind of rejection. A person can become bi-cultural by moving from one country to another, or if they are born and raised in one country by parents who came from elsewhere. For example, for a child born and raised in London by Russian parents, Russian will be what's called their "heritage culture."
Research has shown that being bi-cultural is a tremendously beneficial trait because it makes us more flexible and creative in our thinking. But bi-cultural people may experience their upbringing as the collision of multiple worlds. They sometimes face criticism for stepping outside the bounds of what's normally acceptable in their heritage culture. This happens in the recent film The Big Sick. Kumail Nanjiani, a Pakistan-born man living in the US, falls in love with grad student Emily Gordon rather than following his parents' wishes and marrying someone from their culture.
This experience of rejection from one's heritage culture is referred to as "intragroup marginalisation." People experience this when they adapt to a new culture in ways that are deemed to be a threat to their cultural origins.
Jesminder Bhamra, the British-Asian protagonist in the film Bend it Like Beckham is banned by her parents from playing football, a sport deemed too British and not befitting a young woman in their eyes. As "Jess" pursues her dream in secret, she feels unhappy and torn between her two identities. Her experience, similar to many bi-cultural people, highlights an important aspect of identity construction. They may wish to identify with their parents' culture, but feel that they are barred from it by family or friends. They may even feel that they are betraying their heritage culture.
In our ongoing research, we are looking at ways that people can cope and overcome experiences of rejection from their heritage culture.
To understand this painful experience, other research has looked at whether personality traits, such as attachment style, can make a person more likely to feel intragroup marginalisation. Attachment style shapes how we interact with others in our relationships. A securely attached person sees themselves as worthy of love and others as trustworthy, while somebody who is insecurely attached can be anxious and sensitive to threats of rejection. They can also avoid and feel uncomfortable with closeness and intimacy.
Insecurely attached bi-cultural people tend to report greater marginalisation from their friends and family. This may be because they are sensitive to rejection and perceive themselves as failing to uphold the traditions expected of them by their heritage culture. For example, a second-generation Bangladeshi in Britain may feel ashamed at not being able to speak Bengali very well, or a Hungarian who moved to Britain may feel that their values have changed.
Another key personality trait reflects how individuals perceive their sense of self in relation to others. We can see our self as being independent and unique from others, and as having a high sense of agency. Alternatively, we can see ourselves as being interdependent with others and fluid, changing based on the situation.
Research has found that people who have a more fluid sense of self are less likely to feel rejected from their heritage culture, compared to those who have an independent sense of self. This is because they are better able to reconcile both their cultural identities without experiencing conflict.
Having a more fluid sense of self is also linked with a greater flexibility to tailor our responses and behavior to different social situations. This means these people may find it easier to choose which parts of their identity are appropriate in any given situation. So they may identify with the same values as their family when cooking traditional dishes and eating dinner at home, and another set of values when playing football with their friends. They may be more ready to accept that they can identify with both cultures, without compromising their authenticity.
Being pushed out is painful
Those who feel rejected from their heritage culture can be left feeling alone and unsupported. This has been linked with depressive symptoms, poor well-being, and greater stress. It can also leave people feeling as if their two cultural identities are in conflict with each other.
One of our research studies in 2015 surveyed people from a wide range of heritage cultures about their experiences of intragroup marginalisation. We found that those who perceived that they had been rejected by friends were more likely to agree with extreme attitudes in defense of their heritage culture, such as fighting someone who insults it or even dying for it. One reason may be that this is a way of alleviating uncertainty and reaffirming one's cultural identity.
Marginalisation may appear to be subtle—a gentle scolding about what typical members of a person's family or friends should act like, a teasing comment about an accent—but its persistence can wear down individuals, unsettling relationships, and having a negative impact on well-being.
Nelli Ferenczi, teaching fellow in psychology, Goldsmiths, University of London, and Tara Marshall, lecturer in psychology, Brunel University London. This article was originally published on The Conversation. Read the original article.

redpajama_set_name: RedPajamaCommonCrawl


The 2009 Cashiers Designer Showhouse provided an abundance of stylish and eco-friendly decorating ideas.
With this year's Cashiers [North Carolina] Designer Showhouse just a month away (it's being held August 25 through September 5), Atlanta Homes & Lifestyles is looking back at last year's successful tour, which benefited the Zachary Tolbert House and the Cashiers Historical Society.
Last year's showhouse saw record-breaking numbers in terms of attendance and fundraising; pent-up demand to see the home was so strong that more than 400 people turned out on opening day. And while proceeds annually benefit the Zachary Tolbert House and the care of its grounds as well as its staff and dozens of community projects—including Pioneer Days, chamber music concerts and symposiums about its curatorial work—last year's tour allowed the Cashiers Historical Society to make an additional donation of $28,000 to the Cashiers Valley Community Council.
The 2009 home had a "green" theme. Not only did all of the rooms feature eco-friendly design ideas but some of the green movement's most celebrated players also turned out to talk about eco-friendly lifestyles. Two of Atlanta's leading ecovangelists, Laura Turner Seydel and Jillian Pritchard Cooke, headlined the first weekend with a green message that has been at the forefront of Atlanta's design consciousness, but is not yet so evident in the mountains. Celebrated Atlanta chef Ann Quatrano (of Star Provisions, Bacchanalia and Floataway Café fame) created a special luncheon, followed by a presentation about her own farm, its joys as the backbone to her restaurants and the importance of locally grown foods making a quiet footprint as they find their ways to local tables.
The 2010 Cashiers Designer Showhouse, to be held inside the prestigious Wade Hampton golf community, will again feature a top-notch group of Southeastern design talents, including several participants from Atlanta—Bob Brown, Suzanne Kasler, Bill Peace and Carole Weaks. For more information, see the program in next month's issue of Atlanta Homes & Lifestyles or visit cashiershistoricalsociety.org.


text:
A CLASS ABOVE: PEUGEOT 3008
Autolife Test Drive
Volume 6 Issue 11
Posted On: May 3, 2018 By : AutoLife Team
The Peugeot brand has been in Nepal for a long time, but it wasn't operating as a proper dealership with their imports being on and off. But now that has changed, Peugeot has opened a proper showroom in Thapathali, Kathmandu. The Peugeot 3008 is one of the 4 models on offer at the showroom currently and we were given the task to see just how good the French iteration was in the highly contested mid-sized SUV segment.
Peugeot have made a giant leap in terms of designing the 3008. Compared to the previous generation 3008, saying that the present 3008 looks better would be an understatement. From the boring simple design to the new futuristic and bold design, it's night and day between the two generations. Peugeot have made sure that there isn't a bad angle on the 3008 and it looks absolutely beautiful from all sides. The front of the 3008 has been given the aggressive treatment with a bold new grille with the lion (Peugeot crest) in the center.
The body panels cut into the headlights like a fang, which separates the high beam and the low beam units. Running over the head light is the LED DRLs (Day time Running Lamps) which doubles as the turn indicators. While the GT line gets all LED headlights and the allure variant gets the conventional halogen headlights.
The side profile of the vehicle is given a smooth flowing design which is contrasted by the 18 inch rims, the diamond cut rims has been shaped as a star with the 5 spoke design. The roof gets a contrasting black finish along with the C pillars to give it a floating look.
Moving to the back of the 3008, the taillight is separated into 3 vertical lines each which gives it a very distinguishable look. There is a lot of chrome work done on the vehicle, the front lip, the grille, the doors and the rear bumper are the most prominent along with the chrome exhaust tips.
The Peugeot 3008, hands down, has the best interior in this segment of vehicles. Like the exterior of the car, the interior also has been taken to new heights compared to the previous Gen 3008. Peugeot have tried to pull off an airplane's cockpit style design which they have managed to do. It is a very driver focused cabin. All the buttons on the top half of the dash has been given a airplane like switch which you push down to activate, while the other buttons are finished in black to blend into the dash.
This however makes it difficult at times to locate the buttons with the fact that it is blended in so nicely. The GT line gets nappa leather seats with the heated functions in the front seats. While the driver's side seats get the massage function and the electronically adjustable seats but the other seats miss out on this feature. The small steering wheel gives it a very sporty feel. The 3008 gets a digital instrument cluster as standard, it looks very crisp with its display quality. The touch screen infotainment system is mounted on the top of the dash. While it looks out of place on most other cars, Peugeot have managed to integrate that with the dash. The black roof was not just done aesthetically as there is an all glass panoramic sunroof and moon roof present on the car.
Peugeot have filled the 3008 to the brim with features and while we can't talk about all the features in this review, we will mention the ones that caught our eyes the most. Starting off with the approach lights, there is a LED light mounted on the mirror which lights up when you open the door, this is done so that you do not step into a puddle or anything nasty while getting in or out of the car. While the allure variant gets normal LED lights, the GT line gets the Peugeot lion crest illuminating the ground.
After entering the vehicle you are welcomed by the big digital instrument cluster which can be personalized into showing what you want. Then comes the massaging function of the driver's seat, there are different options for which you can select what type of massage you want and the intensity of the massage. My personal favorite was the cat paw, which felt like a cat massaging your back with its paws minus the nails. There is a fragrance dispenser in the vehicle that lets out fragrance as you program it to. On top of that there is blue mood lighting that illuminates the foot well, front door panels, cup holders etc., according to your mood. The view out the back is a little small due to the sloping roof, so in order to eliminate that blind spot Peugeot have equipped the 3008 with 180 reversing camera and parking sensors.
PERFORMANCE AND DRIVING
The engine that powers the 3008 is a 1.6L e-THP Petrol engine producing 165 hp @6000 RPM and 240 Nm of torque @ 1400 RPM mated to a 6 speed automatic gearbox. The gear shifter is different than the ones usually present in other automatic transmission. The shifter unlike the conventional shifter doesn't slide forward or back, it has to be rocked forward or back depending on what gear you want to engage. There is also an unlock button that you have to press while switching gears while removing the car from parking mode, you also have to press the unlock button while putting it into reverse to reduce the chance of you accidentally switching into the reverse gear.
But to be honest this kind of shifting gets tiresome after some time because you have to rock back the gear lever 3 times to get it into the drive mode from parking mode. The 165 hp of the car doesn't feel as prominent in the normal mode as it does in the sport mode. The responce is much quicker in the sport mode and definitely feels more powerful. The exhaust note of the car also got noticeably louder when in the sport mode, I was amazed at the fact of how they engineered a 1.6l inline four engine to sound so different just at the push of a button and thought it was too good to be true.
And it actually was because after a while of driving in the sport mode I found out that the sound of the engine was being artificially produced and were being emitted from the speakers. The small steering wheel does give it a sportier feel while driving and gives you the confidence to push it a bit harder. The addition of paddle shifters make it that much more fun to drive when you want to take over the job of shifting gears, the auto tends to shift a little early so if you want to extract all of the 165 horsepower you will have to take over the shifting duty. The paddle shifters behind the steering wheel is fixed on the spot rather than spinning with the steering wheel. The brakes feel very strong and will rock you front and back if you abuse it.
The Peugeot 3008 starts off from Npr. 1,13,00,000/- for the allure and Npr. 1,19,00,000/- for the GT line. It is a bit pricier than its Korean rivals and is almost on par with its Japanese rivals while it's cheaper than the German offerings. With an interior that cannot be compared to others in the segment and a good driving experience the Peugeot 3008 proves to be a real threat in taking over the coveted top spot of the mid-sized SUVs.
MAKING A BOLD STATEMENT | FORD ASPIRE
Ford took almost 2 years to introduce the new Aspire, and all for the good reasons. The updated car looks more muscular and sophisticated with its bulked up body frame and headlights. The car has evolved in terms of technology as well; Rain-sensing wipers, automatic headlamps, an auto-dimming rearview mirror, power adjust and fold for […]


Hi! Sign in to let us know how Last Hope Inc was?
I wanted to adopt a dog from this organization but the several people I dealt with were rude and very unhelpful.
Pet rescue is an admirable cause but I have never had to interact with such unprofessional people in my life.
If you've been to or used Last Hope Inc, leave a review.


text:
Berekum
September weather forecast and climate
Berekum, Ghana
ClimateJFMAMJJASeptemberONDYear
Weather in Septiembre
Average temperature in September
Average rainfall in September
Average daylight in September
Septiembre, the first month of the autumn, in Berekum, is still a warm month, with average temperature fluctuating between 29.9°C (85.8°F) and 14.8°C (58.6°F).
The coldest month is Septiembre, with an average high-temperature of 29.9°C (85.8°F) and an average low-temperature of 14.8°C (58.6°F).
In Berekum, 61mm (2.4") of precipitation is typically accumulated. During the entire year, Berekum aggregates up to 485mm (19.09") of precipitation.
In Berekum, the average length of the day in Septiembre is 12.2h.
What is the coldest month in Berekum?
With an average high-temperature of 29.9°C (85.8°F) and an average low-temperature of 14.8°C (58.6°F), Septiembre is the coldest month in Berekum, Ghana.
What is the temperature in Septiembre in Berekum?
In Berekum, in Septiembre, the average high-temperature is 29.9°C (85.8°F), and the average low-temperature is 14.8°C (58.6°F).
How much does it rain in Berekum in Septiembre?
Throughout Septiembre, in Berekum, 61mm (2.4") of precipitation is accumulated.
How many hours of daylight does Berekum have in Septiembre?
Average high temperature in September: 29.9°C
The warmest month (with the highest average high temperature) is October (46°C).
The month with the lowest average high temperature is September (29.9°C).
Average low temperature in September: 14.8°C
The month with the highest average low temperature is February (18.1°C).
The coldest month (with the lowest average low temperature) is June (13.8°C).
Average rainfall in September: 61mm
The wettest month (with the highest rainfall) is May (89mm).
Driest months (with the lowest rainfall) are January and December (8mm).
Average daylight in September: 12.2h
Months with shortest days are January and December (Average daylight: 11.7h).
Weather Atlas: Berekum, Ghana - September weather forecast and climate information. Berekum, Ghana - September weather averages including high and low temperatures, humidity, rainfall, snowfall, daylight, sunshine, UV index, and sea temperature. [782968]


Dr. Lorri Lankiewicz is not only a Doctor of Physical Therapy, but also a Natural Nutrition Consultant and Personal Wellness Coach.
She is now offering nutritional and wellness consultations to initiate or enhance your journey towards practicing whole health.
Get started with our FREE standard process systems online survey!
All consultations and survey results are kept confidential. Email us at bfwoffice2@zoominternet.net for your personalized login information to take the survey and begin your path to proper nutrition!


So 4 years ago McGyver ( my hubby- we call him that because he can fix almost anything, with anything) and I celebrated our 30th Anniversary in Arizona. We explored Phoenix, we visited aviation museum and hiked in Tucson, we then headed to Sedona for days of hiking and enjoying the energy, scenery and all celebrated this milestone of our journey together.
In Sedona we decided one day to take this 5 mile hike in and out to Devils Bridge. Sounded like a good idea at the time. It was actually a very nice hike and we walked and talked and drank lots of water and slathered on sunblock and lip balm! We saw beautiful vistas and rock formation and actually not many hikers but the ones we met along the way ( and their dogs) were quite lovely humans.
So we finally make it to this Devils Bridge and we see folks walking out there, 400 feet up, out on this skinny little stretch of rock! Me, being afraid of heights said, no way. So, we sat and watched others go out, some terrified, others laughing and having fun with it.
I finally sent my husband out there alone, I couldn't do it. I would just take his picture and then we could go. He went, I took pictures. I was scared for him, "don't go that far" I yelled.
He came back happy and full of confidence. I finally decided I should face my fear and go. Of course he had to go back with me. We got others to take our picture. It was frightening, but I did it. I felt so empowered to feel the fear and do it anyway. I have many times "jumped" into things feeling the fear, feeling unprepared and yet somehow I figured it out.
Sometimes we need take risks, do scary things to remind ourselves that we CAN do hard things and things that frighten us. We can do them scared. Get a friend and go do that scary thing.


Providing empowering solutions to the world's researchers, clinicians and engineers takes the efforts of dedicated, creative professionals in marketing, sales and people management. Our global reach provides unparalleled opportunities for enterprising individuals who enjoy the challenge of understanding and penetrating new markets, working with prestigious multinational customers and collaborating on the development of new approaches to serving these key industries.
Why join our business & commercial teams?
As a global market leader, Elsevier offers a wide variety of challenging careers and advancement opportunities in a creative environment that will help you to develop as a professional and achieve an optimum career-life balance.
Build your career the way you want in a company of more than 7000 employees with opportunities around the world. Work with the best minds in science and health at an organisation that believes in promoting from within.
We create opportunities for our people to meet through social events and to give back to the community through our RE Cares programme.


If you're searching for airfare from Halifax to Comox, look no further than WestJet. We have flights that take off and land all across North America, Central America, the Caribbean and Europe, including CFB Comox, which is the reason you can always turn to us to get to where you need to be. We're committed to providing our guests with the best possible experiences, with safe, affordable and friendly travel. Browse our airfare today.
In Comox, the stunning nature of Vancouver Island is always readily apparent. Its excellent seaside location comes with associated activities like fishing and kayaking, while the Toast Comox Valley festival gives visitors the chances to taste local delicacies. Best yet, not too far away is Strathcona Provincial Park, where visitors will find the majestic Della Falls.
Your trip to British Columbia's most laidback and admirable destination starts when you book your airfare. Enjoy swift, safe air travel from Halifax to Comox with WestJet — and then get down to the serious business of enjoying the likes of Heritage Air Park, Crown Isle Resort Golf Course or Courtenay & District Museum.


text:
You are here: Parliament home page > Parliamentary business > Bills and legislation > Bills before Parliament > Commons Amendments
Amendments proposed to the Local Government Bill [Lords] - continued House of Commons
Mr Nigel Waterson
Sir Paul Beresford
Mr David Curry
Mr Peter Atkinson
Mr Tim Loughton
Clause 38, page 23, leave out line 33.
Clause 38, page 23, line 34, leave out subsection (3).
Mr Don Foster
Mr Adrian Sanders
Clause 38, page 23, line 35, leave out 'supplementary' and insert 'alternative'.
Schedule 2, page 70, line 34, leave out from beginning to end of line 4 on page 71 and insert—
'(2) The candidate with the fewest number of first preference votes is eliminated, and the second preference votes given for the candidate shall be ascertained.
(3) The second preference votes under sub-paragraph (2) above shall be transferred to the other candidates, being added to the first preference votes cast for the other candidates.
(4) If, following the re-calculation under sub-paragraph (3) above, none of the candidates receives more than half of the votes, the remaining candidate with the fewest number of votes is eliminated and the procedure in sub-paragraphs (2) and (3) above is carried out.
(5) The process continues until one candidate has received more than half of all the votes, and that person shall be returned as mayor.'.
Page 70, line 21, leave out Schedule 2.
Hilary Armstrong
Clause 39, page 23, line 37, after 'election' insert 'for the return'.
Clause 39, page 24, line 1, leave out subsection (2).
Clause 39, page 24, line 1, leave out from 'first' to second 'preference' in line 2.
Clause 40, page 24, line 9, at end insert 'and
(c) the recall of the mayor in the event of a loss of confidence and the filling of a casual vacancy.'.
(c) the recall of the mayor in the event of incapacity or of a loss of confidence and the filling of the vacancy arising'.
Clause 40, page 24, line 14, leave out 'the election expenses of candidates' and insert 'election expenses'.
Clause 40, page 24, line 26, after first 'or' insert 'any provision of'.
Clause 40, page 24, line 26, after 'enactment' insert '(whenever passed or made)'.
Clause 40, page 24, line 33, at end insert 'or under'.
Clause 40, page 24, line 35, leave out 'or made under'.
Clause 41, page 24, line 43, at end insert—
'( ) If the result of a referendum held by virtue of regulations or an order made under any provision of this Part is to approve the proposals to which the referendum relates, the local authority concerned must implement those proposals in accordance with any provision made by the regulations or order.
( ) If the result of a referendum held by virtue of regulations or an order made under any provision of this Part is to reject the proposals to which the referendum relates, the local authority concerned may not implement those proposals but must instead comply with any provision made by the regulations or order.'.
Clause 41, page 25, line 8, leave out 'made by or under' and insert 'of'.
Clause 41, page 25, line 9, after 'enactment' insert '(whenever passed or made)'.
Clause 41, page 25, leave out line 12 and insert '(a) for independent scrutiny of the question to be asked in a referendum'.
'( ) about the limitation of expenditure in connection with a referendum (and the creation of criminal offences in connection with the limitation of such expenditure),'.
Clause 41, page 25, line 18, leave out paragraph (d) and insert—
'( ) as to when, where and how voting in a referendum is to take place,
( ) as to how the votes cast in a referendum are to be counted, and'.
Clause 41, page 25, leave out lines 18 and 19.
Clause 41, page 25, line 21, leave out 'this section' and insert 'subsections (1), (2) to (4) and (6)'.
Clause 41, page 25, line 22, leave out 'or 28'.'
Clause 41, page 25, line 22, leave out 'under section 31 or 32' and insert 'or an order made under any provision of this Part'.
Clause 42, page 25, line 27, leave out 'of' and insert 'made by or under'.
'(2) The provision which may be made under subsection (1) includes provision modifying any enactment (whenever passed or made).
(3) The power under subsection (2) to modify an enactment is a power—
(a) to apply that enactment with or without modifications,
(b) to extend, disapply or amend that enactment, or
(c) to repeal or revoke that enactment with or without savings.'.
Page 25, line 28, leave out Clause 43.
Clause 44, page 25, leave out lines 40 to 43.
Clause 44, page 26, line 5, at end insert—
' "enactment" includes an enactment contained in a local Act or comprised in subordinate legislation (within the meaning of the Interpretation Act 1978),"'.
Clause 44, page 26, line 44, leave out third 'of' and insert 'made by or under'.
'( ) Any functions conferred on a local authority by virtue of this Part are not to be the responsibility of an executive of the authority under executive arrangements.'.
NEW CLAUSES RELATING TO PART II
Additional forms of executive
To move the following Clause:—
'.—(1) In deciding whether to make regulations under section 11(6) prescribing a particular form of executive, or which provision to make under section 16 in relation to that form of executive, the Secretary of State must have regard to—
(a) any proposals made to him under subsection (2),
(b) the extent to which he considers that the operation by a local authority of executive arrangements involving that form of executive would be likely to ensure that decisions of the authority are taken in an efficient, transparent and accountable way,
(c) the extent to which that form of executive differs from the forms of executive for the time being permitted by or under section 11,
(d) the number and description of authorities for which he considers that that form of executive, if prescribed in regulations made under section 11(6), would be an appropriate form of executive to consider.
(2) For the purposes of subsection (1), a local authority may propose to the Secretary of State a form of executive in relation to which the authority consider that the conditions mentioned in subsection (3) are satisfied.
(3) Those conditions are—
(a) that the operation by the authority of executive arrangements involving that form of executive would be an improvement on the arrangements which the authority have in place for the discharge of their functions at the time that the proposal is made to the Secretary of State,
(b) that the operation by the authority of executive arrangements involving that form of executive would be likely to ensure that decisions of the authority are taken in an efficient, transparent and accountable way, and
(c) that that form of executive, if prescribed in regulations made under section 11(6), would be an appropriate form of executive for all local authorities, or for any particular description of local authority, to consider.
(4) A proposal under subsection (2)—
(a) must describe the form of executive to which it relates,
(b) must describe the provision which the authority consider should be made under section 16 in relation to that form of executive, and
(c) must explain why the authority consider that the conditions mentioned in subsection (3) are satisfied in relation to that form of executive.'.
©Parliamentary copyright 2000
Prepared 16 May 2000


Lacco Ameno is a town and comune situated in the northwest of the island of Ischia, in the Gulf of Naples off the west coast of Italy. The town has a population of around 4,600 inhabitants. It is located at the feet of the Mount Epomeo, facing the sea. The name most likely derives from the Greek lakkos, meaning 'stone'. The name ameno was added to the official name in 1862. Lacco Ameno is home to an 11th-century church, built over a pre-existing Palaeo-Christian edifice. The Museum of Santa Restituta houses several prehistorical findings and Greek ceramics from the 8th-2nd centuries BC.
By plane Once arrived at the International Airport of Naples, you can reach by taxi or bus, the Beverello port (ferries Lauro Lines, Caremar), the terminal Mergellina (hydrofoils Lauro Lines, SNAV), the port of Pozzuoli (Ferry Medmar Caremer). Forio, Ischia is reached in a few minutes from the port of Ischia and once in Ischia you can use buses, taxis and microtaxi. By train The main railway stations of Naples: Central Station, Piazza Garibaldi Station Napoli-Mergellina. Once arrived at Stazione Centrale, you can reach by taxi, bus or tram passing in front of the station, the Beverello port which is situated about 2 km to the joints port if you decide to embark on a ferry or hydrofoil to the Island. The crossing is approximately 90 minutes by ferry and 40 minutes by hydrofoil.


text:
Everyone is a Ragged University - a unique and distinct body of knowledge, accredited by their life experience and in a membership of one
Eclectic Articles
Do A Talk
Science Primers
Mad World Archive
Edinburgh Settlement
Drugs and Recovery
Outcomes and Measures
10th Oct 2015: Daddy's Daughters and Sons; Perspectives on Male Factor Infertility Treatments and Trends by Dr Ruby Raheem
Come along to The Central Library at 2pm (George Washington Browne Conference Room which is one floor down from the front entrance) to listen to Ruby's talk. There will be some food provided and an opportunity to socialise…
Title of talk:
Daddy's Daughters and Sons: Perspectives on Male Factor Infertility, Treatments and Trends
Bullet points of what you would like to talk about:
Infertility trends around the world.
History of human infertility treatment.
What is male factor infertility?
Male factor infertility trends
Causes of male factor infertility
Male factor infertility treatments
Daddy's daughters and sons
Complexities and ethics of embryo usage and surrogacy
I became interested in the social aspects of infertility and started looking into related news and publications during my research at Edinburgh University. I hope the talk will help to raise awareness and compassion towards those suffering from infertility.
A few paragraphs on your subject:
Infertility is the inability to have children and affects ~15% of couples worldwide. Some of these couples, with the help of health clinics, have succeeded in having babies. Infertility is not an illness. Many couples experience intense emotional need to have a baby. In some parts of the world, the social and community pressure on the childless couple can be overwhelming.
Certain sexually transmitted diseases cause infertility and used to be a major cause of infertility in the underdeveloped world. Many couples in the developed world focus on career earlier in their lives and start a family much later. Today, infertility is a growing worldwide trend affecting young and older couples.
Infertility is as old as civilisation and treatment records go back in time by a few thousand years. Gods, magic, priests and medicine men/women played a major role in the treatment of infertility of both men and women in Egypt. The ancient civilisations of Greece, China and India had their own concepts and cure for infertility.
Although historically, women have been the torchbearers of fertility, the egg and the sperm have equal roles in the success of a pregnancy. Male factor infertility is on the rise in the developed and developing world; lifestyle, exposure to certain types of plastics, environmental pollution, smoking, drinking, cancer and age are attributed to the rising male factor infertility trends in the world today.
According to folklores, the first human artificial insemination (AI) happened in the15th century. The history of medical intervention in assisting a couple to have a baby is nearly 300 years old. John Hunter, a Scottish surgeon, was the first person to attempt AI on a couple, successfully. Several medical attempts and a few success stories from the 1800s are found in the medical journals of the 20th century. Modern infertility treatments requiring sophisticated equipment and trained clinical doctors and technicians, date back to mid-1900s.
With the birth of the first test tube baby in July 1978, infertility treatment has been publicly accepted in the West. Australia had its first test tube baby in 1980 and the US in 1981. Interestingly, the world's second test tube baby was born without fanfare in India, 67 days after the world's first test tube baby – in October 1978. The doctor committed suicide in 1981.
Fertility clinics are found in every nation in the 21st century and artificial reproductive technology (ART) is a multi-billion dollar industry. There are over 5 million IVF babies in the world today. What are some of the complexities and social responsibilities associated with IVF? Do come along to find out more about ART and society.
A few paragraphs about you:
I am originally from south India and have an academic background in Physics and Optics. After postgraduate studies and a decade long R&D career in the high tech industries (AMD and Corning) in the US, I came to the UK and pursued a career in academia – optical computing and 3-d imaging. At the University of Edinburgh, I researched DNA health of live cells, using Raman spectroscopy and optical tweezers. Even though the biology was new to me, I became fascinated by the topics related to 'life' and 'health'. Probing embryo and foetal development is not vastly different from the quests of physics – the languages can be a bit confusing, but they both explore the 'origin of life', albeit differently.
What free internet knowledge resources would you recommend to others if they wish to explore your chosen theme further?
Read the newspaper for current topics
Google search will bring up many topics related to infertility
NHS and other health services around the world, fertility clinics and World Health Organisation reports also provide details on the subject.
What are your weblinks?
LinkedIn: https://uk.linkedin.com/pub/ruby-raheem/1a/aa9/822
Click For Event Listing
Ragged Talks
Fertility, Infertility, Male, Ruby Raheem
Working Mens Clubs and Educati…Working Mens C…A Note On The Senses: Common S…A Note On The…
The City of Thieves: A Digest and Perversion of R. D. Laing
Rajasthan's Thar Desert and its Environment by Bob Cranwell
16th Jan 2020: The Extended Mind talk and tour at Talbot Rice Gallery by James Clegg
Twas The Rant Before Christmas: Absent Friends and Being Absent as a Friend
Winding up Ragged SCIO as a Charity: Miles and Miles to go Before I Sleep…
The Importance of Music Within Society by Daniel Zambas
Education History: A Brief History of Ragged Schools
Hypothesis, Theory, Model and Law
The Sociology of Education: A Durkheimian View
Social Capital and Pierre Bourdieu: A Digest
Inspector Rosenhan Visits The Asylum
Development as Freedom: The Human Capabilities Approach
The Origin of Hippie in Europe 1880 to 1940 by Anne Hill Fernie
About Ragged University
Other Archives
Interesting Projects
The Porous University
COOCs
Chat on Twitter with @raggedtalks
RT @carolecadwalla: Important piece by Nobel prize winner @JosephEStiglitz on the bankrupt logic of Facebook's decision to facilitate & spr…
RT @Public_Citizen: Weeks of paid leave for mothers:
🇪🇪 166
🇸🇰 164
🇫🇮 161
🇭🇺 160
🇱🇻 94
🇳🇴 91
🇰🇷 65
🇨🇿 63
🇱🇹 62
🇦🇹 60
🇯🇵 58
🇩🇪 58
🇸🇪 56
🇸🇮…
RT @blendingtolearn: Super video, simple, full of wisdom, clear thinking, imagination and optimism. youtu.be/aUCD_24cygQ
The City of Thieves: A Digest and Perversion of R. D. Laing raggeduniversity.co.uk/2020/01/16/the…
RT @AnthonyOxon: AVIATION: Interesting to read that people make things up when asked a question rather that say they don't know. E.g. Matt…
A new environmental narrative that emphasises regrowth and possibility could provide the hope we need to make a change, argues Paul Jepson: resurgence.org/magazine/artic…
RT @GeorgeMonbiot: "The way the questions are framed could enable the government to go much further than the official purpose of the consul…
@AnthonyOxon @GeorgeMonbiot Yes, the link seems to not be working and Im having trouble working out what it used to point to. It would be good if you reshared a link pointing to the document/information source
RT @guardiannews: Some of our most important stories come from anonymous or confidential tipoffs. Here's how to get in touch securely https…
@guardiannews are you aware that ASDA are using facial recognition technology indescriminately on their customers in at least two UK stores (Preston + Marple) ? If their servers are offshore then there is no regulation on the data processing at all. Important privacy issue
This website has Certified Secure SSL Certificate by Comodo ltd
British Standards Institute certified environmentally managed servers
© Creative Commons Copyright by Attribution 2010 - 2019
Ragged University is part of the public domain
This website uses cookies for functionality and respects privacy.
For a guide on how to block cookies on your computer CLICK HERE For a guide on how to block cookies on your computer


Last week saw the announcement of a new album from Godspeed You! Black Emperor, entitled Luciferian Towers The band also shared the record's opening track 'Undoing a Luciferian Towers', and now they've unveiled a second track from that album, which you can stream exclusively above.
'Anthem For No State, Pt. III' closes the record, which sits at four tracks in total. The album itself was recorded during the winter of 2016 going into 2017 at Montreal's Hotel2Tango, with Greg Norman once again taking up engineering and co-production duties as he did on the band's previous album Asunder, Sweet And Other Distress, released in 2015.
Luciferian Towers is Godspeed You! Black Emperor's third album release since their 2011 reunion, and was announced accompanied by a band statement which you can read here. The album is out on September 22 via Constellation. The band will be touring the album across Europe through October and November and you can find the list of dates for those shows here.


Mumbai: The Reserve Bank of India (RBI) said the profits of Indian non bank finance firms grew at a much higher rate in the 2007-08 despite the rise in their expenditure as their fund based and fee based income rose sharply.
Profits more than tripled while expenditure went up 45.4%, the RBI said in its 'Report on Trend and Progress of Banking in India, 2007-08,' on Wednesday.
However, while the income as a percentage of assets rose, the expenditure as a percentage of assets declined sharply, resulting in a higher net profits to asset ratio, it also said.
While finance firms, as a whole, reported a drop in bad loans, equipment leasing and hire purchase firms reported an increase during the period, said the RBI.
The move was largely on account of the change in classification rules of NBFCs, it added.


text:
Tarkhan (,   or ; ; ; ; alternative spellings Tarkan, Tarkhaan, Tarqan, Tarchan, Turxan, Tarcan, Turgan, Tárkány, Tarján) is an ancient Central Asian title used by various Turkic, Hungarian, Mongolic, and even Iranian peoples. Its use was common among the successors of the Mongol Empire and Turkic Khaganate.

Etymology

The origin of the word is not known. Various historians identify the word as either East Iranian (Sogdian or Khotanese Saka) or Turkic.

Although Richard N. Frye reports that the word "was probably foreign to Sogdian", Gerhard Doerfer points out that even in Turkic languages, its plural is not Turkic (sing. tarxan --> plur. tarxat), suggesting a non-Turkic origin. L. Ligeti comes to the same conclusion, saying that "tarxan and tegin [prince] form the wholly un-Turkic plurals tarxat and tegit" and that the word was unknown to medieval western Turkic languages, such as Bulgar. Taking this into consideration, the word may be derived from medieval Mongolian  (plural suffix -at), itself perhaps derived from the earlier Sogdian word * ('free of taxes'). A. Alemany gives the additional elaboration that the possibly related East Iranian Scytho-Sarmatian (and Alanic) word * still survives in Ossetic  ('argument, trial') and  ('to judge'). Harold Walter Bailey also proposes an Iranian (Khotanese Saka) root for the word, L. Rogers and Edwin G. Pulleyblank argue that the Mongolian word may have actually originated among the Xiongnu, as a pronunciation of the word recorded in Old Chinese as chanyu, which Pulleyblank argues may have originally represented a Chinese approximation of dān-ĥwāĥ for *darxan.

History
Tarkhan was used among the Sogdian, Saka, Hephthalite, Turkic, and proto-Mongol peoples of Central Asia and by other Eurasian nomads. It was a high rank in the army of Timur. Tarkhans commanded military contingents (roughly of regimental size under the Turkic Khazars) and were, roughly speaking, generals. They could also be assigned as military governors of conquered regions.

The Göktürks probably adopted the title darqan from the Rourans or Avars. Oğul Tarqan (𐰆𐰍𐰞𐱃𐰺𐰴𐰣) and other tarqat (𐱃𐰺𐰴𐱃) were mentioned in the Orkhon inscription of Kul Tigin (d. c. 731 CE). They were given high honors such as entering the yurt of the khagan without any prior appointment and shown unusual ninefold pardon to the ninth generation from any crime they committed. Although the etymology of the word is unknown, it is attested under the Khitan people, whose Liao dynasty ruled most of Mongolia and North China from 916 to 1125. G. Clauson argued that Tarqan in Ancient Turkic was considered to be the supreme title and was not even, like Tegin and Shad, peculiar to the royal family, but that it was still a high title, carrying administrative responsibility.

The title has different meanings in different times. In Uyghurs, it meant 'deputy, minister'. By Oghuz Turks, it meant 'head constable'.

Like many titles, Tarkhan also occurs as a personal name, independent of a person's rank, which makes some historical references confusing.  For example, Arabic texts refer to a "Tarkhan, king of the Khazars" as reigning in the mid ninth century. Whether this is a confused reference to a military official or the name of an individual Khazar khagan remains unclear. The name is occasionally used today in Turkish and Arabic speaking countries. It is used as family name in Hungary today.

In the Mongol Empire, the darkhans were exempted from taxation, socage and requisitioning. Genghis Khan made those who helped his rise darkhans in 1206. The families of the darkhans played crucial roles later when the succession crisis occurred in Yuan dynasty and Ilkhanate. Abaqa Khan (1234–82) made an Indian Darkhan after he had led his mother and her team all the way from Central Asia to Persia safely. A wealthy merchant of Persia was made of Darkhan by Ghazan (1271–1304) for his service during the early defeat of the Ilkhan. In Russia, the Khans of the Golden Horde assigned important tasks to the Darkhan. A jarlig of Temür Qutlugh (ca. 1370–1399) authorized rights of the tarkhan of Crimea.

After suppressing the rebellion of the right three tumens in Mongolia, Dayan Khan exempted his soldiers, who participated the battle of Dalan-Terqin, from imposts and made them Darkhan in 1513. Even after the collapse of Northern Yuan dynasty with the death of Ligdan Khan in 1635, the title of darkhan continued to be bestowed on religious dignitaries, sometimes on persons of low birth. For example, in 1665, Erinchin Lobsang Tayiji, the Altan Khan of the Khalkha, bestowed the title on a Russian interpreter and requested the Tsar of Russia to exempt the interpreter from all tax obligations.

A tarkhan of the Arghun dynasty, Muhammad 'Isa Tarkhan, established the Tarkhan dynasty, which ruled Sindh from 1554 to 1591.

All craftsmen held the status of darkhan and were immune to occasional requisitions levied incessantly by passing imperial envoys. From then on, the word referred to craftsmen or blacksmiths in the Mongolian language now and is still used in Mongolia as privilege. People who served the Khagan's orda were granted the title of darkhan and their descendants are known as the darkhad in Ordos City, Inner Mongolia.

One of the seven Magyar (Hungarian) tribes was called Tarjan () according to Constantin VII's De Administrando Imperio, and it is a common geographical name used in many villages and city names.

Notable Tarkans
 Alp Sol Tepek, military leader of Yenisei Kyrgyz Khaganate
 Tonyukuk, General commander of Second Turkic Khaganate
 Kül Tigin, Tigin of Second Turkic Khaganate
 Kül-chor, Türgesh Kaghan
 Tun Baga Tarkhan, fourth Khagan of Uyghur Khaganate
 Chorpan Tarkhan, Khazar commander
 Mirza Ghazi Beg, Ruler of Tarkhan Dynasty, Sindh

In popular culture
 In C. S. Lewis' The Chronicles of Narnia series of novels, the apparent spelling variation Tarkaan is the title of a Calormen nobleman, tarkheena that of a noble woman.
 In Age of Empires II: The Conquerors, the tarkan is the Huns' unique unit with the appearance of a horseman with a torch and scourge in place of sword. Their strength is destroying buildings.
 Tarkan in the comic Tarkan is a fictional Hun warrior created by Turkish cartoonist Sezgin Burak.
 Tarkan: Golden medallion, Turkish film, 1973.
 "Tarkhan" is a military title used by recruitable allies in the 2021 action-strategy video game HighFleet

See also
 Astrakhan, a city in Russia named after a Tarkhan

Notes

External links
 Terminology in Russian history

Turkish words and phrases
Turkic culture
Khazar titles
Military ranks
History of Pakistan
Sogdian words and phrases
Mongol Empire
Bulgarian noble titles
Titles of the Göktürks