예제 #1
0
파일: Room.c 프로젝트: walterdejong/bbs100
int save_Room(Room *r) {
char filename[MAX_PATHLEN];
File *f;

	if (r == NULL)
		return -1;

	if (!(r->flags & ROOM_DIRTY)) {
/*
	if the room is not dirty, don't save it
	this is a performance improvement for demand loaded rooms; Home> and Mail>
*/
		if (!PARAM_HAVE_RESIDENT_INFO) {
			destroy_StringIO(r->info);
			r->info = NULL;
		}
		return 0;
	}
	r->flags &= ROOM_ALL;			/* this automatically clears ROOM_DIRTY */

	if (r->number == MAIL_ROOM || r->number == HOME_ROOM) {
		char name[MAX_LINE], *p;

		cstrcpy(name, r->name, MAX_LINE);
		if ((p = cstrchr(name, '\'')) == NULL)
			return -1;

		*p = 0;

		if (r->number == MAIL_ROOM)
			bufprintf(filename, sizeof(filename), "%s/%c/%s/MailData", PARAM_USERDIR, *name, name);
		else
			if (r->number == HOME_ROOM)
				bufprintf(filename, sizeof(filename), "%s/%c/%s/HomeData", PARAM_USERDIR, *name, name);

		load_roominfo(r, name);
	} else {
		bufprintf(filename, sizeof(filename), "%s/%u/RoomData", PARAM_ROOMDIR, r->number);
		load_roominfo(r, NULL);
	}
	path_strip(filename);

	if ((f = Fcreate(filename)) == NULL)
		return -1;

	if (save_Room_version1(f, r)) {
		Fcancel(f);
		return -1;
	}
	if (Fclose(f))
		return -1;

	if (!PARAM_HAVE_RESIDENT_INFO) {
		destroy_StringIO(r->info);
		r->info = NULL;
	}
	return 0;
}
예제 #2
0
/*
 * search for command with PATH
 */
const char *
search_path(const char *name, const char *lpath,
    /* R_OK or X_OK */
    int mode,
    /* set if candidate found, but not suitable */
    int *errnop)
{
	const char *sp, *p;
	char *xp;
	XString xs;
	size_t namelen;
	int ec = 0, ev;

	if (vstrchr(name, '/')) {
		if ((ec = search_access(name, mode)) == 0) {
 search_path_ok:
			if (errnop)
				*errnop = 0;
			return (name);
		}
		goto search_path_err;
	}

	namelen = strlen(name) + 1;
	Xinit(xs, xp, 128, ATEMP);

	sp = lpath;
	while (sp != NULL) {
		xp = Xstring(xs, xp);
		if (!(p = cstrchr(sp, ':')))
			p = sp + strlen(sp);
		if (p != sp) {
			XcheckN(xs, xp, p - sp);
			memcpy(xp, sp, p - sp);
			xp += p - sp;
			*xp++ = '/';
		}
		sp = p;
		XcheckN(xs, xp, namelen);
		memcpy(xp, name, namelen);
		if ((ev = search_access(Xstring(xs, xp), mode)) == 0) {
			name = Xclose(xs, xp + namelen);
			goto search_path_ok;
		}
		/* accumulate non-ENOENT errors only */
		if (ev != ENOENT && ec == 0)
			ec = ev;
		if (*sp++ == '\0')
			sp = NULL;
	}
	Xfree(xs, xp);
 search_path_err:
	if (errnop)
		*errnop = ec ? ec : ENOENT;
	return (NULL);
}
int main() {
    int length = __VERIFIER_nondet_int();
    if (length < 1) {
        length = 1;
    }
    char* nondetString = (char*) malloc(length * sizeof(char));
    nondetString[length-1] = '\0';
    cstrchr(nondetString,__VERIFIER_nondet_int());
    free(nondetString);
    return 0;
}
예제 #4
0
파일: util.c 프로젝트: walterdejong/bbs100
/*
	try to determine the length of the next word
	this is used by the word wrapper in Out()
	do NOT try to use this function for anything else, because it is
	way crappy
	scans at most only 15 characters ahead
*/
int word_len(char *str) {
int len;

	len = 0;
	while(*str) {
		switch(*str) {
			case '<':
				str += skip_long_color_code(str)-1;
				break;

			case KEY_CTRL('X'):
			case '\r':
				return -10000;		/* fool him */

			case ' ':
			case '\n':
			case '\t':
				return len;

			default:
				if (cstrchr(Wrap_Charset1, *str) != NULL) {
					len++;
					return len;
				}
				if (cstrchr(Wrap_Charset2, *str) != NULL)
					return len;

/* count as printable character (this is NOT always the case, however) */
				if (*str >= ' ' && *str <= '~') {
					len++;
					if (len >= 15)
						return len;
				}
		}
		if (*str)
			str++;
	}
	return len;
}
예제 #5
0
파일: util.c 프로젝트: walterdejong/bbs100
/*
	Warning: modifies buffer
*/
char *path_strip(char *path) {
char *p;

	if (path == NULL)
		return NULL;

	p = path;
	while((p = cstrchr(p, '/')) != NULL) {
		while(p[1] == '/')
			memmove(p+1, p+2, strlen(p+1));
		p++;
	}
	return path;
}
예제 #6
0
파일: util.c 프로젝트: walterdejong/bbs100
int mkdir_p(char *pathname) {
char *p, errbuf[MAX_LINE];

	if (pathname == NULL)
		return -1;

	if (!*pathname)
		return 0;

	p = pathname;
	while((p = cstrchr(p, '/')) != NULL) {
		*p = 0;
		if (!*pathname) {
			*p = '/';
			p++;
			continue;
		}
		if (make_dir(pathname, (mode_t)0750) == -1) {
			*p = '/';
			p++;
			if (errno == EEXIST)
				continue;

			log_err("mkdir_p(): failed to create directory %s : %s", pathname, cstrerror(errno, errbuf, MAX_LINE));
			return -1;
		}
		*p = '/';
		p++;
	}
	if (make_dir(pathname, (mode_t)0750) == -1) {
		if (errno == EEXIST)
			return 0;

		log_err("mkdir_p(): failed to create directory %s : %s", pathname, cstrerror(errno, errbuf, MAX_LINE));
		return -1;
	}
	return 0;
}
예제 #7
0
파일: Room.c 프로젝트: walterdejong/bbs100
int room_exists(char *name) {
char *p;

	if ((p = cstrchr(name, '\'')) != NULL) {
		if ((PARAM_HAVE_HOMEROOM && (!strcmp(p, "'s Home") || !strcmp(p, "' Home")))
			|| (PARAM_HAVE_MAILROOM && (!strcmp(p, "'s Mail") || !strcmp(p, "' Mail")))) {
			*p = 0;
			if (user_exists(name)) {
				*p = '\'';
				return 1;
			}
			*p = '\'';
			return 0;
		}
	}
	if (*name >= '0' && *name <= '9')
		return roomnumber_exists((unsigned int)atoi(name));
	else {
		Room *r;

		for(r = AllRooms; r != NULL; r = r->next)
			if (!strcmp(r->name, name)) {
				if (r->number == MAIL_ROOM && !PARAM_HAVE_MAILROOM)
					return 0;

				if (r->number == HOME_ROOM && !PARAM_HAVE_HOMEROOM)
					return 0;

				if ((r->flags & ROOM_CHATROOM) && !PARAM_HAVE_CHATROOMS)
					return 0;

				return 1;
			}
	}
	return 0;
}
예제 #8
0
void enter_emote(User *usr) {
char name[MAX_NAME], line[MAX_LINE], *p, *endp;
XMsg *x;
int sent;

	if ((x = new_XMsg()) == NULL) {
		Put(usr, "<red>Due to an error, you can not send messages now\n");
		return;
	}
	if (edit_recipients(usr, multi_x_access) == -1) {
		destroy_XMsg(x);
		return;
	}
	if (usr->recipients.len <= 0) {
		destroy_XMsg(x);
		return;
	}
	check_recipients(usr);

	if (usr->recipients.len <= 0) {
		destroy_XMsg(x);
		return;
	}

/* enter the message text */

	Print(usr, "<cyan>* <white>%s <yellow>", usr->name);

	if (edit_line(usr, line, MAX_LINE) == -1 || !line[0]) {
		Put(usr, "<red>Message not sent\n");
		destroy_XMsg(x);
		return;
	}
	ctrim_line(line);

	if (!line[0]) {
		Put(usr, "<red>Message not sent\n");
		destroy_XMsg(x);
		return;
	}
	if (add_XMsg_line(x, line) == -1) {
		Put(usr, "<red>Due to an error, you can not send messages now\n");
		destroy_XMsg(x);
		return;
	}
	check_recipients(usr);

	if (usr->recipients.len <= 0) {
		destroy_XMsg(x);
		return;
	}
	set_XMsg(x, XMSG_EMOTE, usr->name, usr->recipients.str, time(NULL));

	sent = 0;

	p = usr->recipients.str;
	while((endp = cstrchr(p, ',')) != NULL) {
		*endp = 0;
		cstrcpy(name, p, MAX_NAME);
		*endp = ',';
		endp++;
		p = endp;

		sent += send_xmsg(usr, x, name);
	}
	cstrcpy(name, p, MAX_NAME);
	sent += send_xmsg(usr, x, name);

	if (sent)
		send_xmsg_bcc(usr, x);		/* remember message as sent in 'this' user */
	else
		destroy_XMsg(x);
}
예제 #9
0
void enter_xmsg(User *usr) {
char name[MAX_NAME], *p, *endp;
XMsg *x;
GString gstr;
int sent;

	if ((x = new_XMsg()) == NULL) {
		Put(usr, "<red>Due to an error, you can not send messages now\n");
		return;
	}
	if (edit_recipients(usr, multi_x_access) == -1) {
		destroy_XMsg(x);
		return;
	}
	if (usr->recipients.len <= 0) {
		destroy_XMsg(x);
		return;
	}
	check_recipients(usr);

	if (usr->recipients.len <= 0) {
		destroy_XMsg(x);
		return;
	}

/* enter the message text */

	Put(usr, "<green>");

	init_GString(&gstr);

	if (edit_lines(usr, &gstr, ">", MAX_X_LINES) == -1) {
		Put(usr, "<red>Message not sent\n");
		destroy_XMsg(x);
		deinit_GString(&gstr);
		return;
	}
	if (gstr.len <= 0) {
		Put(usr, "<red>Message not sent\n");
		destroy_XMsg(x);
		deinit_GString(&gstr);
		return;
	}
	ctrim_line(gstr.str);
	if (add_XMsg_line(x, gstr.str) == -1) {
		Put(usr, "<red>Due to an error, you can not send messages now\n");
		destroy_XMsg(x);
		deinit_GString(&gstr);
		return;
	}
	deinit_GString(&gstr);

	check_recipients(usr);

	if (usr->recipients.len <= 0) {
		destroy_XMsg(x);
		return;
	}
	set_XMsg(x, XMSG_X, usr->name, usr->recipients.str, time(NULL));

	sent = 0;

	p = usr->recipients.str;
	while((endp = cstrchr(p, ',')) != NULL) {
		*endp = 0;
		cstrcpy(name, p, MAX_NAME);
		*endp = ',';
		endp++;
		p = endp;

		sent += send_xmsg(usr, x, name);
	}
	cstrcpy(name, p, MAX_NAME);
	sent += send_xmsg(usr, x, name);

	if (sent)
		send_xmsg_bcc(usr, x);		/* remember message as sent in 'this' user */
	else
		destroy_XMsg(x);
}
예제 #10
0
파일: util.c 프로젝트: walterdejong/bbs100
/*
	- it takes the cursor position into account for <hline> and <center> tags
	- when max_lines > -1, can display a limited number of lines
	  (used in --More-- prompt reading)
	- returns position in the string where it stopped
	- if dev is NULL, it produces no output, but does run the function and update the cursor pos
	- force_auto_color_off is used for hline tags, that really don't like auto-coloring

	- is_symbol says if it's a symbol that needs auto-coloring
	- dont_auto_color is for controlling exceptions to the rule of auto-coloring
*/
int Out_text(StringIO *dev, User *usr, char *str, int *cpos, int *lines, int max_lines, int force_auto_color_off) {
char buf[MAX_COLORBUF], c;
int pos, n, dont_auto_color, color, is_symbol;

	if (usr == NULL || usr->display == NULL || str == NULL || cpos == NULL || lines == NULL)
		return 0;

	if (max_lines > -1 && *lines >= max_lines)
		return 0;

	dont_auto_color = force_auto_color_off;

	pos = 0;
	while(*str) {
		is_symbol = 0;
		pos++;
		c = *str;

		if ((usr->flags & USR_HACKERZ) && HACK_CHANCE)
			c = hackerz_mode(c);

/* user-defined auto-coloring symbols */

		if ((usr->flags & (USR_ANSI|USR_DONT_AUTO_COLOR)) == USR_ANSI) {
			char *symbol_str;

			symbol_str = (usr->symbols == NULL) ? Default_Symbols : usr->symbols;
			if (cstrchr(symbol_str, c) != NULL) {
				is_symbol = 1;
/*
	auto-coloring a single dot is ugly, but multiple ones is fun
*/
				if (c == '.' && str[1] != '.' && (pos > 0 && str[-1] != '.'))
					dont_auto_color = AUTO_COLOR_FORCED;
			}
		}
/*
	word-wrap in display function
	Charset1 contains characters that break the line
*/
		if (cstrchr(Wrap_Charset1, c) != NULL) {
			if (*cpos + word_len(str+1) >= usr->display->term_width) {
				if (c != ' ') {
					if (is_symbol && !dont_auto_color) {
						auto_color(usr, buf, MAX_COLORBUF);
						put_StringIO(dev, buf);
					}
					write_StringIO(dev, str, 1);

					if (is_symbol && !dont_auto_color) {
						restore_colorbuf(usr, usr->color, buf, MAX_COLORBUF);
						put_StringIO(dev, buf);
					}
				}
				if (str[1] == ' ') {
					str++;
					pos++;
				}
				put_StringIO(dev, "\r\n");
				*cpos = 0;
				(*lines)++;
				if (max_lines > -1 && *lines >= max_lines)
					return pos;

				dont_auto_color = force_auto_color_off;

				if (*str)
					str++;
				continue;
			}
		} else {
/*
	pretty word-wrap: Charset2 contains characters that wrap along with the line
	mind that the < character is also used for long color codes
*/
			if (c != '<' && cstrchr(Wrap_Charset2, c) != NULL) {
				if (*cpos + word_len(str+1) >= usr->display->term_width) {
					write_StringIO(dev, "\r\n", 2);
					*cpos = 0;
					(*lines)++;
					if (max_lines > -1 && *lines >= max_lines)
						return pos-1;

					dont_auto_color = force_auto_color_off;
				}
			}
		}
		switch(c) {
			case '\b':
				write_StringIO(dev, "\b", 1);
				if (*cpos)
					(*cpos)--;

				dont_auto_color = force_auto_color_off;
				break;

			case '\n':
				write_StringIO(dev, "\r\n", 2);
				*cpos = 0;

				(*lines)++;
				if (max_lines > -1 && *lines >= max_lines)
					return pos;

				dont_auto_color = force_auto_color_off;
				break;

			case KEY_CTRL('Q'):								/* don't auto-color this string */
				dont_auto_color = AUTO_COLOR_FORCED;
				break;

			case KEY_CTRL('X'):
				write_StringIO(dev, "\r", 1);
				*cpos = 0;

				dont_auto_color = force_auto_color_off;
				break;

			case KEY_CTRL('A'):
				if (usr->flags & USR_BEEP)
					write_StringIO(dev, "\a", 1);

				dont_auto_color = force_auto_color_off;
				break;

			case KEY_CTRL('L'):				/* clear screen */
				if (usr->flags & (USR_ANSI|USR_BOLD))
					write_StringIO(dev, "\x1b[1;1H\x1b[2J", 10);
				break;

			case KEY_CTRL('Z'):
			case KEY_CTRL('R'):
			case KEY_CTRL('G'):
			case KEY_CTRL('Y'):
			case KEY_CTRL('B'):
			case KEY_CTRL('M'):
			case KEY_CTRL('C'):
			case KEY_CTRL('W'):
/*			case KEY_CTRL('F'):		*/
				if (usr->flags & USR_ANSI) {
					usr->color = c;
					color = Ansi_Color(usr, c);
					if (usr->flags & USR_BOLD)
						bufprintf(buf, sizeof(buf), "\x1b[1;%dm", color);
					else
						bufprintf(buf, sizeof(buf), "\x1b[%dm", color);
					put_StringIO(dev, buf);
					dont_auto_color = AUTO_COLOR_FORCED;
				}
				break;

			case KEY_CTRL('K'):
				str++;
				if (!*str)
					break;

				print_hotkey(usr, *str, buf, sizeof(buf), cpos);
				put_StringIO(dev, buf);

				dont_auto_color = force_auto_color_off;
				break;

			case KEY_CTRL('N'):
				if (usr->flags & USR_ANSI) {
					bufprintf(buf, sizeof(buf), "\x1b[0;%dm", color_table[usr->colors[BACKGROUND]].value+10);
					put_StringIO(dev, buf);
				} else
					if (usr->flags & USR_BOLD)
						put_StringIO(dev, "\x1b[0m");

				if (usr->flags & USR_BOLD)
					put_StringIO(dev, "\x1b[1m");

				dont_auto_color = force_auto_color_off;
				break;

			case KEY_CTRL('D'):
				if (usr->flags & (USR_ANSI | USR_BOLD))
					put_StringIO(dev, "\x1b[0m");

				dont_auto_color = force_auto_color_off;
				break;

/* long codes are specified as '<yellow>', '<beep>', etc. */

			case '<':
				n = long_color_code(dev, usr, str, cpos, lines, max_lines, dont_auto_color);
				if (n > 0)
					dont_auto_color = AUTO_COLOR_FORCED;
				str += n;
				pos += n;
				break;

			default:
				if (is_symbol && !dont_auto_color) {
					auto_color(usr, buf, MAX_COLORBUF);
					put_StringIO(dev, buf);
				}
				write_StringIO(dev, &c, 1);
				(*cpos)++;

				if (is_symbol && !dont_auto_color) {
					restore_colorbuf(usr, usr->color, buf, MAX_COLORBUF);
					put_StringIO(dev, buf);
				}
				if (!is_symbol)
					dont_auto_color = force_auto_color_off;
		}
		if (*str)
			str++;
	}
/*	Flush(usr);		the buffering code and mainloop() will flush for us */
	return pos;
}
예제 #11
0
파일: util.c 프로젝트: walterdejong/bbs100
/*
	long color codes look like '<yellow>', '<white>', '<hotkey>', etc.

	parsing the long color code is a slow function...
	but it makes programming with color coded strings a lot easier task

	it's more or less sorted in order of most frequent appearance to make
	it less slow

	cpos is the cursor position, which is used in <hline> and <center> tags
	for <hline>, the function recurses with Out_text()

	if dev is NULL, it produces no output
*/
int long_color_code(StringIO *dev, User *usr, char *code, int *cpos, int *lines, int max_lines, int dont_auto_color) {
int i, c, color;
char colorbuf[MAX_COLORBUF], buf[PRINT_BUF], *p;

	if (usr == NULL || code == NULL || !*code || cpos == NULL || lines == NULL)
		return 0;

	for(i = 0; i < NUM_COLORS; i++) {
		if (i == HOTKEY)
			continue;

		bufprintf(colorbuf, sizeof(colorbuf), "<%s>", color_table[i].name);

		if (!cstrnicmp(code, colorbuf, strlen(colorbuf))) {
			if (!(usr->flags & USR_ANSI))
				return strlen(colorbuf)-1;

			c = usr->color = color_table[i].key;

			color = Ansi_Color(usr, c);
			if (usr->flags & USR_BOLD)
				bufprintf(buf, sizeof(buf), "\x1b[1;%dm", color);
			else
				bufprintf(buf, sizeof(buf), "\x1b[%dm", color);
			put_StringIO(dev, buf);
			return strlen(colorbuf)-1;
		}
	}
/*
	Blinking is really irritating...

	if (!cstrnicmp(code, "<flash>", 7) || !cstrnicmp(code, "<blink>", 7)) {
		if (!(usr->flags & USR_ANSI))
			return 6;

		usr->color = KEY_CTRL('F');
		color = Ansi_Color(usr, KEY_CTRL('F'));
		if (usr->flags & USR_BOLD)
			bufprintf(buf, sizeof(buf), "\x1b[1;%dm", color);
		else
			bufprintf(buf, sizeof(buf), "\x1b[%dm", color);
		put_StringIO(dev, buf);
		return 6;
	}
*/
	if (!cstrnicmp(code, "<hotkey>", 8)) {
		c = code[8];
		if (!c)
			return 7;

		print_hotkey(usr, c, buf, sizeof(buf), cpos);
		put_StringIO(dev, buf);
		return 8;
	}
	if (!cstrnicmp(code, "<key>", 5)) {
		c = code[5];
		if (!c)
			return 4;
/*
	Don't do this; the <key> code is used in the Help files to keep this from happening

		if (usr->flags & USR_UPPERCASE_HOTKEYS)
			c = ctoupper(c);
*/
		if (usr->flags & USR_ANSI) {
			if (usr->flags & USR_BOLD)
				bufprintf(buf, sizeof(buf), "\x1b[1;%dm%c\x1b[1;%dm", color_table[usr->colors[HOTKEY]].value, c, Ansi_Color(usr, usr->color));
			else
				bufprintf(buf, sizeof(buf), "\x1b[%dm%c\x1b[%dm", color_table[usr->colors[HOTKEY]].value, c, Ansi_Color(usr, usr->color));

			(*cpos)++;
		} else {
			bufprintf(buf, sizeof(buf), "<%c>", c);
			*cpos += 3;
		}
		put_StringIO(dev, buf);
		return 5;
	}
	if (!cstrnicmp(code, "<beep>", 6)) {
		if (usr->flags & USR_BEEP)
			write_StringIO(dev, "\a", 1);
		return 5;
	}
	if (!cstrnicmp(code, "<normal>", 8)) {
		if (usr->flags & USR_ANSI) {
			bufprintf(buf, sizeof(buf), "\x1b[0;%dm", color_table[usr->colors[BACKGROUND]].value+10);
			put_StringIO(dev, buf);
		} else
			if (usr->flags & USR_BOLD)
				put_StringIO(dev, "\x1b[0m");

		if (usr->flags & USR_BOLD)
			put_StringIO(dev, "\x1b[1m");
		return 7;
	}
	if (!cstrnicmp(code, "<default>", 9)) {
		if (usr->flags & (USR_ANSI | USR_BOLD))
			put_StringIO(dev, "\x1b[0m");
		return 8;
	}
	if (!cstrnicmp(code, "<lt>", 4)) {
		if ((usr->flags & USR_ANSI) && !(usr->flags & USR_DONT_AUTO_COLOR) && !dont_auto_color) {
			auto_color(usr, colorbuf, MAX_COLORBUF);
			put_StringIO(dev, colorbuf);
		}
		write_StringIO(dev, "<", 1);
		(*cpos)++;

		if ((usr->flags & USR_ANSI) && !(usr->flags & USR_DONT_AUTO_COLOR) && !dont_auto_color) {
			restore_colorbuf(usr, usr->color, colorbuf, MAX_COLORBUF);
			put_StringIO(dev, colorbuf);
		}
		return 3;
	}
	if (!cstrnicmp(code, "<gt>", 4)) {
		if ((usr->flags & USR_ANSI) && !(usr->flags & USR_DONT_AUTO_COLOR) && !dont_auto_color) {
			auto_color(usr, colorbuf, MAX_COLORBUF);
			put_StringIO(dev, colorbuf);
		}
		write_StringIO(dev, ">", 1);
		(*cpos)++;

		if ((usr->flags & USR_ANSI) && !(usr->flags & USR_DONT_AUTO_COLOR) && !dont_auto_color) {
			restore_colorbuf(usr, usr->color, colorbuf, MAX_COLORBUF);
			put_StringIO(dev, colorbuf);
		}
		return 3;
	}

/*
	there are two special codes for use in help files and stuff...
	<hline> and <center>

	especially the code for hline is cryptic, but the idea is that
	it fills the line to the width of the terminal
*/
	if (!cstrnicmp(code, "<hline>", 7)) {
		int l;

		code += 7;
		if (!*code)
			return 6;

		c = ((usr->display->term_width-1) > PRINT_BUF) ? PRINT_BUF : (usr->display->term_width-1);
		cstrncpy(buf, code, c);
/*
	it stinks, but you have to remove all chars that can reset the cursor pos
*/
		p = buf;
		while(*p) {
			if (*p == KEY_CTRL('X') || *p == '\b')
				memmove(p, p+1, strlen(p+1)+1);
			else {
				if (*p == '\n') {		/* don't go over newlines */
					*p = 0;
					break;
				}
				p++;
			}
		}
		l = strlen(buf);
		i = color_strlen(buf);

		while(*cpos + i < usr->display->term_width-1)
			Out_text(dev, usr, buf, cpos, lines, max_lines, AUTO_COLOR_FORCED);	/* recurse */

		if (*cpos + i >= usr->display->term_width-1) {			/* 'partial put' of the remainder */
			buf[color_index(buf, c - *cpos)] = 0;
			Out_text(dev, usr, buf, cpos, lines, max_lines, AUTO_COLOR_FORCED);
		}
		return 6+l;
	}
	if (!cstrnicmp(code, "<center>", 8)) {
		code += 8;
		if (!*code)
			return 7;

		c = strlen(code);
		c = (c > PRINT_BUF) ? PRINT_BUF : c;
		cstrncpy(buf, code, c);
		buf[c-1] = 0;

		if ((p = cstrchr(buf, '\n')) != NULL)		/* don't go over newlines */
			*p = 0;

		i = (usr->display->term_width-1)/2 - color_strlen(buf)/2 - *cpos;
		while(i > 0) {
			write_StringIO(dev, " ", 1);
			(*cpos)++;
			i--;
		}
		return 7;
	}
	if ((usr->flags & USR_ANSI) && !(usr->flags & USR_DONT_AUTO_COLOR) && !dont_auto_color) {
		auto_color(usr, colorbuf, MAX_COLORBUF);
		put_StringIO(dev, colorbuf);
	}
	write_StringIO(dev, "<", 1);
	(*cpos)++;

	if ((usr->flags & USR_ANSI) && !(usr->flags & USR_DONT_AUTO_COLOR) && !dont_auto_color) {
		restore_colorbuf(usr, usr->color, colorbuf, MAX_COLORBUF);
		put_StringIO(dev, colorbuf);
	}
	return 0;
}
예제 #12
0
파일: util.c 프로젝트: walterdejong/bbs100
/*
	prints the entries in raw_list to create a menu in columns
	this routine looks a lot like the one that formats the wide who-list

	flags is FORMAT_NUMBERED|FORMAT_NO_UNDERSCORES
*/
void print_columns(User *usr, StringList *raw_list, int flags) {
int term_width, total, cols, rows, i, j, buflen, len, max_width, idx;
StringList *sl, *sl_cols[16];
char buf[MAX_LINE*4], format[MAX_LINE], filename[MAX_PATHLEN], *p;

	if (usr == NULL || raw_list == NULL)
		return;

	term_width = usr->display->term_width;
	if (term_width >= MAX_LONGLINE)
		term_width = MAX_LONGLINE;

	total = 0;
	max_width = 10;
	for(sl = raw_list; sl != NULL; sl = sl->next) {
		len = strlen(sl->str);
		if (len > max_width)
			max_width = len;
		total++;
	}
	if (flags & FORMAT_NUMBERED)
		bufprintf(format, sizeof(format), "%c%%3d %c%%-%ds", (char)color_by_name("green"), (char)color_by_name("yellow"), max_width);
	else
		bufprintf(format, sizeof(format), "%c%%-%ds", (char)color_by_name("yellow"), max_width);

	cols = term_width / (max_width+6);
	if (cols < 1)
		cols = 1;
	else
		if (cols > 15)
			cols = 15;

	rows = total / cols;
	if (total % cols)
		rows++;

	memset(sl_cols, 0, sizeof(StringList *) * cols);

/* fill in array of pointers to columns */

	sl = raw_list;
	for(i = 0; i < cols; i++) {
		sl_cols[i] = sl;
		for(j = 0; j < rows; j++) {
			if (sl == NULL)
				break;

			sl = sl->next;
		}
	}

/* make the menu text */

	for(j = 0; j < rows; j++) {
		idx = j + 1;

		buf[0] = 0;
		buflen = 0;

		for(i = 0; i < cols; i++) {
			if (sl_cols[i] == NULL || sl_cols[i]->str == NULL)
				continue;

			cstrcpy(filename, sl_cols[i]->str, MAX_PATHLEN);

			if (flags & FORMAT_NO_UNDERSCORES) {
				p = filename;
				while((p = cstrchr(p, '_')) != NULL)
					*p = ' ';
			}
			if (flags & FORMAT_NUMBERED)
				buflen += bufprintf(buf+buflen, sizeof(buf) - buflen, format, idx, filename);
			else
				buflen += bufprintf(buf+buflen, sizeof(buf) - buflen, format, filename);
			idx += rows;

			if ((i+1) < cols) {
				buf[buflen++] = ' ';
				buf[buflen++] = ' ';
				buf[buflen] = 0;
			}
			sl_cols[i] = sl_cols[i]->next;
		}
		buf[buflen++] = '\n';
		buf[buflen] = 0;
		Put(usr, buf);
	}
}
예제 #13
0
/* getopt() used for shell built-in commands, the getopts command, and
 * command line options.
 * A leading ':' in options means don't print errors, instead return '?'
 * or ':' and set go->optarg to the offending option character.
 * If GF_ERROR is set (and option doesn't start with :), errors result in
 * a call to bi_errorf().
 *
 * Non-standard features:
 *	- ';' is like ':' in options, except the argument is optional
 *	  (if it isn't present, optarg is set to 0).
 *	  Used for 'set -o'.
 *	- ',' is like ':' in options, except the argument always immediately
 *	  follows the option character (optarg is set to the null string if
 *	  the option is missing).
 *	  Used for 'read -u2', 'print -u2' and fc -40.
 *	- '#' is like ':' in options, expect that the argument is optional
 *	  and must start with a digit. If the argument doesn't start with a
 *	  digit, it is assumed to be missing and normal option processing
 *	  continues (optarg is set to 0 if the option is missing).
 *	  Used for 'typeset -LZ4'.
 *	- accepts +c as well as -c IF the GF_PLUSOPT flag is present. If an
 *	  option starting with + is accepted, the GI_PLUS flag will be set
 *	  in go->info.
 */
