Exemplo n.º 1
0
static void
toc_header(struct buf *ob, const struct buf *text, int level, void *opaque)
{
	struct html_renderopt *options = opaque;

	if (level <= options->toc_data.nesting_level) {
		/* set the level offset if this is the first header
		 * we're parsing for the document */
		if (options->toc_data.current_level == 0)
			options->toc_data.level_offset = level - 1;

		level -= options->toc_data.level_offset;

		if (level > options->toc_data.current_level) {
			while (level > options->toc_data.current_level) {
				BUFPUTSL(ob, "<ul>\n<li>\n");
				options->toc_data.current_level++;
			}
		} else if (level < options->toc_data.current_level) {
			BUFPUTSL(ob, "</li>\n");
			while (level < options->toc_data.current_level) {
				BUFPUTSL(ob, "</ul>\n</li>\n");
				options->toc_data.current_level--;
			}
			BUFPUTSL(ob,"<li>\n");
		} else {
			BUFPUTSL(ob,"</li>\n<li>\n");
		}

		bufprintf(ob, "<a href=\"#%s\">", header_anchor(text));

		if (text) {
			if (options->flags & HTML_ESCAPE)
				escape_html(ob, text->data, text->size);
			else
				bufput(ob, text->data, text->size);
		}

		BUFPUTSL(ob, "</a>\n");
	}
}
Exemplo n.º 2
0
static void
toc_header(struct buf *ob, const struct buf *text, int level, void *opaque)
{
	struct html_renderopt *options = opaque;

	/* set the level offset if this is the first header
	 * we're parsing for the document */
	if (options->toc_data.current_level == 0) {
		BUFPUTSL(ob, "<div class=\"toc\">\n");
		options->toc_data.level_offset = level - 1;
	}
	level -= options->toc_data.level_offset;

	if (level > options->toc_data.current_level) {
		while (level > options->toc_data.current_level) {
			BUFPUTSL(ob, "<ul>\n<li>\n");
			options->toc_data.current_level++;
		}
	} else if (level < options->toc_data.current_level) {
		BUFPUTSL(ob, "</li>\n");
		while (level < options->toc_data.current_level) {
			BUFPUTSL(ob, "</ul>\n</li>\n");
			options->toc_data.current_level--;
		}
		BUFPUTSL(ob,"<li>\n");
	} else {
		BUFPUTSL(ob,"</li>\n<li>\n");
	}

	BUFPUTSL(ob, "<a href=\"#");

	if (options->toc_id_prefix) {
		bufputs(ob, options->toc_id_prefix);
	}

	bufprintf(ob, "toc_%d\">", options->toc_data.header_count++);
	if (text)
		escape_html(ob, text->data, text->size);
	BUFPUTSL(ob, "</a>\n");
}
Exemplo n.º 3
0
static void
nat_paragraph(struct buf *ob, struct buf *text, void *opaque) {
	size_t i = 0;
	if (ob->size) bufputc(ob, '\n');
	BUFPUTSL(ob, "<p");
	if (text && text->size && text->data[0] == '(') {
		i = 1;
		while (i < text->size && (text->data[i] == ' '
			/* this seems to be a bit more restrictive than */
			/* what is allowed for class names */
			 || (text->data[i] >= 'a' && text->data[i] <= 'z')
			 || (text->data[i] >= 'A' && text->data[i] <= 'Z')
			 || (text->data[i] >= '0' && text->data[i] <= '0')))
			i += 1;
		if (i < text->size && text->data[i] == ')') {
			bufprintf(ob, " class=\"%.*s\"",
						(int)(i - 1), text->data + 1);
			i += 1; }
		else i = 0; }
	bufputc(ob, '>');
	if (text) bufput(ob, text->data + i, text->size - i);
	BUFPUTSL(ob, "</p>\n"); }
