コード例 #1
0
ファイル: debug.c プロジェクト: Robert-Xie/disque
void _serverPanic(char *msg, char *file, int line) {
    bugReportStart();
    serverLog(LL_WARNING,"------------------------------------------------");
    serverLog(LL_WARNING,"!!! Software Failure. Press left mouse button to continue");
    serverLog(LL_WARNING,"Guru Meditation: %s #%s:%d",msg,file,line);
#ifdef HAVE_BACKTRACE
    serverLog(LL_WARNING,"(forcing SIGSEGV in order to print the stack trace)");
#endif
    serverLog(LL_WARNING,"------------------------------------------------");
    *((char*)-1) = 'x';
}
コード例 #2
0
ファイル: ack.c プロジェクト: lamby/pkg-disque
/* Try to garbage collect the job. */
void tryJobGC(job *job) {
    if (job->state != JOB_STATE_ACKED) return;

    int dummy_ack = dictSize(job->nodes_delivered) == 0;
    serverLog(LL_VERBOSE,"GC %.42s", job->id);

    /* Don't overflow the count, it's only useful for the exponential delay.
     * Actually we'll keep trying forever. */
    if (job->gc_retry != JOB_GC_RETRY_COUNT_MAX) job->gc_retry++;

    /* nodes_confirmed is used in order to store all the nodes that have the
     * job in ACKed state, so that the job can be evicted when we are
     * confident the job will not be reissued. */
    if (job->nodes_confirmed == NULL) {
        job->nodes_confirmed = dictCreate(&clusterNodesDictType,NULL);
        dictAdd(job->nodes_confirmed,myself->name,myself);
    }

    /* Check ASAP if we already reached all the nodes. This special case
     * here is mainly useful when the job replication factor is 1, so
     * there is no SETACK to send, nor GOTCAK to receive.
     *
     * Also check if this is a dummy ACK but the cluster size is now 1:
     * in such a case we don't have other nodes to send SETACK to, we can
     * just remove the ACK. Note that dummy ACKs are not created at all
     * if the cluster size is 1, but this code path may be entered as a result
     * of the cluster getting resized to a single node. */
    int all_nodes_reached =
        (!dummy_ack) &&
        (dictSize(job->nodes_delivered) == dictSize(job->nodes_confirmed));
    int dummy_ack_single_node = dummy_ack && server.cluster->size == 1;

    if (all_nodes_reached || dummy_ack_single_node) {
        serverLog(LL_VERBOSE,
            "Deleting %.48s: all nodes reached in tryJobGC()",
            job->id);
        unregisterJob(job);
        freeJob(job);
        return;
    }

    /* Send a SETACK message to all the nodes that may have a message but are
     * still not listed in the nodes_confirmed hash table. However if this
     * is a dummy ACK (created by ACKJOB command acknowledging a job we don't
     * know) we have to broadcast the SETACK to everybody in search of the
     * owner. */
    dict *targets = dictSize(job->nodes_delivered) == 0 ?
                    server.cluster->nodes : job->nodes_delivered;
    dictForeach(targets,de)
        clusterNode *node = dictGetVal(de);
        if (dictFind(job->nodes_confirmed,node->name) == NULL)
            clusterSendSetAck(node,job);
    dictEndForeach
}
コード例 #3
0
ファイル: debug.c プロジェクト: Robert-Xie/disque
void _serverAssert(char *estr, char *file, int line) {
    bugReportStart();
    serverLog(LL_WARNING,"=== ASSERTION FAILED ===");
    serverLog(LL_WARNING,"==> %s:%d '%s' is not true",file,line,estr);
#ifdef HAVE_BACKTRACE
    server.assert_failed = estr;
    server.assert_file = file;
    server.assert_line = line;
    serverLog(LL_WARNING,"(forcing SIGSEGV to print the bug report.)");
#endif
    *((char*)-1) = 'x';
}
コード例 #4
0
ファイル: debug.c プロジェクト: Robert-Xie/disque
void logStackContent(void **sp) {
    int i;
    for (i = 15; i >= 0; i--) {
        unsigned long addr = (unsigned long) sp+i;
        unsigned long val = (unsigned long) sp[i];

        if (sizeof(long) == 4)
            serverLog(LL_WARNING, "(%08lx) -> %08lx", addr, val);
        else
            serverLog(LL_WARNING, "(%016lx) -> %016lx", addr, val);
    }
}
コード例 #5
0
ファイル: debug.c プロジェクト: Robert-Xie/disque
void serverLogObjectDebugInfo(robj *o) {
    serverLog(LL_WARNING,"Object type: %d", o->type);
    serverLog(LL_WARNING,"Object encoding: %d", o->encoding);
    serverLog(LL_WARNING,"Object refcount: %d", o->refcount);
    if (o->type == OBJ_STRING && sdsEncodedObject(o)) {
        serverLog(LL_WARNING,"Object raw string len: %zu", sdslen(o->ptr));
        if (sdslen(o->ptr) < 4096) {
            sds repr = sdscatrepr(sdsempty(),o->ptr,sdslen(o->ptr));
            serverLog(LL_WARNING,"Object raw string content: %s", repr);
            sdsfree(repr);
        }
    }
}
コード例 #6
0
ファイル: bio.c プロジェクト: Robert-Xie/disque
/* Initialize the background system, spawning the thread. */
void bioInit(void) {
    pthread_attr_t attr;
    pthread_t thread;
    size_t stacksize;
    int j;

    /* Initialization of state vars and objects */
    for (j = 0; j < BIO_NUM_OPS; j++) {
        pthread_mutex_init(&bio_mutex[j],NULL);
        pthread_cond_init(&bio_condvar[j],NULL);
        bio_jobs[j] = listCreate();
        bio_pending[j] = 0;
    }

    /* Set the stack size as by default it may be small in some system */
    pthread_attr_init(&attr);
    pthread_attr_getstacksize(&attr,&stacksize);
    if (!stacksize) stacksize = 1; /* The world is full of Solaris Fixes */
    while (stacksize < DISQUE_THREAD_STACK_SIZE) stacksize *= 2;
    pthread_attr_setstacksize(&attr, stacksize);

    /* Ready to spawn our threads. We use the single argument the thread
     * function accepts in order to pass the job ID the thread is
     * responsible of. */
    for (j = 0; j < BIO_NUM_OPS; j++) {
        void *arg = (void*)(unsigned long) j;
        if (pthread_create(&thread,&attr,bioProcessBackgroundJobs,arg) != 0) {
            serverLog(LL_WARNING,"Fatal: Can't initialize Background Jobs.");
            exit(1);
        }
        bio_threads[j] = thread;
    }
}
コード例 #7
0
static int
backup_if_needed (char *filename)
{
  char backupfile[256];
  int off;
  struct stat filestat;

  if (arc.num_rdb_backups < 1)
    {
      return C_OK;
    }

  if (stat (filename, &filestat) != -1 && S_ISREG (filestat.st_mode))
    {
      strcpy (backupfile, "dump-");
      off =
	strftime (backupfile + 5, sizeof (backupfile) - 5, "%Y%m%d-%T",
		  localtime (&filestat.st_mtime));
      snprintf (backupfile + 5 + off, sizeof (backupfile) - 5 - off,
		"-%d.rdb", (int) getpid ());

      if (rename (filename, backupfile) == -1)
	{
	  serverLog (LL_WARNING, "Error backing up rdb file: %s",
		     strerror (errno));
	  return C_ERR;
	}
    }

  return C_OK;
}
コード例 #8
0
ファイル: debug.c プロジェクト: Robert-Xie/disque
void bugReportStart(void) {
    if (server.bug_report_start == 0) {
        serverLog(LL_WARNING,
                  "\n\n=== DISQUE BUG REPORT START: Cut & paste starting from here ===");
        server.bug_report_start = 1;
    }
}
コード例 #9
0
ファイル: bio.c プロジェクト: Robert-Xie/disque
/* Kill the running bio threads in an unclean way. This function should be
 * used only when it's critical to stop the threads for some reason.
 * Currently Disque does this only on crash (for instance on SIGSEGV) in order
 * to perform a fast memory check without other threads messing with memory. */
