Beispiel #1
0
static int _ls_args(SList ** files, SList ** dirs)
{
	if((*files = slist_new()) == NULL)
		return _ls_error("slist", 1);
	if((*dirs = slist_new()) == NULL)
	{
		slist_delete(*files);
		return _ls_error("slist", 1);
	}
	return 0;
}
Beispiel #2
0
static int _ls_do_files(Prefs * prefs, char const * directory, SList * files)
{
	int res = 0;

	if(*prefs & LS_PREFS_l)
		res = _ls_do_files_long(prefs, directory, files);
	else
		res = _ls_do_files_short(prefs, directory, files);
	slist_apply(files, _ls_free);
	slist_delete(files);
	return res;
}
Beispiel #3
0
void expire_akills(void)
{
    int i;
    time_t now = time(NULL);
    Akill *ak;

    for (i = akills.count - 1; i >= 0; i--) {
        ak = akills.list[i];

        if (!ak->expires || ak->expires > now)
            continue;

        if (WallAkillExpire)
            xanadu_cmd_global(s_OperServ, "AKILL on %s@%s has expired",
                             ak->user, ak->host);
        slist_delete(&akills, i);
    }
}
Beispiel #4
0
void expire_szlines(void)
{
    int i;
    time_t now = time(NULL);
    SXLine *sx;

    for (i = szlines.count - 1; i >= 0; i--) {
        sx = szlines.list[i];

        if (!sx->expires || sx->expires > now)
            continue;

        if (WallSZLineExpire)
            xanadu_cmd_global(s_OperServ, "SZLINE on \2%s\2 has expired",
                             sx->mask);
        slist_delete(&szlines, i);
    }
}
Beispiel #5
0
static int _ls_do_dirs(Prefs * prefs, int argc, SList * dirs)
{
	int res = 0;
	SList cur;
	char * dir = NULL;
	char * eol = "";

	for(cur = *dirs; cur != NULL; slist_next(&cur))
	{
		dir = slist_data(&cur);
		if(argc != 1)
			printf("%s%s%s", eol, dir, ":\n");
		eol = "\n";
		res += _ls_directory_do(prefs, dir);
	}
	slist_apply(dirs, _ls_free);
	slist_delete(dirs);
	return res;
}
Beispiel #6
0
int add_sgline(User * u, char *mask, const char *by, const time_t expires,
               const char *reason)
{
    int deleted = 0, i;
    SXLine *entry;
    User *u2, *next;
    char buf[BUFSIZE];
    *buf = '\0';

    /* Checks whether there is an SGLINE that already covers
     * the one we want to add, and whether there are SGLINEs
     * that would be covered by this one.
     * If so, warn the user in the first case and cleanup
     * the useless SGLINEs in the second.
     */

    if (!mask) {
        return -1;
    }

    if (sglines.count > 0) {

        for (i = sglines.count - 1; i >= 0; i--) {
            entry = sglines.list[i];

            if (!entry)
                continue;

            if (!stricmp(entry->mask, mask)) {
                if (entry->expires >= expires || entry->expires == 0) {
                    if (u)
                        notice_lang(s_OperServ, u, OPER_SGLINE_EXISTS,
                                    mask);
                    return -1;
                } else {
                    entry->expires = expires;
                    if (u)
                        notice_lang(s_OperServ, u, OPER_SGLINE_CHANGED,
                                    entry->mask);
                    return -2;
                }
            }

            if (match_wild_nocase(entry->mask, mask)
                && (entry->expires >= expires || entry->expires == 0)) {
                if (u)
                    notice_lang(s_OperServ, u, OPER_SGLINE_ALREADY_COVERED,
                                mask, entry->mask);
                return -1;
            }

            if (match_wild_nocase(mask, entry->mask)
                && (entry->expires <= expires || expires == 0)) {
                slist_delete(&sglines, i);
                deleted++;
            }
        }

    }

    /* We can now check whether the list is full or not. */
    if (slist_full(&sglines)) {
        if (u)
            notice_lang(s_OperServ, u, OPER_SGLINE_REACHED_LIMIT,
                        sglines.limit);
        return -1;
    }

    /* We can now (really) add the SGLINE. */
    entry = scalloc(sizeof(SXLine), 1);
    if (!entry)
        return -1;

    entry->mask = sstrdup(mask);
    entry->by = sstrdup(by);
    entry->reason = sstrdup(reason);
    entry->seton = time(NULL);
    entry->expires = expires;

    slist_add(&sglines, entry);

    xanadu_cmd_sgline(entry->mask, entry->reason);

    if (KillonSGline && !ircd->sglineenforce) {
        snprintf(buf, (BUFSIZE - 1), "G-Lined: %s", entry->reason);
        u2 = firstuser();
        while (u2) {
            next = nextuser();
            if (!is_oper(u2)) {
                if (match_wild_nocase(entry->mask, u2->realname)) {
                    kill_user(ServerName, u2->nick, buf);
                }
            }
            u2 = next;
        }
    }
    return deleted;
}
Beispiel #7
0
int add_akill(User * u, char *mask, const char *by, const time_t expires,
              const char *reason)
{
    int deleted = 0, i;
    char *user, *mask2, *host;
    Akill *entry;

    if (!mask) {
        return -1;
    }

    /* Checks whether there is an AKILL that already covers
     * the one we want to add, and whether there are AKILLs
     * that would be covered by this one. The masks AND the
     * expiry times are used to determine this, because some
     * AKILLs may become useful when another one expires.
     * If so, warn the user in the first case and cleanup
     * the useless AKILLs in the second.
     */

    if (akills.count > 0) {

        for (i = akills.count - 1; i >= 0; i--) {
            char amask[BUFSIZE];

            entry = akills.list[i];

            if (!entry)
                continue;

            snprintf(amask, sizeof(amask), "%s@%s", entry->user,
                     entry->host);

            if (!stricmp(amask, mask)) {
                /* We change the AKILL expiry time if its current one is less than the new.
                 * This is preferable to be sure we don't change an important AKILL
                 * accidentely.
                 */
                if (entry->expires >= expires || entry->expires == 0) {
                    if (u)
                        notice_lang(s_OperServ, u, OPER_AKILL_EXISTS,
                                    mask);
                    return -1;
                } else {
                    entry->expires = expires;
                    if (u)
                        notice_lang(s_OperServ, u, OPER_AKILL_CHANGED,
                                    amask);
                    return -2;
                }
            }

            if (match_wild_nocase(amask, mask)
                && (entry->expires >= expires || entry->expires == 0)) {
                if (u)
                    notice_lang(s_OperServ, u, OPER_AKILL_ALREADY_COVERED,
                                mask, amask);
                return -1;
            }

            if (match_wild_nocase(mask, amask)
                && (entry->expires <= expires || expires == 0)) {
                slist_delete(&akills, i);
                deleted++;
            }
        }

    }

    /* We can now check whether the list is full or not. */
    if (slist_full(&akills)) {
        if (u)
            notice_lang(s_OperServ, u, OPER_AKILL_REACHED_LIMIT,
                        akills.limit);
        return -1;
    }

    /* We can now (really) add the AKILL. */
    mask2 = sstrdup(mask);
    host = strchr(mask2, '@');
    if (!host)
        return -1;
    user = mask2;
    *host = 0;
    host++;

    entry = scalloc(sizeof(Akill), 1);
    if (!entry)
        return -1;

    entry->user = sstrdup(user);
    entry->host = sstrdup(host);
    entry->by = sstrdup(by);
    entry->reason = sstrdup(reason);
    entry->seton = time(NULL);
    entry->expires = expires;

    slist_add(&akills, entry);

    if (AkillOnAdd)
        xanadu_cmd_akill(entry->user, entry->host, entry->by, entry->seton,
                        entry->expires, entry->reason);

    free(mask2);

    return deleted;
}
Beispiel #8
0
static void load_old_akill(void)
{
    dbFILE *f;
    int i, j;
    uint16 tmp16;
    uint32 tmp32;
    char buf[NICKMAX], mask2[BUFSIZE], *mask, *s;
    Akill *ak, *entry;

    if (!
        (f =
         open_db("AKILL", AutokillDBName ? AutokillDBName : "akill.db",
                 "r", 9)))
        return;

    get_file_version(f);

    read_int16(&tmp16, f);
    slist_setcapacity(&akills, tmp16);

    for (j = 0; j < akills.capacity; j++) {
        ak = scalloc(sizeof(Akill), 1);

        SAFE(read_string(&mask, f));
        s = strchr(mask, '@');
        *s = 0;
        s++;
        ak->user = sstrdup(mask);
        ak->host = sstrdup(s);
        SAFE(read_string(&ak->reason, f));
        SAFE(read_buffer(buf, f));
        if (!*buf)
            ak->by = sstrdup("<unknown>");
        else
            ak->by = sstrdup(buf);
        SAFE(read_int32(&tmp32, f));
        ak->seton = tmp32 ? tmp32 : time(NULL);
        SAFE(read_int32(&tmp32, f));
        ak->expires = tmp32;

        /* Sanity checks *sigh* */

        /* No nicknames allowed! */
        if (strchr(ak->user, '!')) {
            xanadu_cmd_remove_akill(ak->user, ak->host);
            free(ak);
            continue;
        }

        snprintf(mask2, sizeof(mask2), "%s@%s", ak->user, ak->host);

        /* Is the mask already in the AKILL list? */
        if (slist_indexof(&akills, mask2) != -1) {
            free(ak);
            continue;
        }

        /* Checks whether there is an AKILL that already covers
         * the one we want to add, and whether there are AKILLs
         * that would be covered by this one. Expiry time
         * does *also* matter.
         */

        if (akills.count > 0) {

            for (i = akills.count - 1; i >= 0; i--) {

                char amask[BUFSIZE];

                entry = akills.list[i];

                if (!entry)
                    continue;

                snprintf(amask, sizeof(amask), "%s@%s", entry->user,
                         entry->host);

                if (match_wild_nocase(amask, mask2)
                    && (entry->expires >= ak->expires
                        || entry->expires == 0)) {
                    xanadu_cmd_remove_akill(ak->user, ak->host);
                    free(ak);
                    ak = NULL;
                    break;
                }

                if (match_wild_nocase(mask2, amask)
                    && (entry->expires <= ak->expires || ak->expires == 0))
                    slist_delete(&akills, i);
            }

        }

        if (ak)
            slist_add(&akills, ak);
    }

    close_db(f);
}
Beispiel #9
0
int add_szline(User * u, char *mask, const char *by, const time_t expires,
               const char *reason)
{
    int deleted = 0, i;
    SXLine *entry;

    if (!mask) {
        return -1;
    }

    /* Checks whether there is an SZLINE that already covers
     * the one we want to add, and whether there are SZLINEs
     * that would be covered by this one.
     * If so, warn the user in the first case and cleanup
     * the useless SZLINEs in the second.
     */

    if (szlines.count > 0) {

        for (i = szlines.count - 1; i >= 0; i--) {
            entry = szlines.list[i];

            if (!entry)
                continue;

            if (!stricmp(entry->mask, mask)) {
                if (entry->expires >= expires || entry->expires == 0) {
                    if (u)
                        notice_lang(s_OperServ, u, OPER_SZLINE_EXISTS,
                                    mask);
                    return -1;
                } else {
                    entry->expires = expires;
                    if (u)
                        notice_lang(s_OperServ, u, OPER_SZLINE_EXISTS,
                                    mask);
                    return -2;
                }
            }

            if (match_wild_nocase(entry->mask, mask)) {
                if (u)
                    notice_lang(s_OperServ, u, OPER_SZLINE_ALREADY_COVERED,
                                mask, entry->mask);
                return -1;
            }

            if (match_wild_nocase(mask, entry->mask)) {
                slist_delete(&szlines, i);
                deleted++;
            }
        }

    }

    /* We can now check whether the list is full or not. */
    if (slist_full(&szlines)) {
        if (u)
            notice_lang(s_OperServ, u, OPER_SZLINE_REACHED_LIMIT,
                        szlines.limit);
        return -1;
    }

    /* We can now (really) add the SZLINE. */
    entry = scalloc(sizeof(SXLine), 1);
    if (!entry)
        return -1;

    entry->mask = sstrdup(mask);
    entry->by = sstrdup(by);
    entry->reason = sstrdup(reason);
    entry->seton = time(NULL);
    entry->expires = expires;

    slist_add(&szlines, entry);
    xanadu_cmd_szline(entry->mask, entry->reason, entry->by);

    return deleted;
}
Beispiel #10
0
static int do_akill(User * u)
{
    char *cmd = strtok(NULL, " ");
    char breason[BUFSIZE];

    if (!cmd)
        cmd = "";

    if (!stricmp(cmd, "ADD")) {
        int deleted = 0;
        char *expiry, *mask, *reason;
        time_t expires, now = time(NULL);

        mask = strtok(NULL, " ");
        if (mask && *mask == '+') {
            expiry = mask;
            mask = strtok(NULL, " ");
        } else {
            expiry = NULL;
        }

        expires = expiry ? dotime(expiry) : AutokillExpiry;
        /* If the expiry given does not contain a final letter, it's in days,
         * said the doc. Ah well.
         */
        if (expiry && isdigit(expiry[strlen(expiry) - 1]))
            expires *= 86400;
        /* Do not allow less than a minute expiry time */
        if (expires != 0 && expires < 60) {
            notice_lang(s_OperServ, u, BAD_EXPIRY_TIME);
            return MOD_CONT;
        } else if (expires > 0) {
            expires += time(NULL);
        }

        if (mask && (reason = strtok(NULL, ""))) {
            /* We first do some sanity check on the proposed mask. */
            if (strchr(mask, '!')) {
                notice_lang(s_OperServ, u, OPER_AKILL_NO_NICK);
                return MOD_CONT;
            }

            if (!strchr(mask, '@')) {
                notice_lang(s_OperServ, u, BAD_USERHOST_MASK);
                return MOD_CONT;
            }

            if (mask && strspn(mask, "~@.*?") == strlen(mask)) {
                notice_lang(s_OperServ, u, USERHOST_MASK_TOO_WIDE, mask);
                return MOD_CONT;
            }

            /**
             * Changed sprintf() to snprintf()and increased the size of
             * breason to match bufsize
             * -Rob
             **/
            if (AddAkiller) {
                snprintf(breason, sizeof(breason), "[%s] %s", u->nick,
                         reason);
                reason = sstrdup(breason);
            }

            deleted = add_akill(u, mask, u->nick, expires, reason);
            if (deleted < 0) {
                if (AddAkiller) {
                    free(reason);
                }
                return MOD_CONT;
            } else if (deleted) {
                notice_lang(s_OperServ, u, OPER_AKILL_DELETED_SEVERAL,
                            deleted);
            }
            notice_lang(s_OperServ, u, OPER_AKILL_ADDED, mask);

            if (WallOSAkill) {
                char buf[128];

                if (!expires) {
                    strcpy(buf, "does not expire");
                } else {
                    int wall_expiry = expires - now;
                    char *s = NULL;

                    if (wall_expiry >= 86400) {
                        wall_expiry /= 86400;
                        s = "day";
                    } else if (wall_expiry >= 3600) {
                        wall_expiry /= 3600;
                        s = "hour";
                    } else if (wall_expiry >= 60) {
                        wall_expiry /= 60;
                        s = "minute";
                    }

                    snprintf(buf, sizeof(buf), "expires in %d %s%s",
                             wall_expiry, s,
                             (wall_expiry == 1) ? "" : "s");
                }

                anope_cmd_global(s_OperServ,
                                 "%s added an AKILL for %s (%s) (%s)",
                                 u->nick, mask, reason, buf);
            }

            if (readonly) {
                notice_lang(s_OperServ, u, READ_ONLY_MODE);
            }
            if (AddAkiller) {
                free(reason);
            }
        } else {
            syntax_error(s_OperServ, u, "AKILL", OPER_AKILL_SYNTAX);
        }

    } else if (!stricmp(cmd, "DEL")) {

        char *mask;
        int res = 0;

        mask = strtok(NULL, " ");

        if (!mask) {
            syntax_error(s_OperServ, u, "AKILL", OPER_AKILL_SYNTAX);
            return MOD_CONT;
        }

        if (akills.count == 0) {
            notice_lang(s_OperServ, u, OPER_AKILL_LIST_EMPTY);
            return MOD_CONT;
        }

        if (isdigit(*mask) && strspn(mask, "1234567890,-") == strlen(mask)) {
            /* Deleting a range */
            res = slist_delete_range(&akills, mask, NULL);
            if (res == 0) {
                notice_lang(s_OperServ, u, OPER_AKILL_NO_MATCH);
                return MOD_CONT;
            } else if (res == 1) {
                notice_lang(s_OperServ, u, OPER_AKILL_DELETED_ONE);
            } else {
                notice_lang(s_OperServ, u, OPER_AKILL_DELETED_SEVERAL,
                            res);
            }
        } else {
            if ((res = slist_indexof(&akills, mask)) == -1) {
                notice_lang(s_OperServ, u, OPER_AKILL_NOT_FOUND, mask);
                return MOD_CONT;
            }

            slist_delete(&akills, res);
            notice_lang(s_OperServ, u, OPER_AKILL_DELETED, mask);
        }

        if (readonly)
            notice_lang(s_OperServ, u, READ_ONLY_MODE);

    } else if (!stricmp(cmd, "LIST")) {
        char *mask;
        int res, sent_header = 0;

        if (akills.count == 0) {
            notice_lang(s_OperServ, u, OPER_AKILL_LIST_EMPTY);
            return MOD_CONT;
        }

        mask = strtok(NULL, " ");

        if (!mask || (isdigit(*mask)
                      && strspn(mask, "1234567890,-") == strlen(mask))) {
            res =
                slist_enum(&akills, mask, &akill_list_callback, u,
                           &sent_header);
            if (res == 0) {
                notice_lang(s_OperServ, u, OPER_AKILL_NO_MATCH);
                return MOD_CONT;
            } else {
                notice_lang(s_OperServ, u, END_OF_ANY_LIST, "Akill");
            }
        } else {
            int i;
            char amask[BUFSIZE];

            for (i = 0; i < akills.count; i++) {
                snprintf(amask, sizeof(amask), "%s@%s",
                         ((Akill *) akills.list[i])->user,
                         ((Akill *) akills.list[i])->host);
                if (!stricmp(mask, amask)
                    || match_wild_nocase(mask, amask))
                    akill_list(i + 1, akills.list[i], u, &sent_header);
            }

            if (!sent_header)
                notice_lang(s_OperServ, u, OPER_AKILL_NO_MATCH);
            else {
                notice_lang(s_OperServ, u, END_OF_ANY_LIST, "Akill");
            }
        }
    } else if (!stricmp(cmd, "VIEW")) {
        char *mask;
        int res, sent_header = 0;

        if (akills.count == 0) {
            notice_lang(s_OperServ, u, OPER_AKILL_LIST_EMPTY);
            return MOD_CONT;
        }

        mask = strtok(NULL, " ");

        if (!mask || (isdigit(*mask)
                      && strspn(mask, "1234567890,-") == strlen(mask))) {
            res =
                slist_enum(&akills, mask, &akill_view_callback, u,
                           &sent_header);
            if (res == 0) {
                notice_lang(s_OperServ, u, OPER_AKILL_NO_MATCH);
                return MOD_CONT;
            }
        } else {
            int i;
            char amask[BUFSIZE];

            for (i = 0; i < akills.count; i++) {
                snprintf(amask, sizeof(amask), "%s@%s",
                         ((Akill *) akills.list[i])->user,
                         ((Akill *) akills.list[i])->host);
                if (!stricmp(mask, amask)
                    || match_wild_nocase(mask, amask))
                    akill_view(i + 1, akills.list[i], u, &sent_header);
            }

            if (!sent_header)
                notice_lang(s_OperServ, u, OPER_AKILL_NO_MATCH);
        }
    } else if (!stricmp(cmd, "CLEAR")) {
        slist_clear(&akills, 1);
        notice_lang(s_OperServ, u, OPER_AKILL_CLEAR);
    } else {
        syntax_error(s_OperServ, u, "AKILL", OPER_AKILL_SYNTAX);
    }
    return MOD_CONT;
}
Beispiel #11
0
/**
 * The /os admin command.
 * @param u The user who issued the command
 * @param MOD_CONT to continue processing other modules, MOD_STOP to stop processing.
 **/
