Exemplo n.º 1
0
/* Read the request from the socket, returning in a nice binary format.
 * The return value should be subject to NRVO, so it will be fast
 */
static Request read_request(int fd)
{
	Request retval;

	std::unique_ptr<char[]> client_request(new char[client_request_size+1]);
	int amount_read;
	/* Get the request from the socket. */
	if ((amount_read = read(fd,client_request.get(),client_request_size))==-1) {
		server_error(fd,500);
		throw; // TODO: choose a good exception to throw
	} else {
		client_request[amount_read]=0; // Make sure we have a valid C string
	}
	main_log << DEBUG << "Read Client Request:" << client_request.get();
	
	/* Parse the request header */
	std::stringstream request_stream(client_request.get());;
	request_stream >> retval.method;
	request_stream >> retval.URI;
	request_stream >> retval.http_version;
	if (request_stream.fail()) {
		main_log << WARNING << "Received a bad request:\n" << client_request.get();
		server_error(fd,400);
		throw; // TODO: throw a proper exception
	} else {
		main_log << DEBUG << "Method: " << retval.method << '\n';
		main_log << "Request URI: " << retval.URI << '\n';
		main_log << "HTTP Version: " << retval.http_version << '\n';
	}
	
	std::swap(retval.raw,client_request);
	
	return retval;
}
Exemplo n.º 2
0
int		zappy_voir(t_player *player)
{
  char		*str;
  int		i;
  int		j;
  int		err;

  str = NULL;
  if (append_to_str(&str, "{"))
    return (server_error(MALLOC_ERR));
  i = -1;
  while (++i <= player->vision)
    {
      j = -i - 1;
      while (++j <= i)
	{
	  if ((err = append_cell_to_str(&str, player, -i, j)))
	    return (err);
	  if ((i != player->vision || j != i) && append_to_str(&str, ","))
	    return (server_error(MALLOC_ERR));
	}
    }
  if (append_to_str(&str, "}\n"))
    return (server_error(MALLOC_ERR));
  send_message(player, str);
  free(str);
  return (0);
}
Exemplo n.º 3
0
static SV *run_app(request_rec *r, SV *app, SV *env)
{
    dTHX;
    int count;
    SV *res;
    dSP;
    ENTER;
    SAVETMPS;
    PUSHMARK(SP) ;
    XPUSHs(sv_2mortal(env));
    PUTBACK;

    count = call_sv(app, G_EVAL|G_SCALAR|G_KEEPERR);
    SPAGAIN;
    if (SvTRUE(ERRSV)) {
        res = NULL;
        server_error(r, "%s", SvPV_nolen(ERRSV));
        CLEAR_ERRSV();
        (void) POPs;
    } else if (count > 0) {
        res = POPs;
        SvREFCNT_inc(res);
    } else {
        res = NULL;
    }
    PUTBACK;
    FREETMPS;
    LEAVE;
    return res;
}
Exemplo n.º 4
0
int		parse_n_option(int *i, char **av, t_zappy *zappy)
{
  int		n;

  zappy->nb_team = 0;
  (*i)++;
  while (av[zappy->nb_team + *i] && *av[zappy->nb_team + *i] != '-')
    zappy->nb_team++;
  if (zappy->nb_team == 0)
    {
      fprintf(stderr, "Error: empty team names\n");
      return (MISSING_OPTION);
    }
  if ((zappy->team_name = malloc(sizeof(char *) * zappy->nb_team)) == NULL)
    return (server_error(MALLOC_ERR));
  n = 0;
  while (n < zappy->nb_team)
    {
      if (!strcmp(av[*i], "GRAPHIC"))
	{
	  fprintf(stderr, "Error: you cannot use 'GRAPHIC' as a team name\n");
	  return (MISSING_OPTION);
	}
      zappy->team_name[n++] = av[(*i)++];
    }
  return (0);
}
Exemplo n.º 5
0
static int	expulse_player(t_player *player, t_player *cur_player)
{
    int	        x[WEST + 1];
    int	        y[WEST + 1];
    t_cell	**map;

    x[NORTH] = 0;
    x[EAST] = 1;
    x[SOUTH] = 0;
    x[WEST] = -1;
    y[NORTH] = -1;
    y[EAST] = 0;
    y[SOUTH] = 1;
    y[WEST] = 0;
    del_elem_list_no_free(&(g_zappy->map[cur_player->y][cur_player->x].players),
                          cur_player);
    cur_player->x = (player->x + x[player->direction]) % g_zappy->width;
    cur_player->y = (player->y + y[player->direction]) % g_zappy->height;
    cur_player->x = cur_player->x < 0 ? g_zappy->width - 1 : cur_player->x;
    cur_player->y = cur_player->y < 0 ? g_zappy->height - 1 : cur_player->y;
    map = g_zappy->map;
    if (add_front_elem_list(&(map[cur_player->y][cur_player->x].players),
                            cur_player))
        return (server_error(MALLOC_ERR));
    print_deplacement_expulse(player, cur_player);
    return (0);
}
Exemplo n.º 6
0
int 
server_socket_poll() {
	struct socket_server *ss = SOCKET_SERVER;
	assert(ss);
	struct socket_message result;
	int more = 1;
	int type = socket_server_poll(ss, &result, &more);
	switch (type) {
	case SOCKET_EXIT:
		return 0;
	case SOCKET_DATA:
		forward_message(SERVER_SOCKET_TYPE_DATA, false, &result);
		break;
	case SOCKET_CLOSE:
		forward_message(SERVER_SOCKET_TYPE_CLOSE, false, &result);
		break;
	case SOCKET_OPEN:
		forward_message(SERVER_SOCKET_TYPE_CONNECT, true, &result);
		break;
	case SOCKET_ERROR:
		forward_message(SERVER_SOCKET_TYPE_ERROR, false, &result);
		break;
	case SOCKET_ACCEPT:
		forward_message(SERVER_SOCKET_TYPE_ACCEPT, true, &result);
		break;
	default:
		server_error(NULL, "Unknown socket message type %d.",type);
		return -1;
	}
	if (more) {
		return -1;
	}
	return 1;
}
Exemplo n.º 7
0
static int output_body(request_rec *r, SV *body)
{
    dTHX;
    int rc, type;
    switch (type = SvTYPE(SvRV(body))) {
        case SVt_PVAV:
            rc = output_body_ary(r, (AV *) SvRV(body));
            break;
        case SVt_PVGV:
            /* TODO:
             * It's possible to get fd by PerlIO_fileno(IoIFP(sv_2io(body)))
             * It's possible to get apr_file_t by apr_os_file_put
             * Is it possible to implement above portable?
             */
            require_pv("IO/Handle.pm");
        case SVt_PVMG:
            if (respond_to(body, "path")) {
                rc = output_body_path(r, body);
                if (rc != DECLINED) break;
            }
            rc = output_body_obj(r, body, type);
            break;
        default:
            server_error(r, "response body must be an array reference or object");
            rc = HTTP_INTERNAL_SERVER_ERROR;
            break;
    }
    return rc;
}
Exemplo n.º 8
0
static int output_body_path(request_rec *r, SV *body)
{
    dTHX;
    int count;
    apr_status_t rc;
    SV *path_sv;
    char *path = NULL;
    dSP;
    ENTER;
    SAVETMPS;
    PUSHMARK(SP);
    XPUSHs(body);
    PUTBACK;

    count = call_method("path", G_EVAL|G_SCALAR|G_KEEPERR);
    SPAGAIN;
    if (SvTRUE(ERRSV)) {
        rc = DECLINED;
        server_error(r, "unable to get path\n%s", SvPV_nolen(ERRSV));
        CLEAR_ERRSV();
        (void) POPs;
    } else if (count > 0) {
        path_sv = POPs;
        path = apr_pstrdup(r->pool, SvPV_nolen(path_sv));
        rc = OK;
    } else {
        rc = DECLINED;
    }
    PUTBACK;
    FREETMPS;
    LEAVE;

    return rc != OK ? rc : output_body_sendfile(r, path);
}
Exemplo n.º 9
0
int		zappy_avance(t_player *player)
{
    int	        x[WEST + 1];
    int	        y[WEST + 1];

    x[NORTH] = 0;
    x[EAST] = 1;
    x[SOUTH] = 0;
    x[WEST] = -1;
    y[NORTH] = -1;
    y[EAST] = 0;
    y[SOUTH] = 1;
    y[WEST] = 0;
    del_elem_list_no_free(&(g_zappy->map[player->y][player->x].players), player);
    player->x = (player->x + x[player->direction]) % g_zappy->width;
    player->y = (player->y + y[player->direction]) % g_zappy->height;
    player->x = player->x < 0 ? g_zappy->width - 1 : player->x;
    player->y = player->y < 0 ? g_zappy->height - 1 : player->y;
    if (add_front_elem_list(&(g_zappy->map[player->y][player->x].players),
                            player))
        return (server_error(MALLOC_ERR));
    send_message(player, "ok\n");
    graphic_auto_ppo(player);
    return (0);
}
Exemplo n.º 10
0
static int output_headers(request_rec *r, AV *headers)
{
    dTHX;
    SV *key_sv, *val_sv;
    char *key;

    r->content_type = NULL;
    while (av_len(headers) > -1) {
        key_sv = av_shift(headers);
        val_sv = av_shift(headers);
        if (key_sv == NULL || val_sv == NULL) break;
        key = SvPV_nolen(key_sv);
        if (strcmp(key, "Content-Type") == 0) {
            r->content_type = apr_pstrdup(r->pool, SvPV_nolen(val_sv));
        } else if (strcmp(key, "Content-Length") == 0) {
            ap_set_content_length(r, SvIV(val_sv));
        } else if (strcmp(key, "Status") == 0) {
            server_error(r, "headers must not contain a Status");
            return HTTP_INTERNAL_SERVER_ERROR;
        } else {
            apr_table_add(r->headers_out, key, SvPV_nolen(val_sv));
        }
        SvREFCNT_dec(key_sv);
        SvREFCNT_dec(val_sv);
    }
    return OK;
}
Exemplo n.º 11
0
//处理消息回调
static int
_cb(struct server_context * context, void * ud, int type, int session, uint32_t source, const void * msg, size_t sz) {
	lua_State *L = ud;
	int trace = 1;
	int r;
	int top = lua_gettop(L);
	if (top == 0) {
		lua_pushcfunction(L, traceback);
		lua_rawgetp(L, LUA_REGISTRYINDEX, _cb);
	} else {
		assert(top == 2);
	}
	lua_pushvalue(L,2);//拷贝cb放到栈顶,用于执行,那么栈底就存放着 traceback, _cb

	lua_pushinteger(L, type);
	lua_pushlightuserdata(L, (void *)msg);
	lua_pushinteger(L,sz);
	lua_pushinteger(L, session);
	lua_pushnumber(L, source);

	r = lua_pcall(L, 5, 0 , trace);

	if (r == LUA_OK) {//运行成功
		return 0;
	}
	const char * self = server_cmd_command(context, "REG", NULL);
	switch (r) {
	case LUA_ERRRUN://运行时错误
		server_error(context, "lua call [%x to %s : %d msgsz = %d] error : " KRED "%s" KNRM, source , self, session, sz, lua_tostring(L,-1));
		break;
	case LUA_ERRMEM://内存分配错误。对于这种错,Lua不会调用错误处理函数
		server_error(context, "lua memory error : [%x to %s : %d]", source , self, session);
		break;
	case LUA_ERRERR://在运行错误处理函数时发生的错误
		server_error(context, "lua error in error : [%x to %s : %d]", source , self, session);
		break;
	case LUA_ERRGCMM://在运行 __gc 元方法时发生的错误(这个错误和被调用的函数无关)
		server_error(context, "lua gc error : [%x to %s : %d]", source , self, session);
		break;
	};

	lua_pop(L,1);//从栈顶弹出1个元素,即弹出错误信息

	return 0;
}
Exemplo n.º 12
0
int sspi_logout(const struct protocol_interface *protocol)
{
	const char *user = get_username(current_server()->current_root);
	
	if(sspi_set_user_password(user,current_server()->current_root->hostname,current_server()->current_root->port,current_server()->current_root->directory,NULL))
	{
		server_error(1,"Failed to delete password");
	}
	return CVSPROTO_SUCCESS;
}
Exemplo n.º 13
0
int		graphic_seg(char *team)
{
  char		*buf;

  if (asprintf(&buf, "seg %s\n", team) < 0)
    return (server_error(MALLOC_ERR));
  send_to_graphics(buf);
  free(buf);
  return (0);
}
Exemplo n.º 14
0
int server_connect(const struct protocol_interface *protocol, int verify_only)
{
	char current_user[256];
	char remote_user[256];
	char tmp[32];
	unsigned char c;
	int listen_port=0;
	if(!current_server->current_root->hostname || !current_server->current_root->directory || current_server->current_root->port)
		return CVSPROTO_BADPARMS;

	if(tcp_connect_bind(current_server->current_root->hostname,"514",512,1023)<1)
		return CVSPROTO_FAIL;

#ifdef _WIN32
	{
		DWORD dwLen = 256;
		GetUserNameA(current_user,&dwLen);
	}
#else
	strncpy(current_user,getpwuid(geteuid())->pw_name,sizeof(current_user));
#endif

	if(current_server->current_root->username)
		strncpy(remote_user,current_server->current_root->username,sizeof(remote_user));
	else
		strncpy(remote_user,current_user,sizeof(remote_user));

	snprintf(tmp,sizeof(tmp),"%d",listen_port);
	if(tcp_write(tmp,strlen(tmp)+1)<1)
		return CVSPROTO_FAIL;
	if(tcp_write(current_user,strlen(current_user)+1)<1)
		return CVSPROTO_FAIL;
	if(tcp_write(remote_user,strlen(remote_user)+1)<1)
		return CVSPROTO_FAIL;

#define CMD "cvs server"

	if(tcp_write(CMD,sizeof(CMD))<1)
		return CVSPROTO_FAIL;
	
	if(tcp_read(&c,1)<1)
		return CVSPROTO_FAIL;

	if(c)
	{
		char msg[257];
		if((c=tcp_read(msg,256))<1)
			return CVSPROTO_FAIL;
		msg[c]='\0';
		server_error(0,"rsh server reported: %s",msg);
		return CVSPROTO_FAIL;
	}

	return CVSPROTO_SUCCESS_NOPROTOCOL; /* :server: doesn't need login response */
}
Exemplo n.º 15
0
static int output_status(request_rec *r, SV *status)
{
    dTHX;
    int s = SvIV(status);
    if (s < 100) {
        server_error(r, "invalid response status %d", s);
        return HTTP_INTERNAL_SERVER_ERROR;
    }
    r->status = s;
    return OK;
}
Exemplo n.º 16
0
void	send_file(t_all *all, char *cmd)
{
	int		fd;
	char	buff[MAX_SIZE];

	cmd = cmd + 4;
	if (check_file(cmd) == -1)
		display_return_and_explanation(cmd, all->sv->c_sock, 0, 'f');
	else
	{
		if ((fd = open(cmd, O_RDONLY)) == -1)
			server_error("OPEN");
		if (read(fd, buff, MAX_SIZE - 1) == -1)
			server_error("READ");
		// printf("%lu\n", sizeof(buff));
		// all.
		send(all->sv->c_sock, buff, ft_strlen(buff), 0);
	}
	/*send(all->sv->c_sock, pwd, ft_strlen(pwd), 0);*/
}
Exemplo n.º 17
0
int		graphic_send_players2(t_player *graphic, t_player *player)
{
  char		*buf;

  if (asprintf(&buf, "pnw %d %d %d %d %d %s\n", player->id, player->x,
	       player->y, player->direction, player->level,
	       player->team) < 0)
    return (server_error(MALLOC_ERR));
  send_message(graphic, buf);
  free(buf);
  if (asprintf(&buf, "pin %d %d %d %d %d %d %d %d %d %d\n", player->id,
	       player->x, player->y, player->items[NOURRITURE],
	       player->items[LINEMATE], player->items[DERAUMERE],
	       player->items[SIBUR], player->items[MENDIANE],
	       player->items[PHIRAS], player->items[THYSTAME]) < 0)
    return (server_error(MALLOC_ERR));
  send_message(graphic, buf);
  free(buf);
  return (0);
}
Exemplo n.º 18
0
//打印内存分配情况
void
dump_c_mem() {
	int i;
	size_t total = 0;
	server_error(NULL, "dump all service mem:");
	for(i=0; i<SLOT_SIZE; i++) {
		mem_data* data = &mem_stats[i];
		if(data->handle != 0 && data->allocated != 0) {
			total += data->allocated;
			server_error(NULL, "0x%x -> %zdkb, %zd", data->handle, data->allocated >> 10, data->blocknum);
		}
	}
Exemplo n.º 19
0
void MainWindow::acceptConnection()
{
    QMessageBox::information(this, tr("网络"), tr("接受连接"), QMessageBox::Yes);
    tcpServerConnection = tcpServer.nextPendingConnection();
    connect(tcpServerConnection, SIGNAL(readyRead()), this, SLOT(server_readMessege()));//触发接收信息的槽函数
    connect(tcpServerConnection, SIGNAL(error(QAbstractSocket::SocketError)),
            this, SLOT(server_error(QAbstractSocket::SocketError)));
    connected = false;
    beconnected = true;
    tcpServer.close();

}
Exemplo n.º 20
0
int sspi_login(const struct protocol_interface *protocol, char *password)
{
	CScramble scramble;
	const char *user = get_username(current_server()->current_root);
	
	/* Store username & encrypted password in password store */
	if(sspi_set_user_password(user,current_server()->current_root->hostname,current_server()->current_root->port,current_server()->current_root->directory,scramble.Scramble(password)))
	{
		server_error(1,"Failed to store password");
	}

	return CVSPROTO_SUCCESS;
}
Exemplo n.º 21
0
int
server_socket_send(struct server_context *ctx, int id, void *buffer, int sz) {
	int64_t wsz = socket_server_send(SOCKET_SERVER, id, buffer, sz);
	if (wsz < 0) {
		server_free(buffer);
		return -1;
	} else if (wsz > 1024 * 1024) {
		int kb4 = wsz / 1024 / 4;
		if (kb4 % 256 == 0) {
			server_error(ctx, "%d Mb bytes on socket %d need to send out", (int)(wsz / (1024 * 1024)), id);
		}
	}
	return 0;
}
Exemplo n.º 22
0
void error (const char *format, ...)
{
	va_list va;
	char msg[256];
	
	va_start (va, format);
	vsnprintf (msg, sizeof(msg), format, va);
	msg[sizeof(msg) - 1] = 0;
	va_end (va);
	
	if (im_server)
		server_error (msg);
	else
		interface_error (msg);
}
Exemplo n.º 23
0
static int output_body_obj(request_rec *r, SV *obj, int type)
{
    dTHX;
    SV *buf_sv;
    apr_off_t clen = 0;
    STRLEN len;
    dSP;
    char *buf;
    int count;

    if (type == SVt_PVMG && !respond_to(obj, "getline")) {
        server_error(r, "response body object must be able to getline");
        return HTTP_INTERNAL_SERVER_ERROR;
    }

    ENTER;
    SAVETMPS;
    SAVESPTR(PL_rs);
    PL_rs = newRV_inc(newSViv(AP_IOBUFSIZE));
    while (1) {
        PUSHMARK(SP);
        XPUSHs(obj);
        PUTBACK;
        count = call_method("getline", G_SCALAR);
        if (count != 1) croak("Big trouble\n");
        SPAGAIN;
        buf_sv = POPs;
        if (SvOK(buf_sv)) {
            buf = SvPV(buf_sv, len);
            clen += len;
            ap_rwrite(buf, len, r);
        } else {
            break;
        }
    }
    if (clen > 0) {
        ap_set_content_length(r, clen);
    }
    PUSHMARK(SP);
    XPUSHs(obj);
    PUTBACK;
    call_method("close", G_DISCARD);
    SPAGAIN;
    PUTBACK;
    FREETMPS;
    LEAVE;
    return OK;
}
Exemplo n.º 24
0
int		graphic_pnw(t_player *player)
{
  char		*buf;

  if (asprintf(&buf, "pnw %d %d %d %d %d %s\n",
	       player->id,
	       player->x,
	       player->y,
	       player->direction,
	       player->level,
	       player->team) < 0)
    return (server_error(MALLOC_ERR));
  send_to_graphics(buf);
  free(buf);
  return (0);
}
Exemplo n.º 25
0
int		graphic_tna(t_player *player)
{
  char		*team;
  int		i;

  i = 0;
  while (i < g_zappy->nb_team)
    {
      if (asprintf(&team, "tna %s\n", g_zappy->team_name[i]) < 0)
	return (server_error(MALLOC_ERR));
      send_message(player, team);
      free(team);
      i++;
    }
  return (0);
}
Exemplo n.º 26
0
static int		recv_client()
{
  struct timeval	tv;
  int			ret;

  tv.tv_sec = 0;
  tv.tv_usec = 0;
  set_read();
  set_write();
  if ((ret = select(*(g_zappy->highest) + 1,
		    &(g_zappy->read.fds),
		    &(g_zappy->write.fds), NULL, &tv)) < 0)
    return (server_error(SELECT_ERR));
  else if (ret == 0)
    return (0);
  return (get_actions());
}
Exemplo n.º 27
0
json_t * getInfo(const json_t *requestJson) {
	json_t *responseJson = NULL;

	json_t* result = json_object();

	char * response = get_version();
	if(response) {
		json_object_set_new(result, "machineFirmvareVersion", json_string(response));
	}  else {
		logger(LEVEL_WARN, "get_info()  invalid version response");
		return server_error(requestJson);
	}

	json_object_set_new(result, "machineName", json_string("Good Coffee Machine"));

	responseJson = jsonrpc_response(requestJson, result, FALSE);

	return responseJson;
}
Exemplo n.º 28
0
static int output_response(request_rec *r, SV *res)
{
    dTHX;
    AV *res_av;
    SV **status;
    SV **headers;
    AV *headers_av;
    SV **body;
    int rc;

    if (!SvROK(res) || SvTYPE(SvRV(res)) != SVt_PVAV) {
        server_error(r, "response must be an array reference");
        return HTTP_INTERNAL_SERVER_ERROR;
    }
    res_av = (AV *) SvRV(res);
    if (av_len(res_av) != 2) {
        server_error(r, "response must have 3 elements");
        return HTTP_INTERNAL_SERVER_ERROR;
    }

    status = av_fetch(res_av, 0, 0);
    if (!SvOK(*status)) {
        server_error(r, "response status must be a scalar value");
        return HTTP_INTERNAL_SERVER_ERROR;
    }
    rc = output_status(r, *status);
    if (rc != OK) return rc;

    headers = av_fetch(res_av, 1, 0);
    if (!SvROK(*headers) || SvTYPE(SvRV(*headers)) != SVt_PVAV) {
        server_error(r, "response headers must be an array reference");
        return HTTP_INTERNAL_SERVER_ERROR;
    }
    headers_av = (AV *) SvRV(*headers);
    if ((av_len(headers_av) + 1) % 2 != 0) {
        server_error(r, "num of response headers must be even");
        return HTTP_INTERNAL_SERVER_ERROR;
    }
    rc = output_headers(r, headers_av);
    if (rc != OK) return rc;

    body = av_fetch(res_av, 2, 0);
    if (!SvROK(*body)) {
        server_error(r, "response body must be a reference");
        return HTTP_INTERNAL_SERVER_ERROR;
    }
    rc = output_body(r, *body);

    return rc;
}
Exemplo n.º 29
0
void internal_error (const char *file, int line, const char *function,
                     const char *format, ...)
{
	int saved_errno = errno;
	va_list va;
	char *msg;

	va_start (va, format);
	msg = format_msg_va (format, va);
	va_end (va);

	if (im_server)
		server_error (file, line, function, msg);
	else
		interface_error (msg);

	free (msg);

	errno = saved_errno;
}
Exemplo n.º 30
0
int pserver_auth_protocol_connect(const struct protocol_interface *protocol, const char *auth_string)
{
	char *tmp;
	CScramble scramble;

    if (!strcmp (auth_string, "BEGIN VERIFICATION REQUEST"))
		pserver_protocol_interface.verify_only = 1;
    else if (!strcmp (auth_string, "BEGIN AUTH REQUEST"))
		pserver_protocol_interface.verify_only = 0;
	else
		return CVSPROTO_NOTME;

    /* Get the three important pieces of information in order. */
    /* See above comment about error handling.  */
    server_getline (protocol, &pserver_protocol_interface.auth_repository, PATH_MAX);
    server_getline (protocol, &pserver_protocol_interface.auth_username, PATH_MAX);
    server_getline (protocol, &pserver_protocol_interface.auth_password, PATH_MAX);

    /* ... and make sure the protocol ends on the right foot. */
    /* See above comment about error handling.  */
    server_getline(protocol, &tmp, PATH_MAX);
    if (strcmp (tmp,
		pserver_protocol_interface.verify_only ?
		"END VERIFICATION REQUEST" : "END AUTH REQUEST")
	!= 0)
    {
		server_error (1, "bad auth protocol end: %s", tmp);
		free(tmp);
    }

	const char *unscrambled_password = scramble.Unscramble(pserver_protocol_interface.auth_password);
	if(!unscrambled_password || !*unscrambled_password)
	{
		CServerIo::trace(1,"PROTOCOL VIOLATION: Invalid scrambled password sent by client.  Assuming blank for compatibility.  Report bug to client vendor.");
		unscrambled_password="";
	}
	strcpy(pserver_protocol_interface.auth_password, unscrambled_password);

	free(tmp);
	return CVSPROTO_SUCCESS;
}