void bioKillThreads(void) {
    int err, j;

    for (j = 0; j < BIO_NUM_OPS; j++) {
        if (pthread_cancel(bio_threads[j]) == 0) {
            if ((err = pthread_join(bio_threads[j],NULL)) != 0) {
                serverLog(LL_WARNING,
                    "Bio thread for job type #%d can be joined: %s",
                        j, strerror(err));
            } else {
                serverLog(LL_WARNING,
                    "Bio thread for job type #%d terminated",j);
            }
        }
    }
}
コード例 #10
0
static void printErrorStack(entry *e) {
    unsigned int i;
    char body[64];

    if (e->type == -1) {
        sprintf(body, "Error trace");
    } else if (e->type >= 253) {
        sprintf(body, "Error trace (%s)", types[e->type]);
    } else if (!e->key) {
        sprintf(body, "Error trace (%s: (unknown))", types[e->type]);
    } else {
        char tmp[41];
        strncpy(tmp, e->key, 40);

        /* display truncation at the last 3 chars */
        if (strlen(e->key) > 40) {
            memset(&tmp[37], '.', 3);
        }

        /* display unprintable characters as ? */
        for (i = 0; i < strlen(tmp); i++) {
            if (tmp[i] <= 32) tmp[i] = '?';
        }
        sprintf(body, "Error trace (%s: %s)", types[e->type], tmp);
    }

    printCentered(4, 80, body);

    /* display error stack */
    for (i = 0; i < errors.level; i++) {
        serverLog(LL_WARNING, "0x%08lx - %s",
            (unsigned long) errors.offset[i], errors.error[i]);
    }
}
コード例 #11
0
static void
mig_end (client * c)
{
  serverLog (LL_NOTICE, "Client ask for migrate end");
  if (arc.migrate_slot == NULL)
    {
      addReplyError (c,
		     "Migration is not in progress. Unable to perform MIGEND.");
      return;
    }

  serverLog (LL_NOTICE, "Finishing migration");
  sdsfree (arc.migrate_slot);
  arc.migrate_slot = NULL;
  addReply (c, shared.ok);
  return;
}
コード例 #12
0
ファイル: ChatServer.cpp プロジェクト: dirktao/chat-server
void ChatServer::processMessage(UserInfoChanged *msg)
{
    ChatClient client = m_clientList.getClient(msg->username);
    client.setUserInfo(msg->info);
    m_clientList.updateClient(client);
    QString log = "User " + msg->username + " changed his info";
    emit updateTable("clients");
    emit serverLog(esNotify, log);
}
コード例 #13
0
/* RDB check main: called form redis.c when Redis is executed with the
 * redis-check-rdb alias. */