int do_admin(User * u)
{
    char *cmd = strtok(NULL, " ");
    char *nick = strtok(NULL, " ");
    NickAlias *na;
    int res = 0;

    if (skeleton) {
        notice_lang(s_OperServ, u, OPER_ADMIN_SKELETON);
        return MOD_CONT;
    }

    if (!cmd || (!nick && stricmp(cmd, "LIST") && stricmp(cmd, "CLEAR"))) {
        syntax_error(s_OperServ, u, "ADMIN", OPER_ADMIN_SYNTAX);
    } else if (!stricmp(cmd, "ADD")) {
        if (!is_services_root(u)) {
            notice_lang(s_OperServ, u, PERMISSION_DENIED);
            return MOD_CONT;
        }

        if (!(na = findnick(nick))) {
            notice_lang(s_OperServ, u, NICK_X_NOT_REGISTERED, nick);
            return MOD_CONT;
        }

        if (na->status & NS_VERBOTEN) {
            notice_lang(s_OperServ, u, NICK_X_FORBIDDEN, nick);
            return MOD_CONT;
        }

        if (na->nc->flags & NI_SERVICES_ADMIN
            || slist_indexof(&servadmins, na->nc) != -1) {
            notice_lang(s_OperServ, u, OPER_ADMIN_EXISTS, nick);
            return MOD_CONT;
        }

        res = slist_add(&servadmins, na->nc);
        if (res == -2) {
            notice_lang(s_OperServ, u, OPER_ADMIN_REACHED_LIMIT, nick);
            return MOD_CONT;
        } else {
            if (na->nc->flags & NI_SERVICES_OPER
                && (res = slist_indexof(&servopers, na->nc)) != -1) {
                slist_delete(&servopers, res);
                na->nc->flags |= NI_SERVICES_ADMIN;
                notice_lang(s_OperServ, u, OPER_ADMIN_MOVED, nick);
	    } else if (na->nc->flags & NI_SERVICES_HELPOP && (res = slist_indexof(&servhelpops, na->nc)) != -1) {
	    	slist_delete(&servhelpops, res);
		na->nc->flags |= NI_SERVICES_ADMIN;
		notice_lang(s_OperServ, u, OPER_ADMIN_MOVED, nick);
            } else {
                na->nc->flags |= NI_SERVICES_ADMIN;
                notice_lang(s_OperServ, u, OPER_ADMIN_ADDED, nick);
            }

	    LogStaffAction(STAFFLOG_CHANNEL | STAFFLOG_OPERGLOBAL, "OperServ",
            	"%s!%s@%s added %s to the services admin list",
                u->nick, u->username, u->host, nick);

        }

        if (readonly)
            notice_lang(s_OperServ, u, READ_ONLY_MODE);
    } else if (!stricmp(cmd, "DEL")) {
        if (!is_services_root(u)) {
            notice_lang(s_OperServ, u, PERMISSION_DENIED);
            return MOD_CONT;
        }

        if (servadmins.count == 0) {
            notice_lang(s_OperServ, u, OPER_ADMIN_LIST_EMPTY);
            return MOD_CONT;
        }

        if (isdigit(*nick) && strspn(nick, "1234567890,-") == strlen(nick)) {
            /* Deleting a range */
            res = slist_delete_range(&servadmins, nick, NULL);
            if (res == 0) {
                notice_lang(s_OperServ, u, OPER_ADMIN_NO_MATCH);
                return MOD_CONT;
            } else if (res == 1) {
                notice_lang(s_OperServ, u, OPER_ADMIN_DELETED_ONE);
            } else {
                notice_lang(s_OperServ, u, OPER_ADMIN_DELETED_SEVERAL,
                            res);
            }
        } else {
            if (!(na = findnick(nick))) {
                notice_lang(s_OperServ, u, NICK_X_NOT_REGISTERED, nick);
                return MOD_CONT;
            }

            if (na->status & NS_VERBOTEN) {
                notice_lang(s_OperServ, u, NICK_X_FORBIDDEN, nick);
                return MOD_CONT;
            }

            if (!(na->nc->flags & NI_SERVICES_ADMIN)
                || (res = slist_indexof(&servadmins, na->nc)) == -1) {
                notice_lang(s_OperServ, u, OPER_ADMIN_NOT_FOUND, nick);
                return MOD_CONT;
            }

            slist_delete(&servadmins, res);
            notice_lang(s_OperServ, u, OPER_ADMIN_DELETED, nick);
        }

        if (readonly)
            notice_lang(s_OperServ, u, READ_ONLY_MODE);
    } else if (!stricmp(cmd, "LIST")) {
        int sent_header = 0;

        if (servadmins.count == 0) {
            notice_lang(s_OperServ, u, OPER_ADMIN_LIST_EMPTY);
            return MOD_CONT;
        }

        if (!nick || (isdigit(*nick)
                      && strspn(nick, "1234567890,-") == strlen(nick))) {
            res =
                slist_enum(&servadmins, nick, &admin_list_callback, u,
                           &sent_header);
            if (res == 0) {
                notice_lang(s_OperServ, u, OPER_ADMIN_NO_MATCH);
                return MOD_CONT;
            } else {
                notice_lang(s_OperServ, u, END_OF_ANY_LIST, "Admin");
            }
        } else {
            int i;

            for (i = 0; i < servadmins.count; i++)
                if (!stricmp
                    (nick, ((NickCore *) servadmins.list[i])->display)
                    || match_wild_nocase(nick,
                                         ((NickCore *) servadmins.
                                          list[i])->display))
                    admin_list(i + 1, servadmins.list[i], u, &sent_header);

            if (!sent_header)
                notice_lang(s_OperServ, u, OPER_ADMIN_NO_MATCH);
            else {
                notice_lang(s_OperServ, u, END_OF_ANY_LIST, "Admin");
            }
        }
    } else if (!stricmp(cmd, "CLEAR")) {
        if (!is_services_root(u)) {
            notice_lang(s_OperServ, u, PERMISSION_DENIED);
            return MOD_CONT;
        }

        if (servadmins.count == 0) {
            notice_lang(s_OperServ, u, OPER_ADMIN_LIST_EMPTY);
            return MOD_CONT;
        }

        slist_clear(&servadmins, 1);
        notice_lang(s_OperServ, u, OPER_ADMIN_CLEAR);
    } else {
        syntax_error(s_OperServ, u, "ADMIN", OPER_ADMIN_SYNTAX);
    }
    return MOD_CONT;
}
Beispiel #12
0
void test_slist( void )
{
  unsigned int
    loop,
    cpu_count;

  thread_state_t
    *thread_handles;

  struct slist_thread_start_state
    stss;

  /* TRD : 1. one head writer per CPU
           2. make one element, then one after writer per CPU
           3. make a list, then one list traverser per CPU
           4. one head writer and one list traverser per CPU
           5. make one element, then one after writer and one list traverser per CPU
           6. make a list, then one 100% deleter-traverser per CPU
           7. make a list, then one 25% deleter-traverser per CPU
           8. one head writer and one 100% deleter-traverse per CPU
           9. one head writer and one 25% deleter-traverse per CPU
           10. make one element, then one after writer and one 100% deleter-traverser per CPU
           11. make one element, then one after writer and one 25% deleter-traverser per CPU
           12. one head writer, one after writer, one traverser and one 25% deleter-traverser per CPU
  */

  cpu_count = abstraction_cpu_count();

  printf( "\n"
          "SList Test\n"
          "==========\n" );

  // TRD : 1. one head writer per CPU

  printf( "\n"
          "1. one head writer per CPU\n"
          "==========================\n" );

  slist_new( &stss.ss, NULL, NULL );
  stss.iteration_modulo = 1;
  stss.se = NULL;
  stss.duration = 1;

  thread_handles = (thread_state_t *) malloc( sizeof(thread_state_t) * cpu_count * 1 );

  for( loop = 0 ; loop < cpu_count ; loop++ )
    abstraction_thread_start( &thread_handles[loop], loop, slist_internal_thread_head_writer, &stss );

  for( loop = 0 ; loop < cpu_count ; loop++ )
    abstraction_thread_wait( thread_handles[loop] );

  slist_delete( stss.ss );

  free( thread_handles );

  // TRD : 2. make one element, then one after writer per CPU

  printf( "\n"
          "2. make one element, then one after writer per CPU\n"
          "==================================================\n" );

  slist_new( &stss.ss, NULL, NULL );
  stss.iteration_modulo = 1;
  stss.se = slist_new_head( stss.ss, (void *) NULL );
  stss.duration = 1;

  thread_handles = (thread_state_t *) malloc( sizeof(thread_state_t) * cpu_count * 1 );

  for( loop = 0 ; loop < cpu_count ; loop++ )
    abstraction_thread_start( &thread_handles[loop], loop, slist_internal_thread_after_writer, &stss );

  for( loop = 0 ; loop < cpu_count ; loop++ )
    abstraction_thread_wait( thread_handles[loop] );

  slist_delete( stss.ss );

  free( thread_handles );

  // TRD : 3. make a list, then one list traverser per CPU

  printf( "\n"
          "3. make a list, then one list traverser per CPU\n"
          "===============================================\n" );

  slist_new( &stss.ss, NULL, NULL );
  stss.iteration_modulo = 1;
  stss.se = NULL;
  stss.duration = 10;

  // TRD : small list so we get collisions
  for( loop = 0 ; loop < 10 ; loop++ )
    slist_new_head( stss.ss, (void *) 0 );

  thread_handles = (thread_state_t *) malloc( sizeof(thread_state_t) * cpu_count * 1 );

  for( loop = 0 ; loop < cpu_count ; loop++ )
    abstraction_thread_start( &thread_handles[loop], loop, slist_internal_thread_traverser, &stss );

  for( loop = 0 ; loop < cpu_count ; loop++ )
    abstraction_thread_wait( thread_handles[loop] );

  slist_delete( stss.ss );

  free( thread_handles );

  // TRD : 4. one head writer and one list traverser per CPU

  printf( "\n"
          "4. one head writer and one list traverser per CPU\n"
          "=================================================\n" );

  slist_new( &stss.ss, NULL, NULL );
  stss.iteration_modulo = 1;
  stss.se = NULL;
  stss.duration = 1;

  thread_handles = (thread_state_t *) malloc( sizeof(thread_state_t) * cpu_count * 2 );

  for( loop = 0 ; loop < cpu_count ; loop++ )\
  {
    abstraction_thread_start( &thread_handles[loop], loop, slist_internal_thread_head_writer, &stss );
    abstraction_thread_start( &thread_handles[loop+cpu_count], loop, slist_internal_thread_traverser, &stss );
  }

  for( loop = 0 ; loop < cpu_count * 2 ; loop++ )
    abstraction_thread_wait( thread_handles[loop] );

  slist_delete( stss.ss );

  free( thread_handles );

  // TRD : 5. make one element, then one after writer and one list traverser per CPU

  printf( "\n"
          "5. make one element, then one after writer and one list traverser per CPU\n"
          "=========================================================================\n" );

  slist_new( &stss.ss, NULL, NULL );
  stss.iteration_modulo = 1;
  stss.se = slist_new_head( stss.ss, (void *) NULL );
  stss.duration = 1;

  thread_handles = (thread_state_t *) malloc( sizeof(thread_state_t) * cpu_count * 2 );

  for( loop = 0 ; loop < cpu_count ; loop++ )\
  {
    abstraction_thread_start( &thread_handles[loop], loop, slist_internal_thread_after_writer, &stss );
    abstraction_thread_start( &thread_handles[loop+cpu_count], loop, slist_internal_thread_traverser, &stss );
  }

  for( loop = 0 ; loop < cpu_count * 2 ; loop++ )
    abstraction_thread_wait( thread_handles[loop] );

  slist_delete( stss.ss );

  free( thread_handles );

  // TRD : 6. make a list, then one 100% deleter-traverser per CPU

  printf( "\n"
          "6. make a list, then one 100%% deleter-traverser per CPU\n"
          "=======================================================\n" );

  slist_new( &stss.ss, NULL, NULL );
  stss.iteration_modulo = 1;
  stss.se = NULL;
  stss.duration = 1;

  for( loop = 0 ; loop < 10000 ; loop++ )
    slist_new_head( stss.ss, (void *) 0 );

  thread_handles = (thread_state_t *) malloc( sizeof(thread_state_t) * cpu_count * 1 );

  for( loop = 0 ; loop < cpu_count ; loop++ )
    abstraction_thread_start( &thread_handles[loop], loop, slist_internal_thread_deleter_traverser, &stss );

  for( loop = 0 ; loop < cpu_count ; loop++ )
    abstraction_thread_wait( thread_handles[loop] );

  slist_delete( stss.ss );

  free( thread_handles );

  // TRD : 7. make a list, then one 25% deleter-traverser per CPU

  printf( "\n"
          "7. make a list, then one 25%% deleter-traverser per CPU\n"
          "======================================================\n" );

  slist_new( &stss.ss, NULL, NULL );
  stss.iteration_modulo = 4;
  stss.se = NULL;
  stss.duration = 1;

  for( loop = 0 ; loop < 10000 ; loop++ )
    slist_new_head( stss.ss, (void *) 0 );

  thread_handles = (thread_state_t *) malloc( sizeof(thread_state_t) * cpu_count * 1 );

  for( loop = 0 ; loop < cpu_count ; loop++ )
    abstraction_thread_start( &thread_handles[loop], loop, slist_internal_thread_deleter_traverser, &stss );

  for( loop = 0 ; loop < cpu_count ; loop++ )
    abstraction_thread_wait( thread_handles[loop] );

  slist_delete( stss.ss );

  free( thread_handles );

  // TRD : 8. one head writer and one 100% deleter-traverse per CPU

  printf( "\n"
          "8. one head writer and one 100%% deleter-traverse per CPU\n"
          "========================================================\n" );

  slist_new( &stss.ss, NULL, NULL );
  stss.iteration_modulo = 1;
  stss.se = NULL;
  stss.duration = 10;

  thread_handles = (thread_state_t *) malloc( sizeof(thread_state_t) * cpu_count * 2 );

  for( loop = 0 ; loop < cpu_count ; loop++ )
  {
    abstraction_thread_start( &thread_handles[loop], loop, slist_internal_thread_head_writer, &stss );
    abstraction_thread_start( &thread_handles[loop+cpu_count], loop, slist_internal_thread_deleter_traverser, &stss );
  }

  for( loop = 0 ; loop < cpu_count * 2 ; loop++ )
    abstraction_thread_wait( thread_handles[loop] );

  slist_delete( stss.ss );

  free( thread_handles );

  // TRD : 9. one head writer and one 25% deleter-traverse per CPU

  printf( "\n"
          "9. one head writer and one 25%% deleter-traverse per CPU\n"
          "=======================================================\n" );

  slist_new( &stss.ss, NULL, NULL );
  stss.iteration_modulo = 4;
  stss.se = NULL;
  stss.duration = 1;

  thread_handles = (thread_state_t *) malloc( sizeof(thread_state_t) * cpu_count * 2 );

  for( loop = 0 ; loop < cpu_count ; loop++ )
  {
    abstraction_thread_start( &thread_handles[loop], loop, slist_internal_thread_head_writer, &stss );
    abstraction_thread_start( &thread_handles[loop+cpu_count], loop, slist_internal_thread_deleter_traverser, &stss );
  }

  for( loop = 0 ; loop < cpu_count * 2 ; loop++ )
    abstraction_thread_wait( thread_handles[loop] );

  slist_delete( stss.ss );

  free( thread_handles );

  // TRD : 10. make one element, then one after writer and one 100% deleter-traverser per CPU

  printf( "\n"
          "10. make one element, then one after writer and one 100%% deleter-traverser per CPU\n"
          "==================================================================================\n" );

  slist_new( &stss.ss, NULL, NULL );
  stss.iteration_modulo = 1;
  stss.se = slist_new_head( stss.ss, (void *) NULL );
  stss.duration = 10;

  thread_handles = (thread_state_t *) malloc( sizeof(thread_state_t) * cpu_count * 2 );

  for( loop = 0 ; loop < cpu_count ; loop++ )
  {
    abstraction_thread_start( &thread_handles[loop], loop, slist_internal_thread_after_writer, &stss );
    abstraction_thread_start( &thread_handles[loop+cpu_count], loop, slist_internal_thread_deleter_traverser, &stss );
  }

  for( loop = 0 ; loop < cpu_count * 2 ; loop++ )
    abstraction_thread_wait( thread_handles[loop] );

  slist_delete( stss.ss );

  free( thread_handles );

  // TRD : 11. make one element, then one after writer and one 25% deleter-traverser per CPU

  printf( "\n"
          "11. make one element, then one after writer and one 25%% deleter-traverser per CPU\n"
          "=================================================================================\n" );

  slist_new( &stss.ss, NULL, NULL );
  stss.iteration_modulo = 4;
  stss.se = slist_new_head( stss.ss, (void *) NULL );
  stss.duration = 1;

  thread_handles = (thread_state_t *) malloc( sizeof(thread_state_t) * cpu_count * 2 );

  for( loop = 0 ; loop < cpu_count ; loop++ )
  {
    abstraction_thread_start( &thread_handles[loop], loop, slist_internal_thread_after_writer, &stss );
    abstraction_thread_start( &thread_handles[loop+cpu_count], loop, slist_internal_thread_deleter_traverser, &stss );
  }

  for( loop = 0 ; loop < cpu_count * 2 ; loop++ )
    abstraction_thread_wait( thread_handles[loop] );

  slist_delete( stss.ss );

  free( thread_handles );

  // TRD : 12. one head writer, one after writer, one traverser and one 25% deleter-traverser per CPU

  printf( "\n"
          "12. one head writer, one after writer, one traverser and one 25%% deleter-traverser per CPU\n"
          "==========================================================================================\n" );

  slist_new( &stss.ss, NULL, NULL );
  stss.iteration_modulo = 4;
  stss.se = slist_new_head( stss.ss, (void *) NULL );
  stss.duration = 1;

  thread_handles = (thread_state_t *) malloc( sizeof(thread_state_t) * cpu_count * 4 );

  for( loop = 0 ; loop < cpu_count ; loop++ )
  {
    abstraction_thread_start( &thread_handles[loop], loop, slist_internal_thread_head_writer, &stss );
    abstraction_thread_start( &thread_handles[loop+cpu_count], loop, slist_internal_thread_after_writer, &stss );
    abstraction_thread_start( &thread_handles[loop+cpu_count*2], loop, slist_internal_thread_traverser, &stss );
    abstraction_thread_start( &thread_handles[loop+cpu_count*3], loop, slist_internal_thread_deleter_traverser, &stss );
  }

  for( loop = 0 ; loop < cpu_count * 4 ; loop++ )
    abstraction_thread_wait( thread_handles[loop] );

  slist_delete( stss.ss );

  free( thread_handles );

  return;
}
Beispiel #13
0
/**
 * The /os sgline command.
 * @param u The user who issued the command
 * @param MOD_CONT to continue processing other modules, MOD_STOP to stop processing.
 **/
