示例#1
0
/* 
 * cmd_goto()  -  goto a new room
 */
void cmd_goto(char *gargs)
{
	struct ctdlroom QRscratch;
	int c;
	int ok = 0;
	int ra;
	char augmented_roomname[ROOMNAMELEN];
	char towhere[ROOMNAMELEN];
	char password[32];
	int transiently = 0;

	if (CtdlAccessCheck(ac_logged_in_or_guest)) return;

	extract_token(towhere, gargs, 0, '|', sizeof towhere);
	extract_token(password, gargs, 1, '|', sizeof password);
	transiently = extract_int(gargs, 2);

	CtdlGetUser(&CC->user, CC->curr_user);

	/*
	 * Handle some of the macro named rooms
	 */
	convert_room_name_macros(towhere, sizeof towhere);

	/* First try a regular match */
	c = CtdlGetRoom(&QRscratch, towhere);

	/* Then try a mailbox name match */
	if (c != 0) {
		CtdlMailboxName(augmented_roomname, sizeof augmented_roomname,
			    &CC->user, towhere);
		c = CtdlGetRoom(&QRscratch, augmented_roomname);
		if (c == 0)
			safestrncpy(towhere, augmented_roomname, sizeof towhere);
	}

	/* And if the room was found... */
	if (c == 0) {

		/* Let internal programs go directly to any room. */
		if (CC->internal_pgm) {
			memcpy(&CC->room, &QRscratch,
				sizeof(struct ctdlroom));
			CtdlUserGoto(NULL, 1, transiently, NULL, NULL, NULL, NULL);
			return;
		}

		/* See if there is an existing user/room relationship */
		CtdlRoomAccess(&QRscratch, &CC->user, &ra, NULL);

		/* normal clients have to pass through security */
		if (ra & UA_GOTOALLOWED) {
			ok = 1;
		}

		if (ok == 1) {
			if ((QRscratch.QRflags & QR_MAILBOX) &&
			    ((ra & UA_GOTOALLOWED))) {
				memcpy(&CC->room, &QRscratch,
					sizeof(struct ctdlroom));
				CtdlUserGoto(NULL, 1, transiently, NULL, NULL, NULL, NULL);
				return;
			} else if ((QRscratch.QRflags & QR_PASSWORDED) &&
			    ((ra & UA_KNOWN) == 0) &&
			    (strcasecmp(QRscratch.QRpasswd, password)) &&
			    (CC->user.axlevel < AxAideU)
			    ) {
				cprintf("%d wrong or missing passwd\n",
					ERROR + PASSWORD_REQUIRED);
				return;
			} else if ((QRscratch.QRflags & QR_PRIVATE) &&
				   ((QRscratch.QRflags & QR_PASSWORDED) == 0) &&
				   ((QRscratch.QRflags & QR_GUESSNAME) == 0) &&
				   ((ra & UA_KNOWN) == 0) &&
			           (CC->user.axlevel < AxAideU)
                                  ) {
				syslog(LOG_DEBUG, "Failed to acquire private room\n");
			} else {
				memcpy(&CC->room, &QRscratch,
					sizeof(struct ctdlroom));
				CtdlUserGoto(NULL, 1, transiently, NULL, NULL, NULL, NULL);
				return;
			}
		}
	}

	cprintf("%d room '%s' not found\n", ERROR + ROOM_NOT_FOUND, towhere);
}
示例#2
0
//
// Implements the GROUP and LISTGROUP commands
//
void nntp_group(const char *cmd) {
	if (CtdlAccessCheck(ac_logged_in_or_guest)) return;

	citnntp *nntpstate = (citnntp *) CC->session_specific_data;
	char verb[16];
	char requested_group[1024];
	char message_range[256];
	char range_lo[256];
	char range_hi[256];
	char requested_room[ROOMNAMELEN];
	char augmented_roomname[ROOMNAMELEN];
	int c = 0;
	int ok = 0;
	int ra = 0;
	struct ctdlroom QRscratch;
	int msgs, new;
	long oldest,newest;
	struct listgroup_range lr;

	extract_token(verb, cmd, 0, ' ', sizeof verb);
	extract_token(requested_group, cmd, 1, ' ', sizeof requested_group);
	extract_token(message_range, cmd, 2, ' ', sizeof message_range);
	extract_token(range_lo, message_range, 0, '-', sizeof range_lo);
	extract_token(range_hi, message_range, 1, '-', sizeof range_hi);
	lr.lo = atoi(range_lo);
	lr.hi = atoi(range_hi);

	/* In LISTGROUP mode we can specify an empty name for 'currently selected' */
	if ((!strcasecmp(verb, "LISTGROUP")) && (IsEmptyStr(requested_group))) {
		room_to_newsgroup(requested_group, CC->room.QRname, sizeof requested_group);
	}

	/* First try a regular match */
	newsgroup_to_room(requested_room, requested_group, sizeof requested_room);
	c = CtdlGetRoom(&QRscratch, requested_room);

	/* Then try a mailbox name match */
	if (c != 0) {
		CtdlMailboxName(augmented_roomname, sizeof augmented_roomname, &CC->user, requested_room);
		c = CtdlGetRoom(&QRscratch, augmented_roomname);
		if (c == 0) {
			safestrncpy(requested_room, augmented_roomname, sizeof(requested_room));
		}
	}

	/* If the room exists, check security/access */
	if (c == 0) {
		/* See if there is an existing user/room relationship */
		CtdlRoomAccess(&QRscratch, &CC->user, &ra, NULL);

		/* normal clients have to pass through security */
		if (ra & UA_KNOWN) {
			ok = 1;
		}
	}

	/* Fail here if no such room */
	if (!ok) {
		cprintf("411 no such newsgroup\r\n");
		return;
	}


	/*
	 * CtdlUserGoto() formally takes us to the desired room, happily returning
	 * the number of messages and number of new messages.
	 */
	memcpy(&CC->room, &QRscratch, sizeof(struct ctdlroom));
	CtdlUserGoto(NULL, 0, 0, &msgs, &new, &oldest, &newest);
	cprintf("211 %d %ld %ld %s\r\n", msgs, oldest, newest, requested_group);

	// If this is a GROUP command, set the "current article number" to zero, and then stop here.
	if (!strcasecmp(verb, "GROUP")) {
		nntpstate->current_article_number = oldest;
		return;
	}

	// If we get to this point we are running a LISTGROUP command.  Fetch those message numbers.
	CtdlForEachMessage(MSGS_ALL, 0L, NULL, NULL, NULL, nntp_listgroup_backend, &lr);
	cprintf(".\r\n");
}