int
ksh_getopt(const char **argv, Getopt *go, const char *optionsp)
{
	char c;
	const char *o;

	if (go->p == 0 || (c = argv[go->optind - 1][go->p]) == '\0') {
		const char *arg = argv[go->optind], flag = arg ? *arg : '\0';

		go->p = 1;
		if (flag == '-' && arg[1] == '-' && arg[2] == '\0') {
			go->optind++;
			go->p = 0;
			go->info |= GI_MINUSMINUS;
			return (-1);
		}
		if (arg == NULL ||
		    ((flag != '-' ) && /* neither a - nor a + (if + allowed) */
		    (!(go->flags & GF_PLUSOPT) || flag != '+')) ||
		    (c = arg[1]) == '\0') {
			go->p = 0;
			return (-1);
		}
		go->optind++;
		go->info &= ~(GI_MINUS|GI_PLUS);
		go->info |= flag == '-' ? GI_MINUS : GI_PLUS;
	}
	go->p++;
	if (c == '?' || c == ':' || c == ';' || c == ',' || c == '#' ||
	    !(o = cstrchr(optionsp, c))) {
		if (optionsp[0] == ':') {
			go->buf[0] = c;
			go->optarg = go->buf;
		} else {
			warningf(true, "%s%s-%c: unknown option",
			    (go->flags & GF_NONAME) ? "" : argv[0],
			    (go->flags & GF_NONAME) ? "" : ": ", c);
			if (go->flags & GF_ERROR)
				bi_errorfz();
		}
		return ('?');
	}
	/* : means argument must be present, may be part of option argument
	 *   or the next argument
	 * ; same as : but argument may be missing
	 * , means argument is part of option argument, and may be null.
	 */
	if (*++o == ':' || *o == ';') {
		if (argv[go->optind - 1][go->p])
			go->optarg = argv[go->optind - 1] + go->p;
		else if (argv[go->optind])
			go->optarg = argv[go->optind++];
		else if (*o == ';')
			go->optarg = NULL;
		else {
			if (optionsp[0] == ':') {
				go->buf[0] = c;
				go->optarg = go->buf;
				return (':');
			}
			warningf(true, "%s%s-'%c' requires argument",
			    (go->flags & GF_NONAME) ? "" : argv[0],
			    (go->flags & GF_NONAME) ? "" : ": ", c);
			if (go->flags & GF_ERROR)
				bi_errorfz();
			return ('?');
		}
		go->p = 0;
	} else if (*o == ',') {
		/* argument is attached to option character, even if null */
		go->optarg = argv[go->optind - 1] + go->p;
		go->p = 0;
	} else if (*o == '#') {
		/* argument is optional and may be attached or unattached
		 * but must start with a digit. optarg is set to 0 if the
		 * argument is missing.
		 */
		if (argv[go->optind - 1][go->p]) {
			if (ksh_isdigit(argv[go->optind - 1][go->p])) {
				go->optarg = argv[go->optind - 1] + go->p;
				go->p = 0;
			} else
				go->optarg = NULL;
		} else {
			if (argv[go->optind] && ksh_isdigit(argv[go->optind][0])) {
				go->optarg = argv[go->optind++];
				go->p = 0;
			} else
				go->optarg = NULL;
		}
	}
	return (c);
}
예제 #14
0
파일: smatch.c 프로젝트: GlowMUCK/GlowMUCK
int 
smatch(char *s1, char *s2)
{
    char    ch, *start = s2;

    while (*s1) {
	switch (*s1) {
	    case '\\':
		if (!*(s1+1)) {
		    return 1;
		} else {
		    s1++;
		    if (DOWNCASE(*s1++) != DOWNCASE(*s2++))
			return 1;
		}
		break;
	    case '?':
		if (!*s2++)
		    return 1;
		s1++;
		break;
	    case '*':
		while (*s1 == '*' || (*s1 == '?' && *s2++))
		    s1++;
		if (*s1 == '?')
		    return 1;
		if (*s1 == '{') {
		    if (s2 == start)
			if (!smatch(s1, s2))
			    return 0;
		    while ((s2 = strchr(s2, ' ')) != NULL)
			if (!smatch(s1, ++s2))
			    return 0;
		    return 1;
		} else if (*s1 == '[') {
		    while (*s2)
			if (!smatch(s1, s2++))
			    return 0;
		    return 1;
		}
		if (*s1 == '\\' && *(s1+1))
		    ch = *(s1 + 1);
		else
		    ch = *s1;
		while ((s2 = cstrchr(s2, ch)) != NULL) {
		    if (!smatch(s1, s2))
			return 0;
		    s2++;
		}
		return 1;
	    case '[':
		{
		    char   *end;
		    int     tmpflg;

		    if (!(end = estrchr(s1, ']', '\\'))) {
			return 1;
		    }
		    *end = '\0';
		    tmpflg = cmatch(&s1[1], *s2++);
		    *end = ']';

		    if (tmpflg) {
			return 1;
		    }
		    s1 = end + 1;
		}
		break;
	    case '{':
		if (s2 != start && *(s2 - 1) != ' ')
		    return 1;
		{
		    char   *end;
		    int     tmpflg = 0;

		    if (s1[1] == '^')
			tmpflg = 1;

		    if (!(end = estrchr(s1, '}', '\\'))) {
			return 1;
		    }
		    *end = '\0';
		    tmpflg -= (wmatch(&s1[tmpflg + 1], &s2)) ? 1 : 0;
		    *end = '}';

		    if (tmpflg) {
			return 1;
		    }
		    s1 = end + 1;
		}
		break;
	    default:
		if (DOWNCASE(*s1++) != DOWNCASE(*s2++))
		    return 1;
		break;
	}
    }
    return DOWNCASE(*s1) - DOWNCASE(*s2);
}
예제 #15
0
파일: Room.c 프로젝트: walterdejong/bbs100
/*
	find a room by name
*/
Room *find_Room(User *usr, char *name) {
Room *r;

	if (name == NULL || !*name || usr == NULL)
		return NULL;

	if (*name >= '0' && *name <= '9')
		return find_Roombynumber(usr, (unsigned int)atoi(name));
	else {
		char *p, *quote;

		if (PARAM_HAVE_MAILROOM && !strcmp(name, "Mail"))
			return usr->mail;

		if (PARAM_HAVE_HOMEROOM && !strcmp(name, "Home"))
			return find_Home(usr->name);

		if ((p = cstrchr(name, '\'')) != NULL) {
			quote = p;
			*quote = 0;
			p++;
			if (*p == 's')
				p++;
			if (*p == ' ') {
				p++;
				if (PARAM_HAVE_MAILROOM && !strcmp(p, "Mail")) {
					User *u;

					if ((u = is_online(name)) == NULL) {
						int load_room_flags = LOAD_ROOM_ALL;

						if (!PARAM_HAVE_RESIDENT_INFO)
							load_room_flags &= ~LOAD_ROOM_INFO;

						r = load_Mail(name, load_room_flags);
						*quote = '\'';
						(void)prepend_Room(&HomeRooms, r);
						return r;
					}
					*quote = '\'';
					return u->mail;
				}
				if (PARAM_HAVE_HOMEROOM && !strcmp(p, "Home")) {
					r = find_Home(name);
					*quote = '\'';
					return r;
				}
			}
			*quote = '\'';
		}

/* find 'normal' room */

		for(r = AllRooms; r != NULL; r = r->next) {
			if (!strcmp(r->name, name)) {
				if (r->number == LOBBY_ROOM || r->number == MAIL_ROOM || r->number == HOME_ROOM)
					return find_Roombynumber(usr, r->number);

/* guess-name rooms can be found by typing the correct name */
				if (!PARAM_HAVE_GUESSNAME && !room_visible(usr, r))
					return NULL;

				if (!PARAM_HAVE_CHATROOMS && (r->flags & ROOM_CHATROOM))
					return NULL;
				return r;
			}
		}
	}
	return NULL;
}