int do_sgline(User * u)
{
    char *cmd = strtok(NULL, " ");

    if (!cmd)
        cmd = "";

    if (!stricmp(cmd, "ADD")) {
        int deleted = 0;
        char *expiry, *mask, *reason;
        time_t expires;

        mask = strtok(NULL, ":");
        if (mask && *mask == '+') {
            expiry = mask;
            mask = strchr(expiry, ' ');
            if (mask) {
                *mask = 0;
                mask++;
            }
        } else {
            expiry = NULL;
        }

        expires = expiry ? dotime(expiry) : SGLineExpiry;
        /* If the expiry given does not contain a final letter, it's in days,
         * said the doc. Ah well.
         */
        if (expiry && isdigit(expiry[strlen(expiry) - 1]))
            expires *= 86400;
        /* Do not allow less than a minute expiry time */
        if (expires != 0 && expires < 60) {
            notice_lang(s_OperServ, u, BAD_EXPIRY_TIME);
            return MOD_CONT;
        } else if (expires > 0) {
            expires += time(NULL);
        }

        if (mask && (reason = strtok(NULL, ""))) {
			/* Clean up the last character of the mask if it is a space
			 * See bug #761
			 */
			size_t masklen = strlen(mask);
			if (mask[masklen - 1] == ' ')
				mask[masklen - 1] = '\0';
			
            /* We first do some sanity check on the proposed mask. */

            if (mask && strspn(mask, "*?") == strlen(mask)) {
                notice_lang(s_OperServ, u, USERHOST_MASK_TOO_WIDE, mask);
                return MOD_CONT;
            }

            deleted = add_sgline(u, mask, u->nick, expires, reason);
            if (deleted < 0)
                return MOD_CONT;
            else if (deleted)
                notice_lang(s_OperServ, u, OPER_SGLINE_DELETED_SEVERAL,
                            deleted);
            notice_lang(s_OperServ, u, OPER_SGLINE_ADDED, mask);

            if (WallOSSGLine) {
                char buf[128];

                if (!expires) {
                    strcpy(buf, "does not expire");
                } else {
                    int wall_expiry = expires - time(NULL);
                    char *s = NULL;

                    if (wall_expiry >= 86400) {
                        wall_expiry /= 86400;
                        s = "day";
                    } else if (wall_expiry >= 3600) {
                        wall_expiry /= 3600;
                        s = "hour";
                    } else if (wall_expiry >= 60) {
                        wall_expiry /= 60;
                        s = "minute";
                    }

                    snprintf(buf, sizeof(buf), "expires in %d %s%s",
                             wall_expiry, s,
                             (wall_expiry == 1) ? "" : "s");
                }

                xanadu_cmd_global(s_OperServ,
                                 "%s added an SGLINE for %s (%s)", u->nick,
                                 mask, buf);
            }

            if (readonly)
                notice_lang(s_OperServ, u, READ_ONLY_MODE);

        } else {
            syntax_error(s_OperServ, u, "SGLINE", OPER_SGLINE_SYNTAX);
        }

    } else if (!stricmp(cmd, "DEL")) {

        char *mask;
        int res = 0;

        mask = strtok(NULL, "");

        if (!mask) {
            syntax_error(s_OperServ, u, "SGLINE", OPER_SGLINE_SYNTAX);
            return MOD_CONT;
        }

        if (sglines.count == 0) {
            notice_lang(s_OperServ, u, OPER_SGLINE_LIST_EMPTY);
            return MOD_CONT;
        }

        if (isdigit(*mask) && strspn(mask, "1234567890,-") == strlen(mask)) {
            /* Deleting a range */
            res = slist_delete_range(&sglines, mask, NULL);
            if (res == 0) {
                notice_lang(s_OperServ, u, OPER_SGLINE_NO_MATCH);
                return MOD_CONT;
            } else if (res == 1) {
                notice_lang(s_OperServ, u, OPER_SGLINE_DELETED_ONE);
            } else {
                notice_lang(s_OperServ, u, OPER_SGLINE_DELETED_SEVERAL,
                            res);
            }
        } else {
            if ((res = slist_indexof(&sglines, mask)) == -1) {
                notice_lang(s_OperServ, u, OPER_SGLINE_NOT_FOUND, mask);
                return MOD_CONT;
            }

            slist_delete(&sglines, res);
            notice_lang(s_OperServ, u, OPER_SGLINE_DELETED, mask);
        }

        if (readonly)
            notice_lang(s_OperServ, u, READ_ONLY_MODE);

    } else if (!stricmp(cmd, "LIST")) {
        char *mask;
        int res, sent_header = 0;

        if (sglines.count == 0) {
            notice_lang(s_OperServ, u, OPER_SGLINE_LIST_EMPTY);
            return MOD_CONT;
        }

        mask = strtok(NULL, "");

        if (!mask || (isdigit(*mask)
                      && strspn(mask, "1234567890,-") == strlen(mask))) {
            res =
                slist_enum(&sglines, mask, &sgline_list_callback, u,
                           &sent_header);
            if (res == 0) {
                notice_lang(s_OperServ, u, OPER_SGLINE_NO_MATCH);
                return MOD_CONT;
            }
        } else {
            int i;
            char *amask;

            for (i = 0; i < sglines.count; i++) {
                amask = ((SXLine *) sglines.list[i])->mask;
                if (!stricmp(mask, amask)
                    || match_wild_nocase(mask, amask))
                    sgline_list(i + 1, sglines.list[i], u, &sent_header);
            }

            if (!sent_header)
                notice_lang(s_OperServ, u, OPER_SGLINE_NO_MATCH);
            else {
                notice_lang(s_OperServ, u, END_OF_ANY_LIST, "SGLine");
            }
        }
    } else if (!stricmp(cmd, "VIEW")) {
        char *mask;
        int res, sent_header = 0;

        if (sglines.count == 0) {
            notice_lang(s_OperServ, u, OPER_SGLINE_LIST_EMPTY);
            return MOD_CONT;
        }

        mask = strtok(NULL, "");

        if (!mask || (isdigit(*mask)
                      && strspn(mask, "1234567890,-") == strlen(mask))) {
            res =
                slist_enum(&sglines, mask, &sgline_view_callback, u,
                           &sent_header);
            if (res == 0) {
                notice_lang(s_OperServ, u, OPER_SGLINE_NO_MATCH);
                return MOD_CONT;
            }
        } else {
            int i;
            char *amask;

            for (i = 0; i < sglines.count; i++) {
                amask = ((SXLine *) sglines.list[i])->mask;
                if (!stricmp(mask, amask)
                    || match_wild_nocase(mask, amask))
                    sgline_view(i + 1, sglines.list[i], u, &sent_header);
            }

            if (!sent_header)
                notice_lang(s_OperServ, u, OPER_SGLINE_NO_MATCH);
        }
    } else if (!stricmp(cmd, "CLEAR")) {
        slist_clear(&sglines, 1);
        notice_lang(s_OperServ, u, OPER_SGLINE_CLEAR);
    } else {
        syntax_error(s_OperServ, u, "SGLINE", OPER_SGLINE_SYNTAX);
    }
    return MOD_CONT;
}