int redis_check_rdb_main(char **argv, int argc) {
    if (argc != 2) {
        fprintf(stderr, "Usage: %s <rdb-file-name>\n", argv[0]);
        exit(1);
    }
    serverLog(LL_WARNING, "Checking RDB file %s", argv[1]);
    exit(redis_check_rdb(argv[1]));
    return 0;
}
コード例 #14
0
static void printCentered(int indent, int width, char* body) {
    char head[256], tail[256];
    memset(head, '\0', 256);
    memset(tail, '\0', 256);

    memset(head, '=', indent);
    memset(tail, '=', width - 2 - indent - strlen(body));
    serverLog(LL_WARNING, "%s %s %s", head, body, tail);
}
コード例 #15
0
ファイル: ChatServer.cpp プロジェクト: dirktao/chat-server
void ChatServer::serverGotNewConnection()
//activates when server got new incoming connection
//isn't very important for us, cause server requires authorization
//so we still waiting authorization/registration request from that son of a bitch
{
    QTcpSocket *newSocket = m_tcpServer->nextPendingConnection();
    connect(newSocket, SIGNAL(readyRead()), this, SLOT(serverGotNewMessage()));
    QString log = "Server got new connection from " + newSocket->peerAddress().toString() + ":" + QString::number(newSocket->peerPort());
    emit serverLog(esNotify, log);
}
コード例 #16
0
ファイル: redis_test.c プロジェクト: a1406/redis-test
static void redis_test_accept(aeEventLoop *el, int fd, void *privdata, int mask) {
    int cport, cfd, max = MAX_ACCEPTS_PER_CALL;
    char cip[NET_IP_STR_LEN];
    UNUSED(el);
    UNUSED(mask);
    UNUSED(privdata);

    while(max--) {
        cfd = anetTcpAccept(server.neterr, fd, cip, sizeof(cip), &cport);
        if (cfd == ANET_ERR) {
            if (errno != EWOULDBLOCK)
                serverLog(LL_WARNING,
                    "Accepting client connection: %s", server.neterr);
            return;
        }
        serverLog(LL_VERBOSE,"Accepted %s:%d", cip, cport);
        redis_accept_handler(cfd,0,cip);
    }
}
コード例 #17
0
ファイル: debug.c プロジェクト: Robert-Xie/disque
/* Log information about the "current" client, that is, the client that is
 * currently being served by Disque. May be NULL if Disque is not serving a
 * client right now. */
