📄 bbspost.c
字号:
/* * File: scanboard.c * * A part of innbbsd, SEEDNetBBS v1 series * $Id: bbspost.c,v 1.8 1999/06/12 23:24:33 edwardc Exp $ */char *ProgramUsage = "\bbspost (list|visit) bbs_home\n\ post board_path < uid + title + Article...\n\ mail board_path < uid + title + passwd + realfrom + Article...\n\ cancel bbs_home board filename\n\ expire bbs_home board days [max_posts] [min_posts]\n";#include <stdio.h>#include <string.h>#include <unistd.h>#include <sys/stat.h>#include <sys/types.h>#if !defined(PalmBBS) #include "bbs.h"#include "../innbbsconf.h"#define INNDHOME BBSHOME"/innd"#define MAXLEN 1024char *crypt();char *homepath;int visitflag;char realfrom[ MAXLEN ];usage(){ printf( ProgramUsage ); exit( 0 );}report(){ /* Function called from record.o */ /* Please leave this function empty */}intci_strcmp( s1, s2 )register char *s1, *s2;{ char c1, c2; while( 1 ) { c1 = *s1++; c2 = *s2++; if( c1 >= 'a' && c1 <= 'z' ) c1 += 'A' - 'a'; if( c2 >= 'a' && c2 <= 'z' ) c2 += 'A' - 'a'; if( c1 != c2 ) return (c1 - c2); if( c1 == 0 ) return 0; }}void search_article( brdname )char *brdname;{ struct fileheader head; struct stat state; char index[ MAXLEN ], article[ MAXLEN ]; int fd, num, offset, type; char send; offset = (int) &(head.filename[ STRLEN - 1 ]) - (int) &head; sprintf( index, "%s/boards/%s/.DIR", homepath, brdname ); if( (fd = open( index, O_RDWR )) < 0 ) { return; } fstat( fd, &state ); num = (state.st_size / sizeof( head )) - 1; while( num >= 0 ) { lseek( fd, (off_t) (num * sizeof( head )) + offset, 0 ); if( read( fd, &send, 1 ) > 0 && send == '%' ) break; num -= 4; } num++; if( num < 0 ) num = 0; lseek( fd, (off_t) (num * sizeof( head )), 0 ); for( send = '%'; read( fd, &head, sizeof( head )) > 0; num++ ) { type = head.filename[ STRLEN - 1 ]; if( type != send && visitflag ) { lseek( fd, (off_t) (num * sizeof( head )) + offset, 0 ); safewrite( fd, &send, 1 ); lseek( fd, (off_t) ((num + 1) * sizeof( head )), 0 ); } if( type == '\0' ) { printf( "%s\t%s\t%s\t%s\n", brdname, head.filename, head.owner, head.title ); } } close( fd );}void search_boards( visit ){ struct dirent *de; DIR *dirp; char buf[ 8192 ], *ptr; int fd, len; visitflag = visit; sprintf( buf, "%s/boards", homepath ); if ((dirp = opendir( buf )) == NULL ) { printf( ":Err: unable to open %s\n", buf ); return; } printf( "New article listed:\n" ); while ((de = readdir( dirp )) != NULL ) { if( de->d_name[0] > ' ' && de->d_name[0] != '.' ) search_article( de->d_name ); } closedir( dirp );}check_password( record )struct userec *record;{ FILE *fn; char *pw; char passwd[ MAXLEN ]; char genbuf[ MAXLEN ]; gets( passwd ); pw = crypt( passwd, record->passwd ); if( strcmp( pw, record->passwd ) != 0 ) { printf( ":Err: user '%s' password incorrect!!\n", record->userid ); exit( 0 ); } gets( realfrom );/* sprintf( genbuf, "tmp/email_%s", record->userid ); if( (fn = fopen( genbuf, "w" )) != NULL ) { fprintf( fn, "%s\n", realfrom ); fclose( fn ); }*/ if( !strstr( realfrom, "bbs@" ) ) { record->termtype[ 15 ] = '\0'; strncpy( record->termtype+16, realfrom, STRLEN-16 ); } if( !strstr( homepath, "test" ) ) { record->numposts++; }}check_userec( record, name )struct userec *record;char *name;{ int fh; if( (fh = open( ".PASSWDS", O_RDWR )) == -1 ) { printf( ":Err: unable to open .PASSWDS file.\n" ); exit( 0 ); } while( read( fh, record, sizeof *record ) > 0 ) { if( ci_strcmp( name, record->userid ) == 0 ) { strcpy( name, record->userid ); check_password( record ); lseek( fh, (off_t) (-1 * sizeof *record), SEEK_CUR ); safewrite( fh, record, sizeof *record ); close( fh ); return; } } close( fh ); printf( ":Err: unknown userid %s\n", name ); exit( 0 );}post_article( usermail ){ struct userec record; struct fileheader header; char userid[ MAXLEN ], subject[ MAXLEN ]; char index[ MAXLEN ], name[ MAXLEN ], article[ MAXLEN ]; char buf[ MAXLEN ], *ptr; FILE *fidx; int fh,islocalpost; time_t now; sprintf( index, "%s/.DIR", homepath ); if( (fidx = fopen( index, "r" )) == NULL ) { if( (fidx = fopen( index, "w" )) == NULL ) { printf( ":Err: Unable to post in %s.\n", homepath ); return; } } fclose( fidx ); gets( userid ); gets( subject ); if( usermail ) { check_userec( &record, userid ); } now = time( NULL ); sprintf( name, "M.%d.A", now ); ptr = strrchr( name, 'A' ); while( 1 ) { sprintf( article, "%s/%s", homepath, name ); fh = open( article, O_CREAT | O_EXCL | O_WRONLY, 0644 ); if( fh != -1 ) break; if( *ptr < 'Z' ) (*ptr)++; else ptr++, *ptr = 'A', ptr[1] = '\0'; } printf( "post to %s\n", article ); if( usermail ) { char local[MAXLEN]; gets(local); islocalpost=strcmp(local,"localpost"); ptr = strrchr( homepath, '/' ); (ptr == NULL) ? (ptr = homepath) : (ptr++); sprintf( buf, "\发信人: %s (%s), 信区: %s\n\标 题: %s\n\发信站: %s (%24.24s), %s\n\n", userid, record.username, ptr, subject, BBSNAME, ctime( &now ) ,islocalpost?"转信":"站内信件"); write( fh, buf, strlen( buf ) ); } while( fgets( buf, MAXLEN, stdin ) != NULL ) { write( fh, buf, strlen( buf ) ); } if( usermail ) { FILE *foo; char outname[80]; /*写入转信档*/ if(islocalpost) { sprintf(outname,"%s/out.bntp",INNDHOME); if (foo = fopen(outname, "a")) { fprintf(foo, "%s\t%s\t%s\t%s\t%s\n", ptr, name, userid, record.username, subject); fclose(foo); } } realfrom[20]='\0'; sprintf(buf,"\n--\n[1;36m☆ 来源:·%s %s·[FROM: %s]\n",BBSNAME, BBSHOST, realfrom); write( fh, buf, strlen( buf ) ); } close( fh ); bzero( (void *)&header, sizeof( header ) ); strcpy( header.filename, name ); strncpy( header.owner, userid, IDLEN ); strncpy( header.title, subject, STRLEN ); if( ! usermail ) { header.filename[ STRLEN - 1 ] = 'M'; } append_record( index, &header, sizeof( header ) );}cancel_article( board, file, message )char *board, *file, *message;{ struct fileheader header; struct stat state; char dirname[ MAXLEN ]; char buf[ MAXLEN ]; long numents, size, time, now; int fd, lower, ent; if( file == NULL || file[0] != 'M' || file[1] != '.' || (time = atoi( file+2 )) <= 0 ) return; size = sizeof( header ); sprintf( dirname, "%s/boards/%s/.DIR", homepath, board ); if( (fd = open( dirname, O_RDWR )) == -1 ) return; flock( fd, LOCK_EX ); fstat( fd, &state ); ent = ((long)state.st_size) / size; lower = 0; while( 1 ) { ent -= 8; if( ent <= 0 || lower >= 2 ) break; lseek( fd, (off_t) (size * ent), SEEK_SET ); if( read( fd, &header, size ) != size ) { ent = 0; break; } now = atoi( header.filename + 2 ); lower = (now < time) ? lower + 1 : 0; } if( ent < 0 ) ent = 0; while( read( fd, &header, size ) == size ) { if( strcmp( file, header.filename ) == 0 ) { sprintf( buf, "-%s", header.owner ); strcpy( header.owner, buf ); if (message && *message) strcpy( header.title, "<< E-mail post 文章审核中... >>" ); else strcpy( header.title, "<< article canceled >>" ); lseek( fd, (off_t) -size, SEEK_CUR ); safewrite( fd, &header, size ); break; } now = atoi( header.filename + 2 ); if( now > time ) break; } flock( fd, LOCK_UN ); close( fd );}expire_article( brdname, days_str, maxpost, minpost )char *brdname, *days_str;{ struct fileheader head; struct stat state; char lockfile[ MAXLEN ], index[ MAXLEN ]; char tmpfile[ MAXLEN ], delfile[ MAXLEN ]; int days, total; int fd, fdr, fdw, done, keep; int duetime, ftime; days = atoi( days_str ); if( days < 1 ) { printf( ":Err: expire time must more than 1 day.\n" ); return; } else if( maxpost < 100 ) { printf( ":Err: maxmum posts number must more than 100.\n" ); return; } sprintf( lockfile, "%s/.dellock", homepath, brdname ); sprintf( index, "%s/boards/%s/.DIR", homepath, brdname ); sprintf( tmpfile, "%s/.tmpfile", homepath, brdname ); sprintf( delfile, "%s/.deleted", homepath, brdname ); if( (fd = open( lockfile, O_RDWR | O_CREAT | O_APPEND, 0644 )) == -1 ) return; flock( fd, LOCK_EX ); unlink( tmpfile ); duetime = time( NULL ) - days * 24*60*60; done = 0; if( (fdr = open( index, O_RDONLY, 0 )) > 0 ) { fstat( fdr, &state ); total = state.st_size / sizeof( head ); if( (fdw = open( tmpfile, O_WRONLY|O_CREAT|O_EXCL, 0644 )) > 0 ) { while( read( fdr, &head, sizeof head ) == sizeof head ) { done = 1; ftime = atoi( head.filename + 2 ); if( head.owner[0] == '-' ) keep = 0; else if( head.accessed[0] & FILE_MARKED || total <= minpost ) keep = 1; else if( ftime < duetime || total > maxpost ) keep = 0; else keep = 1; if( keep ) { if( safewrite( fdw, &head, sizeof head ) == -1 ) { done = 0; break; } } else { printf( "Unlink %s\n", head.filename ); if( head.owner[0] == '-' ) printf( "Unlink %s.cancel\n", head.filename ); total --; } } close( fdw ); } close( fdr ); } if( done ) { unlink( delfile ); if( rename( index, delfile ) != -1 ) { rename( tmpfile, index ); } } flock( fd, LOCK_UN ); close( fd );}main( argc, argv )char *argv[];{ char *progmode; int max, min; if( argc < 3 ) usage(); progmode = argv[1]; homepath = argv[2]; if( ci_strcmp( progmode, "list" ) == 0 ) { search_boards( 0 ); } else if( ci_strcmp( progmode, "visit" ) == 0 ) { search_boards( 1 ); } else if( ci_strcmp( progmode, "post" ) == 0 ) { post_article( 0 ); } else if( ci_strcmp( progmode, "mail" ) == 0 ) { post_article( 1 ); } else if( ci_strcmp( progmode, "cancel" ) == 0 ) { if( argc < 5 ) usage(); if ( argc >= 6) cancel_article( argv[3], argv[4], argv[5] ); else cancel_article( argv[3], argv[4] ); } else if( ci_strcmp( progmode, "expire" ) == 0 ) { if( argc < 5 ) usage(); max = atoi( argc > 5 ? argv[5] : "9999" ); min = atoi( argc > 6 ? argv[6] : "10" ); expire_article( argv[3], argv[4], max, min ); }}#elsemain(){ printf("You must use the bbspost in palmbbs source\n");}#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -