2 Copyright (C) Andrew Tridgell 2002
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; either version 2 of the License, or
7 (at your option) any later version.
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
14 You should have received a copy of the GNU General Public License
15 along with this program; if not, write to the Free Software
16 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20 support for the 'news' command
25 static TDB_CONTEXT *news_db;
27 /* close the news database */
36 open the news database
41 news_db = tdb_open(NEWS_DB, 0, 0, O_RDWR|O_CREAT, 0600);
43 d_printf("Unable to open news database!\n");
52 static void news_free(struct news *news)
60 return the maximum news item number
62 static int news_max(int admin)
64 return tdb_get_int(news_db, admin?"ADMIN_MAXNUM":"MAXNUM", 0);
70 static int news_save(int num, struct news *news, int admin)
75 /* marshall it into a string */
76 s = marshall_news(news);
81 asprintf(&name, "%s%u", admin?"ADMIN/":"", num);
82 if (tdb_set_string(news_db, name, s) != 0) {
91 if (news_max(admin) < num) {
92 tdb_set_int(news_db, admin?"ADMIN_MAXNUM":"MAXNUM", num);
102 static int news_load(int num, struct news *news, int admin)
108 asprintf(&name, "%s%u", admin?"ADMIN/":"", num);
109 s = tdb_get_string(news_db, name);
116 ret = unmarshall_news(news, s);
124 static int news_delete(int p, int num, int admin)
128 asprintf(&name, "%s%u", admin?"ADMIN/":"", num);
129 if (tdb_delete_string(news_db, name) == 0) {
130 pprintf(p,"Deleted news item %u\n", num);
132 pprintf(p,"Unable to delete news item %u !\n", num);
142 static int news_summary(int p, int first, int how_many, int admin)
148 for (i=first; i< first+how_many; i++) {
150 if (news_load(i, &news, admin) == 0) {
151 pprintf(p, "%4u (%s) %s\n",
153 strday(&news.post_date),
166 static int do_news(int p, param_list param, int admin)
171 if (param[0].type == TYPE_NULL) {
172 return news_summary(p, news_max(admin)-9, 10, admin);
174 if (strcasecmp(param[0].val.word, "all") == 0) {
175 return news_summary(p, 1, news_max(admin), admin);
178 num = atoi(param[0].val.word);
180 pprintf(p, "Bad news item number '%s'\n", param[0].val.word);
184 if (news_load(num, &news, admin) != 0) {
185 pprintf(p, "News item %u not found\n", num);
189 pprintf_more(p,"%4u (%s) %s\n\n%s\n\nPosted by %s.\n",
191 strday(&news.post_date),
204 int com_news(int p, param_list param)
206 return do_news(p, param, 0);
211 lookup a admin news item
213 int com_anews(int p, param_list param)
215 return do_news(p, param, 1);
220 create a new news item
222 static int cnewsi(int p, const char *title, int admin)
224 struct player *pp = &player_globals.parray[p];
229 news.poster = strdup(pp->name);
230 news.post_date = time(NULL);
231 news.message = strdup("");
232 news.title = strndup(title, 45);
234 num = news_max(admin) + 1;
235 ret = news_save(num, &news, admin);
238 pprintf(p,"Created news item %u\n", num);
240 pprintf(p,"Failed to create news item %u !\n", num);
250 static int cnewsf(int p, int num, const char *message, int admin)
255 if (news_load(num, &news, admin) != 0) {
256 pprintf(p, "News item %u not found\n", num);
260 asprintf(&msg, "%s%s\n", news.message, message);
264 if (news_save(num, &news, admin) != 0) {
265 pprintf(p, "News item %u could not be updated !\n", num);
270 pprintf(p, "News item %u updated\n", num);
277 set title on a news item
279 static int cnewst(int p, int num, const char *title, int admin)
283 if (news_load(num, &news, admin) != 0) {
284 pprintf(p, "News item %u not found\n", num);
289 news.title = strndup(title, 45);
291 if (news_save(num, &news, admin) != 0) {
292 pprintf(p, "News item %u could not be updated !\n", num);
297 pprintf(p, "News item %u updated\n", num);
304 set poster on a news item
306 static int cnewsp(int p, int num, int admin)
308 struct player *pp = &player_globals.parray[p];
311 if (news_load(num, &news, admin) != 0) {
312 pprintf(p, "News item %u not found\n", num);
317 news.poster = strdup(pp->name);
319 if (news_save(num, &news, admin) != 0) {
320 pprintf(p, "News item %u could not be updated !\n", num);
325 pprintf(p, "News item %u updated\n", num);
332 delete last line of an item
334 static int cnewsd(int p, int num, int admin)
339 if (news_load(num, &news, admin) != 0) {
340 pprintf(p, "News item %u not found\n", num);
344 news.message[strlen(news.message)-1] = 0;
345 s = strrchr(news.message, '\n');
352 if (news_save(num, &news, admin) != 0) {
353 pprintf(p, "News item %u could not be updated !\n", num);
358 pprintf(p, "News item %u updated\n", num);
366 set expiry on a news item
368 static int cnewse(int p, int num, int expiry, int admin)
372 if (news_load(num, &news, admin) != 0) {
373 pprintf(p, "News item %u not found\n", num);
379 return news_delete(p, num, admin);
380 } else if (expiry == 0) {
383 news.expires = time(NULL) + (expiry * 24*60*60);
386 if (news_save(num, &news, admin) != 0) {
387 pprintf(p, "News item %u could not be updated !\n", num);
392 pprintf(p, "News item %u updated\n", num);
399 create a normal news item
401 int com_cnewsi(int p, param_list param)
403 cnewsi(p, param[0].val.string, 0);
408 add to a normal news item
410 int com_cnewsf(int p, param_list param)
412 cnewsf(p, param[0].val.integer,
413 param[1].type != TYPE_NULL?param[1].val.string:"",
419 set title on a normal news item
421 int com_cnewst(int p, param_list param)
423 cnewst(p, param[0].val.integer, param[1].val.string, 0);
428 set poster on a normal news item
430 int com_cnewsp(int p, param_list param)
432 cnewsp(p, param[0].val.integer, 0);
437 set expiry on a normal news item
439 int com_cnewse(int p, param_list param)
442 param[0].val.integer,
443 param[1].type != TYPE_NULL?param[1].val.integer:-1,
449 delete last line on a normal news item
451 int com_cnewsd(int p, param_list param)
453 cnewsd(p, param[0].val.integer, 0);
458 create a admin news item
460 int com_canewsi(int p, param_list param)
462 cnewsi(p, param[0].val.string, 1);
467 add to a admin news item
469 int com_canewsf(int p, param_list param)
471 cnewsf(p, param[0].val.integer,
472 param[1].type != TYPE_NULL?param[1].val.string:"",
478 set title on a admin news item
480 int com_canewst(int p, param_list param)
482 cnewst(p, param[0].val.integer, param[1].val.string, 1);
487 set poster on a admin news item
489 int com_canewsp(int p, param_list param)
491 cnewsp(p, param[0].val.integer, 1);
496 set expiry on a admin news item
498 int com_canewse(int p, param_list param)
500 cnewse(p, param[0].val.integer,
501 param[1].type != TYPE_NULL?param[1].val.integer:-1,
507 delete last line on a admin news item
509 int com_canewsd(int p, param_list param)
511 cnewsd(p, param[0].val.integer, 1);
517 tell user about new news
519 void news_login(int p)
521 struct player *pp = &player_globals.parray[p];
525 if (max > pp->latest_news) {
526 pprintf(p,"\nThere are %u new news items since your last login\n",
527 max - pp->latest_news);
528 pp->latest_news = max;
531 if (!check_admin(p, ADMIN_ADMIN)) return;
534 if (max > pp->admin_latest_news) {
535 pprintf(p,"\nThere are %u new admin news items since your last login\n",
536 max - pp->admin_latest_news);
537 pp->admin_latest_news = max;