void logCurrentClient(void) {
    if (server.current_client == NULL) return;

    client *cc = server.current_client;
    sds client;
    int j;

    serverLog(LL_WARNING, "--- CURRENT CLIENT INFO");
    client = catClientInfoString(sdsempty(),cc);
    serverLog(LL_WARNING,"client: %s", client);
    sdsfree(client);
    for (j = 0; j < cc->argc; j++) {
        robj *decoded;

        decoded = getDecodedObject(cc->argv[j]);
        serverLog(LL_WARNING,"argv[%d]: '%s'", j, (char*)decoded->ptr);
        decrRefCount(decoded);
    }
}
コード例 #18
0
ファイル: debug.c プロジェクト: Robert-Xie/disque
void debugCommand(client *c) {
    if (!strcasecmp(c->argv[1]->ptr,"segfault")) {
        *((char*)-1) = 'x';
    } else if (!strcasecmp(c->argv[1]->ptr,"oom")) {
        void *ptr = zmalloc(ULONG_MAX); /* Should trigger an out of memory. */
        zfree(ptr);
        addReply(c,shared.ok);
    } else if (!strcasecmp(c->argv[1]->ptr,"assert")) {
        if (c->argc >= 3) c->argv[2] = tryObjectEncoding(c->argv[2]);
        serverAssertWithInfo(c,c->argv[0],1 == 2);
    } else if (!strcasecmp(c->argv[1]->ptr,"flushall")) {
        flushServerData();
        addReply(c,shared.ok);
    } else if (!strcasecmp(c->argv[1]->ptr,"loadaof")) {
        flushServerData();
        if (loadAppendOnlyFile(server.aof_filename) != C_OK) {
            addReply(c,shared.err);
            return;
        }
        serverLog(LL_WARNING,"Append Only File loaded by DEBUG LOADAOF");
        addReply(c,shared.ok);
    } else if (!strcasecmp(c->argv[1]->ptr,"sleep") && c->argc == 3) {
        double dtime = strtod(c->argv[2]->ptr,NULL);
        long long utime = dtime*1000000;
        struct timespec tv;

        tv.tv_sec = utime / 1000000;
        tv.tv_nsec = (utime % 1000000) * 1000;
        nanosleep(&tv, NULL);
        addReply(c,shared.ok);
    } else if (!strcasecmp(c->argv[1]->ptr,"error") && c->argc == 3) {
        sds errstr = sdsnewlen("-",1);

        errstr = sdscatsds(errstr,c->argv[2]->ptr);
        errstr = sdsmapchars(errstr,"\n\r","  ",2); /* no newlines in errors. */
        errstr = sdscatlen(errstr,"\r\n",2);
        addReplySds(c,errstr);
    } else if (!strcasecmp(c->argv[1]->ptr,"structsize") && c->argc == 2) {
        sds sizes = sdsempty();
        sizes = sdscatprintf(sizes,"bits:%d ",(sizeof(void*) == 8)?64:32);
        sizes = sdscatprintf(sizes,"job:%d ", (int)sizeof(job));
        sizes = sdscatprintf(sizes,"queue:%d ", (int)sizeof(queue));
        sizes = sdscatprintf(sizes,"robj:%d ",(int)sizeof(robj));
        sizes = sdscatprintf(sizes,"dictentry:%d ",(int)sizeof(dictEntry));
        sizes = sdscatprintf(sizes,"sdshdr5:%d ",(int)sizeof(struct sdshdr5));
        sizes = sdscatprintf(sizes,"sdshdr8:%d ",(int)sizeof(struct sdshdr8));
        sizes = sdscatprintf(sizes,"sdshdr16:%d ",(int)sizeof(struct sdshdr16));
        sizes = sdscatprintf(sizes,"sdshdr32:%d ",(int)sizeof(struct sdshdr32));
        sizes = sdscatprintf(sizes,"sdshdr64:%d ",(int)sizeof(struct sdshdr64));
        addReplyBulkSds(c,sizes);
    } else {
        addReplyErrorFormat(c, "Unknown DEBUG subcommand or wrong number of arguments for '%s'",
                            (char*)c->argv[1]->ptr);
    }
}
コード例 #19
0
ファイル: bio.c プロジェクト: dyu/disque
void *bioProcessBackgroundJobs(void *arg) {
    struct bio_job *job;
    unsigned long type = (unsigned long) arg;
    sigset_t sigset;

    /* Make the thread killable at any time, so that bioKillThreads()
     * can work reliably. */
    pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL);
    pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, NULL);

    pthread_mutex_lock(&bio_mutex[type]);
    /* Block SIGALRM so we are sure that only the main thread will
     * receive the watchdog signal. */
    sigemptyset(&sigset);
    sigaddset(&sigset, SIGALRM);
    if (pthread_sigmask(SIG_BLOCK, &sigset, NULL))
        serverLog(LL_WARNING,
                  "Warning: can't mask SIGALRM in bio.c thread: %s", strerror(errno));

    while(1) {
        listNode *ln;

        /* The loop always starts with the lock hold. */
        if (listLength(bio_jobs[type]) == 0) {
            pthread_cond_wait(&bio_newjob_cond[type],&bio_mutex[type]);
            continue;
        }
        /* Pop the job from the queue. */
        ln = listFirst(bio_jobs[type]);
        job = ln->value;
        /* It is now possible to unlock the background system as we know have
         * a stand alone job structure to process.*/
        pthread_mutex_unlock(&bio_mutex[type]);

        /* Process the job accordingly to its type. */
        if (type == BIO_CLOSE_FILE) {
            close((long)job->arg1);
        } else if (type == BIO_AOF_FSYNC) {
            aof_fsync((long)job->arg1);
        } else {
            serverPanic("Wrong job type in bioProcessBackgroundJobs().");
        }
        zfree(job);

        /* Unblock threads blocked on bioWaitStepOfType() if any. */
        pthread_cond_broadcast(&bio_step_cond[type]);

        /* Lock again before reiterating the loop, if there are no longer
         * jobs to process we'll block again in pthread_cond_wait(). */
        pthread_mutex_lock(&bio_mutex[type]);
        listDelNode(bio_jobs[type],ln);
        bio_pending[type]--;
    }
}
コード例 #20
0
ファイル: ChatServer.cpp プロジェクト: dirktao/chat-server
void ChatServer::processMessage(RegistrationRequest *msg, QTcpSocket *socket)
//processing regisration message
//registration logic stored in clientList,
//we just call it and use results to send registration answer
{
    if (!msg)
    {
        QString log = "Error processing registration request - message is empty";
        emit serverLog(esMinor, log);
        return;
    }
    RegistrationAnswer *answer = new RegistrationAnswer();
    switch (m_clientList.registrate(msg->username, msg->password))
    {
    case GeneralClientList::rrOccupiedUsername:
        {
            answer->registrationResult = false;
            answer->denialReason = "Username allready reserved, please choose another";
            break;
        }
    case GeneralClientList::rrBadUsername:
        {
            answer->registrationResult = false;
            answer->denialReason = "Your username isn't allowed";
            break;
        }
    case GeneralClientList::rrRegSuccess:
        {
            answer->registrationResult = true;
            emit updateTable("clients");
            emit updateTable("membership");
            break;
        }
    }
    sendMessageToClient(socket, answer);
    //
    QString log = msg->username + ((answer->registrationResult) ? " was registered." : "wasn't registered");
    emit serverLog(esNotify, log);
    //
    delete answer;
}
コード例 #21
0
ファイル: networking.c プロジェクト: tuyuwei/chat
void readClient(aeEventLoop *eventLoop, int fd, void *clientData, int mask) {
    UNUSED(mask);
    int nread;
    client *c = (client *)clientData;
    //取body长度
    if (c->bufsize <= 0) { 
        uint16_t size;
        nread = read(fd, (void *)&size, 2);
        if (nread <= 0) {
            serverLog(LL_VERBOSE, "Client closed connection fd:%d", c->fd);
            freeClient(c);
            return;
        }
        c->bufsize = (int)ntohs(size);
        return;
    }

    //取body
    nread = read(fd, (void *)(c->buf + c->bufpos), c->bufsize - c->bufpos);
    if (nread == -1) {
        if (errno == EAGAIN) {
            return;
        } else {
            serverLog(LL_VERBOSE, "Reading from client: %s",strerror(errno));
            return;
        }
    } else if (nread == 0) {
        serverLog(LL_VERBOSE, "body Client closed connection fd:%d", c->fd);
        freeClient(c);
        return;
    }
    c->bufpos += nread;
    if (c->bufpos >= c->bufsize) {
        serverLog(LL_VERBOSE, "msg: %s", c->buf);
        //init
        c->bufpos = c->bufsize = 0;
        memset(c->buf, 0, PROTO_REPLY_CHUNK_BYTES);
        return;
    }
}
コード例 #22
0
/* ----------------------- */
void
checkpointCommand (client * c)
{
  sds bitarray;
  serverLog (LL_NOTICE, "Client ask for checkpoint");
  /* Here we need to check if there is a background saving operation in progress */
  if (server.rdb_child_pid != -1 || server.aof_child_pid != -1)
    {
      serverLog (LL_NOTICE,
		 "Another background operation is in progress. Unable to perform CHECKPOINT.");
      addReplyError (c, "Unable to perform CHECKPOINT");
      return;
    }

  /* set bitarray from argument */
  bitarray = get_bitmap_from_argv (c->argc - 1, c->argv + 1);
  if (!bitarray)
    {
      addReplyError (c, "Invalid argument format.");
      return;
    }

  serverLog (LL_NOTICE, "Starting CHECKPOINT");
  arc.checkpoint_slots = bitarray;
  if (rdbSaveBackground (arc.checkpoint_filename) != C_OK)
    {
      serverLog (LL_NOTICE, "Replication failed, can't CHECKPOINT");
      addReplyError (c, "Unable to perform CHECKPOINT");
      sdsfree (bitarray);
      arc.checkpoint_slots = NULL;
      return;
    }
  arc.checkpoint_seqnum = arc.smr_seqnum;	//TODO 이건 여기가 아님.
  serverLog (LL_NOTICE,
	     "Partial Checkpoint sequence num:%lld", arc.smr_seqnum);
  c->replstate = SLAVE_STATE_WAIT_BGSAVE_END;
  c->repldbfd = -1;
  arc.checkpoint_client = c;
  return;
}
コード例 #23
0
/* argv includes command itself */
static void
mig_start (client * c, int argc, robj ** argv)
{
  serverLog (LL_NOTICE, "Client ask for migrate start");
  if (arc.migrate_slot != NULL)
    {
      addReplyError (c,
		     "Another migration is in progress. Unable to perform MIGSTART.");
      return;
    }

  arc.migrate_slot = get_bitmap_from_argv (argc - 1, argv + 1);
  if (!arc.migrate_slot)
    {
      addReplyError (c, "Invalid argument format.");
      return;
    }

  serverLog (LL_NOTICE, "Starting migration");
  addReply (c, shared.ok);
  return;
}
コード例 #24
0
ファイル: redis_test.c プロジェクト: a1406/redis-test
static void redis_accept_handler(int fd, int flags, char *ip)
{
	UNUSED(ip);
	redis_test_client *c;
	if ((c = redis_test_create_client(fd)) == NULL) {
        serverLog(LL_WARNING,
            "Error registering fd event for the new client: %s (fd=%d)",
            strerror(errno),fd);
        close(fd); /* May be already closed, just ignore errors */
        return;
    }
    c->flags |= flags;
}
コード例 #25
0
ファイル: ChatServer.cpp プロジェクト: dirktao/chat-server
void ChatServer::processMessage(DisconnectMessage *msg)
//processing disconnect message from client
//that's simple
//we need only to delete client from client list
//and close his socket
//also we should reply disconnect fact in all client's channels
{
    if (!msg)
    {
        QString log = "Error processing disconnect message - message is empty";
        emit serverLog(esMinor, log);
        return;
    }
    QString messageText = msg->sender + " was disconnected from server.";
    emit serverLog(esNotify, messageText);
    QStringList channels = m_clientList.getChannelsForClient(msg->sender).keys();
    ChannelSystemMessage *inform = new ChannelSystemMessage();
    ChannelUserList *list;
    inform->message = msg->sender+ " leaved chat.";
    m_clientList.disconnect(msg->sender);
    for (int i = 0; i < channels.count(); ++i)
    {
        list = new ChannelUserList();
        list->channelName = channels[i];
        ChatChannel channel = m_clientList.getChannel(channels[i]);
        for(int j = 0; j < channel.userList.count(); j++)
        {
            //FIXME: GOVNOKOD
            list->userList.insert(channel.userList[j], getSendableState(channel.userList[j]));
        }
        sendMessageToChannel(channels[i], list);
        delete list;
        inform->channelName = channels[i];
        sendMessageToChannel(channels[i], inform);
    }
    emit updateTable("clients");
    delete inform;
}
コード例 #26
0
ファイル: debug.c プロジェクト: Robert-Xie/disque
void _serverAssertPrintClientInfo(client *c) {
    int j;

    bugReportStart();
    serverLog(LL_WARNING,"=== ASSERTION FAILED CLIENT CONTEXT ===");
    serverLog(LL_WARNING,"client->flags = %d", c->flags);
    serverLog(LL_WARNING,"client->fd = %d", c->fd);
    serverLog(LL_WARNING,"client->argc = %d", c->argc);
    for (j=0; j < c->argc; j++) {
        char buf[128];
        char *arg;

        if (c->argv[j]->type == OBJ_STRING && sdsEncodedObject(c->argv[j])) {
            arg = (char*) c->argv[j]->ptr;
        } else {
            snprintf(buf,sizeof(buf),"Object type: %d, encoding: %d",
                     c->argv[j]->type, c->argv[j]->encoding);
            arg = buf;
        }
        serverLog(LL_WARNING,"client->argv[%d] = \"%s\" (refcount: %d)",
                  j, arg, c->argv[j]->refcount);
    }
}
コード例 #27
0
ファイル: ChatServer.cpp プロジェクト: dirktao/chat-server
void ChatServer::processMessage(ChannelListRequest *msg, QTcpSocket *socket)
//new processMessage for ChannelListRequest
{
    if (!msg)
    {
        QString log = "Error processing authorization request- message is empty";
        emit serverLog(esMinor, log);
        return;
    }
    ChannelListMessage *chanListMsg = new ChannelListMessage();
    if(msg->listType == ChannelListRequest::listOfAll)
    {
        chanListMsg->listType = ChannelListMessage::listOfAll;
        chanListMsg->channelList = m_clientList.getAllChanells();
        sendMessageToClient(socket, chanListMsg);
    }
    else
    {
        chanListMsg->listType = ChannelListMessage::listOfJoined;
        chanListMsg->channelList = m_clientList.getChannelsForClient(msg->nick);
        sendMessageToClient(socket, chanListMsg);
        ChannelUserList *userListMsg = new ChannelUserList();
        ChannelThemeChanged *theme = new ChannelThemeChanged();
        QMap<QString, QString>::iterator channel = chanListMsg->channelList.begin();
        for(;channel != chanListMsg->channelList.end(); ++channel)
        {
            QString channelName = channel.key();
            ChatChannel tempChannel = m_clientList.getChannel(channelName);
            userListMsg->channelName = channel.key();
            for(int i = 0; i < tempChannel.userList.count(); i++)
            {
                //FIXME: GOVNOKOD
                userListMsg->userList.insert(tempChannel.userList[i], getSendableState(tempChannel.userList[i]));
            }
            theme->channel = channel.key();
            theme->theme = m_clientList.getChannel(userListMsg->channelName).topic();
            sendMessageToChannel(channel.key(), userListMsg);
            sendMessageToClient(msg->nick, theme);
        }
        delete userListMsg;
        delete theme;
        UserInfoMessage *userInfo = new UserInfoMessage();
        userInfo->username = msg->nick;
        userInfo->info = m_clientList.getClient(msg->nick).userInfo();
        sendMessageToClient(msg->nick, userInfo);
        delete userInfo;
    }
    delete chanListMsg;
}
コード例 #28
0
ファイル: ChatServer.cpp プロジェクト: dirktao/chat-server
void ChatServer::processMessage(ChannelMessage *msg)
//processing channel message
//we need to reply this message to all clients in channel,
{
    //got channel message
    //need to reply it to all authorized clients in that channel
    if (!msg)
    {
        QString log = "Error processing channel message - message is empty";
        emit serverLog(esMinor, log);
        return;
    }
    QString messageText = QString("%1: %2")
            .arg(msg->sender)
            .arg(msg->messageText);
    emit channelLog(msg->receiver, messageText);
    //and reply to all of receiver channel users a channel message
    sendMessageToChannel(msg->receiver, msg);
}
コード例 #29
0
ファイル: ChatServer.cpp プロジェクト: dirktao/chat-server
void ChatServer::stopServer(const QString &shutdownReason)
//stops server
//we need to send disconnect messages to all channels
{
    GeneralClientList::userSocketsList_t *userList = m_clientList.getAllSockets();
    GeneralClientList::userSocketsListIterator_t itr(*userList);
    ServerShutdownMessage msg;
    msg.shutdownReason = shutdownReason;
    while(itr.hasNext())
        sendMessageToClient(itr.next(), &msg);
    delete userList;
    m_clientList.disconnectAll();
    QString log = tr("Server stopped.");
    m_tcpServer->close();
    disconnect(m_tcpServer, SIGNAL(newConnection()), this, SLOT(serverGotNewConnection()));
    disconnect(&m_clientList, SIGNAL(logMessage(ErrorStatus, QString&)), this, SLOT(replyLog(ErrorStatus, QString&)));
    emit serverLog(esNotify, log);
    delete m_tcpServer;
}
コード例 #30
0
void smemrmCommand(client *c)
{
    long long ll_var;
    int mem_id;
    int free_cnt = 0;
    struct smem_t * smem_p = NULL;
    listNode *lnode;

    int j;

    for (j = 1; j < c->argc; j++){
        // check the size
        if(getLongLongFromObject(c->argv[j],&ll_var) == C_OK){
            //serverLog(LL_WARNING,"get share memory id: %lld", ll_var);
            mem_id = ll_var;

            // get the item from list
            lnode = listSearchKey(server.smem_list_available, &mem_id);
            if(lnode){
                smem_p = lnode->value;

                // update the share memory used status
                server.share_memory_size -= smem_p->size;

                //serverLog(LL_WARNING,"[smemrmCommand] rm the id(%d) in list.", mem_id);
                listDelNode(server.smem_list_available, lnode);

            }else
                serverLog(LL_WARNING,"[smemrmCommand] not found the id(%d) in list, try to free.", mem_id);

            if(!smem_free_buffer(mem_id)){
                free_cnt ++;
            }

        }
        
    }

    addReplyLongLong(c,free_cnt);
    return C_OK;
}