Exemplo n.º 4
0
unsigned long get_mail_top(char *username) {
char buf[MAX_PATHLEN], *p;
DIR *dirp;
struct dirent *direntp;
unsigned long maxnum = 0UL, n;

	bufprintf(buf, sizeof(buf), "%s/%c/%s/", PARAM_USERDIR, *username, username);
	path_strip(buf);
	if ((dirp = opendir(buf)) == NULL)
		return maxnum;

	while((direntp = readdir(dirp)) != NULL) {
		p = direntp->d_name;
		if (*p >= '0' && *p <= '9') {
			n = cstrtoul(p, 10);
			if (n > maxnum)
				maxnum = n;
		}
	}
	closedir(dirp);
	return maxnum;
}
Exemplo n.º 5
0
/*
	rm -rf : first empty directory, then remove directory
*/
int rm_rf_trashdir(char *dirname) {
char buf[MAX_PATHLEN], *bufp;
DIR *dirp;
struct dirent *direntp;

	if (dirname == NULL || !*dirname)
		return -1;

/* safety check */
	bufprintf(buf, sizeof(buf), "%s/", PARAM_TRASHDIR);
	path_strip(buf);
	if (strncmp(buf, dirname, strlen(buf)) || cstrstr(dirname, "..") != NULL)
		return -1;

	cstrcpy(buf, dirname, MAX_PATHLEN);
	bufp = buf+strlen(buf)-1;
	if (*bufp != '/') {
		bufp++;
		*bufp = '/';
		bufp++;
		*bufp = 0;
	}
	if ((dirp = opendir(buf)) == NULL)
		return -1;

	while((direntp = readdir(dirp)) != NULL) {
/* check for '.' and '..' directory */
		if (direntp->d_name[0] == '.' && (!direntp->d_name[1]
			|| (direntp->d_name[1] == '.' && !direntp->d_name[2])))
			continue;

		cstrcpy(bufp, direntp->d_name, MAX_PATHLEN);
		unlink(buf);		/* note: trash/ is not cached ; it's ok not to use unlink_file() */
	}
	closedir(dirp);
	return remove_dir(dirname);
}
Exemplo n.º 6
0
static void
toc_header(struct buf *ob, struct buf *text, int level, void *opaque)
{
	struct html_renderopt *options = opaque;

	while (level > options->toc_data.current_level) {
		if (options->toc_data.current_level > 0)
			BUFPUTSL(ob, "<li>");
		BUFPUTSL(ob, "<ul>\n");
		options->toc_data.current_level++;
	}

	while (level < options->toc_data.current_level) {
		BUFPUTSL(ob, "</ul>");
		if (options->toc_data.current_level > 1)
			BUFPUTSL(ob, "</li>\n");
		options->toc_data.current_level--;
	}

	bufprintf(ob, "<li><a href=\"#toc_%d\">", options->toc_data.header_count++);
	if (text)
		bufput(ob, text->data, text->size);
	BUFPUTSL(ob, "</a></li>\n");
}
Exemplo n.º 7
0
static void
nat_span(struct buf *ob, struct buf *text, char *tag) {
	bufprintf(ob, "<%s>", tag);
	bufput(ob, text->data, text->size);
	bufprintf(ob, "</%s>", tag); }
Exemplo n.º 8
0
static void
rndr_header(struct buf *ob, struct buf *text, int level, void *opaque) {
	if (ob->size) bufputc(ob, '\n');
	bufprintf(ob, "<h%d>", level);
	if (text) bufput(ob, text->data, text->size);
	bufprintf(ob, "</h%d>\n", level); }
Exemplo n.º 9
0
/*
	convert key code to long color code
	some key codes do not have a long equivalent

	flags can be USR_SHORT_DL_COLORS, which means that the color codes should be
	represented in short format
*/
int short_color_to_long(char c, char *buf, int max_len, int flags) {
int i;

	if (buf == NULL || max_len <= 0)
		return -1;

	buf[0] = 0;
	switch(c) {
		case KEY_CTRL('Q'):				/* don't auto-color this string */
			break;

		case KEY_CTRL('X'):
			break;

		case KEY_CTRL('A'):
			cstrcpy(buf, "<beep>", max_len);
			break;

		case KEY_CTRL('L'):				/* clear screen */
			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'):
			for(i = 0; i < NUM_COLORS; i++) {
				if (color_table[i].key == c) {
					if (flags & USR_SHORT_DL_COLORS) {
/*
	black is Ctrl-Z, but actually has to entered as Ctrl-K
	see also edit_color() in edit.c

	(this is confusing, but black is blacK, while the K is for hotkeys)
*/
						if (c == KEY_CTRL('Z'))
							c = KEY_CTRL('K');

						bufprintf(buf, max_len, "^%c", c + 'A' - 1);
					} else {
						bufprintf(buf, max_len, "<%s>", color_table[i].name);
						cstrlwr(buf);
					}
					break;
				}
			}
			break;

		case KEY_CTRL('K'):
			cstrcpy(buf, "<hotkey>", max_len);
			break;

		case KEY_CTRL('N'):
			cstrcpy(buf, "<normal>", max_len);
			break;

		case KEY_CTRL('D'):
			cstrcpy(buf, "<default>", max_len);
			break;

		default:
			if (c >= ' ' && c <= '~' && max_len >= 2) {
				buf[0] = c;
				buf[1] = 0;
			}
	}
	return 0;
}
Exemplo n.º 10
0
/*
	- 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;
}
Exemplo n.º 11
0
/*
	find_Room() with abbreviated name
*/
Room *find_abbrevRoom(User *usr, char *name) {
Room *r;
char room_name[MAX_LINE+2], match[MAX_LINE+2];

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

	if ((r = find_Room(usr, name)) == NULL) {
		int l;

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

				if (!room_visible(usr, r))
					continue;

				if (!PARAM_HAVE_CHATROOMS && (r->flags & ROOM_CHATROOM))
					continue;
				return r;
			}
		}
/*
	didn't find any room, try a substring that matches whole words
*/
		bufprintf(match, sizeof(match), " %s ", name);
		for(r = AllRooms; r != NULL; r = r->next) {
			bufprintf(room_name, sizeof(room_name), " %s ", r->name);
			if (cstrstr(room_name, match) != NULL) {
				if (r->number == LOBBY_ROOM || r->number == MAIL_ROOM || r->number == HOME_ROOM)
					return find_Roombynumber(usr, r->number);

				if (!room_visible(usr, r))
					continue;

				if (!PARAM_HAVE_CHATROOMS && (r->flags & ROOM_CHATROOM))
					continue;
				return r;
			}
		}
/*
	didn't find any room, try a substring that matches half words
*/
		for(r = AllRooms; r != NULL; r = r->next) {
			if (cstrstr(r->name, name) != NULL) {
				if (r->number == LOBBY_ROOM || r->number == MAIL_ROOM || r->number == HOME_ROOM)
					return find_Roombynumber(usr, r->number);

				if (!room_visible(usr, r))
					continue;

				if (!PARAM_HAVE_CHATROOMS && (r->flags & ROOM_CHATROOM))
					continue;
				return r;
			}
		}
		return NULL;
	}
	return r;
}
Exemplo n.º 12
0
/*
	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);
	}
}
Exemplo n.º 13
0
/* TODO: accuracy */
int ranged_attack( entity_t *atk, int tx, int ty )
{
	weapon_t *wpn;
	int cx = atk->x, cy = atk->y;

	if( !atk->in_hand )
	{
		if( atk == player )
		{
			buf_t *msg = bufnew( "You're not wielding anything!" );
			push_message( msg );
			bufdestroy( msg );
		}
		return 0;
	}

	if( atk->in_hand->type != ITEMTYPE_WEAPON )
	{
		if( atk == player )
		{
			buf_t *msg = bufnew( "You're not wielding a weapon!" );
			push_message( msg );
			bufdestroy( msg );
		}
		return 0;
	}

	wpn = (weapon_t*)atk->in_hand->specific;

	if( wpn->type != WEAPONTYPE_HANDGUN )
	{
		if( atk == player )
		{
			buf_t *msg = bufnew( "You're not wielding a ranged weapon!" );
			push_message( msg );
			bufdestroy( msg );
		}
		return 0;
	}

	/* consume ammo */
	if( wpn->ammo_loaded >= 1 )
	{
		wpn->ammo_loaded -= 1;
	}
	else
	{
		buf_t *msg = bufnew( "The clip is empty!" );
		push_message( msg );
		bufdestroy( msg );
		return 0;
	}

	if( atk == player )
	{
		buf_t *msg = bufnew( "You shoot your weapon!" );
		push_message( msg );
		bufdestroy( msg );
	}

	while( 1 )
	{
		cx += tx;
		cy += ty;
		
		if( is_legal( cx, cy ) &&
			( dungeon[atk->z]->terrain[cx][cy]->flags & TILEFLAG_SOLID ) )
		{
			/* you hit something solid */
			break;
		}
	
		attrset( COLOR_PAIR( C_RED ) );
		mvaddch( cy+2, cx, '*' );

		entity_t *e = entity_find_by_position( cx, cy, atk->z );
		if( e )
		{
			buf_t *msg = bufprintf( "You hit the %s!", e->name->data );
			push_message( msg );
			bufdestroy( msg );

			take_damage( e, wpn );

			break;
		}
	}

	refresh();
	msleep( 100 );

	return 1;
}
Exemplo n.º 14
0
int melee_attack( entity_t *atk, entity_t *def )
{
	if( !atk->in_hand )
	{
		if( atk == player )
		{
			buf_t *msg = bufprintf( "You %s the %s.", atk->natural->attack_name, def->name->data );
			push_message( msg );
			bufdestroy( msg );
		}
		else if( def == player )
		{
			buf_t *msg = bufprintf( "The %s %ss you.", atk->name->data, atk->natural->attack_name );
			push_message( msg );
			bufdestroy( msg );
		}

		take_damage( def, atk->natural );

		return 1;
	}

	if( atk->in_hand->type != ITEMTYPE_WEAPON )
	{
		if( atk == player )
		{
			buf_t *msg = bufnew( "You're not wielding a weapon." );
			push_message( msg );
			bufdestroy( msg );
		}
		return 0;
	}

	weapon_t *wpn = (weapon_t*)atk->in_hand->specific;

	if( wpn->type != WEAPONTYPE_MELEE )
	{
		/* TODO: ranged weapons that also have melee attacks? */
		if( atk == player )
		{
			buf_t *msg = bufnew( "You're not wielding a melee weapon." );
			push_message( msg );
			bufdestroy( msg );
		}
		return 0;
	}

	if( atk == player )
	{
		buf_t *msg = bufprintf( "You hit the %s!", def->name->data );
		push_message( msg );
		bufdestroy( msg );
	}
	else if( def == player )
	{
		buf_t *msg = bufprintf( "The %s hits you!", atk->name->data );
		push_message( msg );
		bufdestroy( msg );
	}

	take_damage( def, wpn );

	return 1;
}
Exemplo n.º 15
0
static int
rndr_footnote_ref(struct buf *ob, unsigned int num, void *opaque)
{
	bufprintf(ob, "<sup id=\"fnref%d\"><a href=\"#fn%d\" rel=\"footnote\">%d</a></sup>", num, num, num);
	return 1;
}
Exemplo n.º 16
0
/*
	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;
}
Exemplo n.º 17
0
/*
	load all rooms definitions at startup
	Note that room #1 and room #2 are 'shadow' rooms for Mail> and Home>
	the BBS cannot work without room #0, #1, and #2
*/
int init_Room(void) {
char buf[MAX_PATHLEN], *bufp;
DIR *dirp;
struct dirent *direntp;
struct stat statbuf;
Room *newroom;
unsigned int u;
int load_room_flags, len;

	printf("\n");

	listdestroy_Room(AllRooms);
	AllRooms = Lobby_room = NULL;

	load_room_flags = LOAD_ROOM_ALL;
	if (!PARAM_HAVE_RESIDENT_INFO)
		load_room_flags &= ~LOAD_ROOM_INFO;

	bufprintf(buf, sizeof(buf), "%s/", PARAM_ROOMDIR);
	path_strip(buf);
	len = strlen(buf);
	bufp = buf+len;

	if ((dirp = opendir(buf)) == NULL)
		return -1;

	while((direntp = readdir(dirp)) != NULL) {
		if (is_numeric(direntp->d_name)) {		/* only do numeric directories */
			cstrcpy(bufp, direntp->d_name, MAX_PATHLEN - len);
			if (stat(buf, &statbuf))
				continue;

			if ((statbuf.st_mode & S_IFMT) == S_IFDIR) {
				u = (unsigned int)cstrtoul(bufp, 10);

				printf("loading room %3u ... ", u);
				fflush(stdout);

				if ((newroom = load_Room(u, load_room_flags)) != NULL) {
					(void)prepend_Room(&AllRooms, newroom);
					room_readdir(newroom);
					printf("%s>\n", newroom->name);
				} else {
					printf("FAILED!\n");
					closedir(dirp);

					listdestroy_Room(AllRooms);
					AllRooms = Lobby_room = NULL;
					return -1;
				}
			}
		}
	}
	closedir(dirp);

	if (PARAM_HAVE_CATEGORY)
		(void)sort_Room(&AllRooms, room_sort_by_category);
	else
		(void)sort_Room(&AllRooms, room_sort_by_number);

/*
	find the Lobby>
	It should be first, but you never know...
*/
	if (Lobby_room == NULL) {
		Room *rm;

		for(rm = AllRooms; rm != NULL; rm = rm->next) {
			if (!rm->number) {
				Lobby_room = rm;
				break;
			}
		}
	}
	if (Lobby_room == NULL) {
		printf("Failed to find the Lobby> (room 0)\n"
			"Please create room definition file '%s/0/RoomData'\n", PARAM_ROOMDIR);

		listdestroy_Room(AllRooms);
		AllRooms = NULL;
		return -1;
	}
	printf("\n");
	return 0;
}