Beispiel #1
0
int main(int argc,char **argv)
{
    char path[256];
    char title[256];
    time_t now;
    int before;

    if (argc > 1)
        before = atoi(argv[1]);
    else
        before = 0;

    chdir(BBSHOME);
    bzero(&x[0], sizeof(x));

    if (init_all()) {
        printf("init data fail\n");
        return -1;
    }

    mysql_init(&s);

    if (! my_connect_mysql(&s)) {
        printf("Mysql connect error: %s\n",mysql_error(&s));
        return 0;
    }

    now=time(0) - 86400 - 86400*before;
    localtime_r(&now, &t);

    fillboard();

    mysql_close(&s);

    qsort(x, n, sizeof(x[0]), online_cmp);
    /* generate boards usage result in xml format */
    gen_board_rank_xml();

    sprintf(path,"tmp/brdlog.%d.out",getpid());
    putout(path);

    sprintf(title, "%d年%2d月%2d日版面统计数据(在线排序)", t.tm_year + 1900, t.tm_mon + 1, t.tm_mday);
    post_file(NULL, "", path, "SysTrace", title, 0, 1, getSession());
    unlink(path);

    qsort(x, n, sizeof(x[0]), id_cmp);

    sprintf(path,"tmp/brdlog.%d.out",getpid());
    putout(path);

    sprintf(title, "%d年%2d月%2d日版面统计数据(文章数排序)", t.tm_year + 1900, t.tm_mon + 1, t.tm_mday);
    post_file(NULL, "", path, "SysTrace", title, 0, 1, getSession());
    unlink(path);

    return 0;
}
Beispiel #2
0
int main(int argc, char **argv)
{
    time_t now;
    struct tm ptime;
    int i;

	if (init_all()) {
		printf("init data fail\n");
		return -1;
	}
    time(&now);
    ptime = *localtime(&now);
    force_refresh = false;    /* 增加强制重新统计十大功能 pig2532 2006.04.06 */
    if (argc == 2) {
        if (strcmp(argv[1], "refresh") == 0) {
            force_refresh = true;
        }
        else {
            i = atoi(argv[1]);
            if (i != 0 || argv[1][0]=='0') {
                poststat(i);
                return 0;
            }
        }
    }

    if ((ptime.tm_hour == 0) || force_refresh) {
		if (ptime.tm_yday == 1)
			poststat(3);
        if (ptime.tm_mday == 1)
            poststat(2);
        if (ptime.tm_wday == 0)
            poststat(1);
    }

    poststat(0);
    poststat(4);

    if (ptime.tm_hour == 23) {
        char fname[STRLEN];

        sprintf(fname, "%d年%2d月%2d日十大热门话题", ptime.tm_year + 1900, ptime.tm_mon + 1, ptime.tm_mday);
        post_file(NULL, "", "etc/posts/day", "BBSLists", fname, 0, 1, getSession());
        sprintf(fname, "%d年%2d月%2d日十大祝福话题", ptime.tm_year + 1900, ptime.tm_mon + 1, ptime.tm_mday);
        post_file(NULL, "", "etc/posts/bless", "BBSLists", fname, 0, 1, getSession());
        if (ptime.tm_wday == 6) {
            sprintf(fname, "%d年%2d月%2d日本周五十大热门话题", ptime.tm_year + 1900, ptime.tm_mon + 1, ptime.tm_mday);
            post_file(NULL, "", "etc/posts/week", "BBSLists", fname, 0, 1, getSession());
        }
    }
    return 0;
}
Beispiel #3
0
unsigned int close_segment(const char *name, unsigned int segment, FILE *f, int count) {
	char jsonfile[BUFLEN] = NULLSTR;
	SNPRINTF(jsonfile, BUFLEN, "%s_%02u", name, segment);

	fprintf(f, "\n},\n\"L\":%d\n}\n}\n}\n", count);
	fclose(f);
	// printf("OK\n");
	return post_file(jsonfile);
}
Beispiel #4
0
int main(int argc, char **argv){
	char path[256];
	char title[256];
	struct stat st;
	time_t now;
	struct tm t;
	int before=0;

chdir(BBSHOME);

if(argc > 1) before=atoi(argv[1]);

	now=time(0)-86400*before;
	localtime_r( &now, &t);

    if (init_all()) {
        printf("init data fail\n");
        return -1;
    }

sprintf(path, "%s/%d/%d/%d_boarduse.visit", BONLINE_LOGDIR, t.tm_year+1900, t.tm_mon+1, t.tm_mday);

if( stat( path, &st) >= 0){
    sprintf(title, "%d年%2d月%2d日版面使用数据(次数排序)", t.tm_year + 1900, t.tm_mon + 1, t.tm_mday);
    post_file(NULL, "", path, "SysTrace", title, 0, 1, getSession());
}

sprintf(path, "%s/%d/%d/%d_boarduse.total", BONLINE_LOGDIR, t.tm_year+1900, t.tm_mon+1, t.tm_mday);

if( stat( path, &st) >= 0){
    sprintf(title, "%d年%2d月%2d日版面使用数据(总时间排序)", t.tm_year + 1900, t.tm_mon + 1, t.tm_mday);
    post_file(NULL, "", path, "SysTrace", title, 0, 1, getSession());
}

    return 0;
}
Beispiel #5
0
int score_update_from_file( const char* filename )
{
	FILE* fd = fopen(filename,"r");
	FILE* update_fd;
	char  uid[IDLEN+2];
	char  reason[400];
	char  fname[STRLEN];
	int   score;
	int   flag;

	if ( fd == NULL )
	{
		printf("Cannot read file %s", filename);
		return 0;
	}

#ifdef CA_LOG
	fprintf( logfd, "------------------------------------------\n" );
#endif
	while ( fgets( reason, 400, fd ) )
	{
		update_fd = fopen("etc/posts/update_score","w+");
		sscanf( reason, "%s %d", uid, &score );
		if ( fgets( reason, 400, fd ) == NULL )
		{
			return 0;
		}
		if ( score > 0)
		{
#ifdef CA_LOG
			fprintf( logfd, "%s  +%d \n", uid, score );
#endif
			sprintf( fname, "[公告] 增加 %s 积分 %d 分", uid, score );
		}
		else
		{
#ifdef CA_LOG
			fprintf( logfd, "%s  %d \n", uid, score );
#endif
			sprintf( fname, "[公告] 扣除 %s 积分 %d 分", uid, score );

		}
			update_user_score( (const char*)uid, score );
		fprintf( update_fd, "说明:\n");
		fprintf( update_fd, "        %s\n", reason);
		fclose(update_fd);
		post_file(NULL, "", "etc/posts/update_score", "ScoreRecords", fname, 0, 1, getSession());
	}
#ifdef CA_LOG
	fprintf( logfd, "------------------------------------------\n" );
#endif
	fclose(fd);
	sprintf( fname, "%s.%04u%02u%02u.bak", 
			filename, local_time->tm_year + 1900,
			local_time->tm_mon + 1,
			local_time->tm_mday
			);
	flag = rename( filename, fname );
	if ( flag < 0 )
	{
		perror( "rename successfully\n" );
	}
	return 1;
}
Beispiel #6
0
int main(int argc, char* argv[])
{
	static int idx;
	int flag;
	int ex_score = 0;	
	int num_of_users = 0;
	int is_update = 0;
	FILE* top50_fd;
	char fname[STRLEN];
	//FILE* top100ex_fd;

#ifdef CA_LOG
	char* log_file_name = (char *)malloc(sizeof(char) * 20);
#endif

    if(setgid(BBSGID)==-1)
        exit(8);
    if(setuid(BBSUID)==-1)
        exit(8);

	curtime = time(NULL);
	local_time = localtime(&curtime);
	is_first_init = 0;

	count = 0;
	if(chdir(BBSHOME)==-1)
		return -1;
	if (init_all()) {
		printf("init data fail\n");
		return -2; 
	}
	apply_users(create_userlist,NULL);

	if( argc == 2)
	{
		if ( strncmp(argv[1], "--init", 6) == 0 ) 
			is_first_init = 1; 
		if ( strncmp( argv[1], "--update", 8 ) == 0 )
			is_update = 1;
	}


#ifdef CA_LOG
	sprintf( log_file_name, "scores.log.%d%02d%02d", 
			1900+local_time->tm_year, 1+local_time->tm_mon, local_time->tm_mday);
	logfd = fopen( log_file_name, "r" );
	if (logfd > 0)
	{
		fclose(logfd);
		logfd = fopen( log_file_name, "a+" );
		fprintf(logfd, "[%02u/%02u %02u:%02u]:\t\tCan't caculate scores second time a day\n", 
				local_time->tm_mon+1, local_time->tm_mday, local_time->tm_hour, local_time->tm_min);
		fclose(logfd);
		exit(1);
	}
	logfd = fopen( log_file_name, "a+" );
#endif

	flag = read_userscore_from_file(".SCORES", scorelist);
	/*读积分操作文件,对用户进行相应的积分增减*/
	if ( score_update_from_file("score_update.txt") == 0 )
	{
#ifdef CA_LOG
		fprintf( logfd, "No score update today\n" );
#endif
	}
	if ( is_update )
	{
		exit(1);
	}
	/*读文件结束*/
	
	for(idx=0;idx<count;idx++)
	{
		if(userlist[idx]->userid[0])
		{
			
#ifdef CA_DEBUG
			printf("------------------------\n");
			printf("[%s]\n", userlist[idx]->userid);
			printf("[%s]\n", userlist[idx]->username);
			printf("初始积分:%d\n", scorelist[idx].base_score);
#endif
			
			ex_score = 0;
			if(is_first_init)
			{
				//第一次创建文件的时候,把对应的用户ID拷贝过去
				strncpy(scorelist[idx].userid, userlist[idx]->userid, sizeof(scorelist[idx].userid) - 1);
				scorelist[idx].userid[sizeof(scorelist[idx].userid) - 1] = '\0';
				//计算基础积分了
				scorelist[idx].base_score = calculate_base_score(idx, userlist[idx]);
				scorelist[idx].ex_score = 0;
			}
			else 
			{
				if( scorelist[idx].userid[0] ){
					if( strcmp(userlist[idx]->userid, scorelist[idx].userid) != 0 )
					{
					//这部分用来验证用户的ID是否符合
#ifdef CA_DEBUG
						printf("user id error\n");
#endif
						strncpy(scorelist[idx].userid, userlist[idx]->userid, sizeof(scorelist[idx].userid) - 1);
						scorelist[idx].userid[sizeof(scorelist[idx].userid) - 1] = '\0';
						scorelist[idx].base_score = 0;
						scorelist[idx].ex_score = 0;
						continue;
					}
				}
				else
				{
					//说明遇到了新注册用户,需要拷贝用户ID
					strncpy(scorelist[idx].userid, userlist[idx]->userid, sizeof(scorelist[idx].userid) - 1);
					scorelist[idx].userid[sizeof(scorelist[idx].userid) - 1] = '\0';
					scorelist[idx].base_score = 0;
					scorelist[idx].ex_score = 0;
					continue;//新用户不用再计算积分了
				}
				//不是第一次创建文件,而且是老用户,计算积分增量
				if( strcmp("guest",scorelist[idx].userid)==0 )
				{
					scorelist[idx].base_score = 0;
					scorelist[idx].ex_score = 0;
					continue;
				}
				scorelist[idx].base_score = userlist[idx]->score;
				ex_score = calculate_ex_score(idx, userlist[idx]);
				scorelist[idx].base_score += ex_score;
				scorelist[idx].ex_score = ex_score;
			}
#ifdef CA_DEBUG
			printf("增加积分: %d\n", scorelist[idx].ex_score);
			printf("总积分: %d\n", scorelist[idx].base_score);
#endif
			p_scorelist[num_of_users].s = &scorelist[idx];
			p_scorelist[num_of_users].i = idx;
			num_of_users ++;
		}
		else
		{
			if(is_first_init)
			{
				scorelist[idx].base_score = 0;
				scorelist[idx].ex_score = 0;
				userlist[idx]->score_rank = 0;
				userlist[idx]->score = 0;
			}
		}
	}


/*******************************************************
 *  下面使用库函数qsort对积分进行排序
 *  同时输出日志
 *  将每日Top50总量排名和增量排名发文到ScoreRecords版
 ******************************************************/

	// 总量排名
	qsort(p_scorelist, num_of_users, sizeof(struct score_sort), cmp_base_score);
	//输出日志
	flag = write_userscore(".SCORES", scorelist);
	for(idx=0; idx<num_of_users; idx++)
	{
		p_scorelist[idx].s->rank = idx;
#ifdef CA_LOG
		fprintf(logfd, "[%02u/%02u %02u:%02u]:\t",
				local_time->tm_mon+1, local_time->tm_mday, 
				local_time->tm_hour, local_time->tm_min);
		fprintf(logfd,"%-16s", p_scorelist[idx].s->userid);
		fprintf(logfd,"=%-10d",p_scorelist[idx].s->base_score);
		fprintf(logfd,"+%-10d",p_scorelist[idx].s->ex_score);
		fprintf(logfd,"rank=%-6d",p_scorelist[idx].s->rank);
		userlist[ p_scorelist[idx].i ]->score_rank = (num_of_users-idx)*100000/num_of_users;
		fprintf(logfd,"%d.%d%%\n", userlist[ p_scorelist[idx].i ]->score_rank/1000, userlist[ p_scorelist[idx].i ]->score_rank%1000);
		userlist[ p_scorelist[idx].i ]->score = p_scorelist[idx].s->base_score;
#endif
	}
#ifdef CA_DEBUG
	if(flag<=0)
		printf("write error\n");
#endif
#ifdef CA_LOG
	fflush(logfd);
	fclose(logfd);
#endif
	//发文至ScoreRecords
	top50_fd = fopen("etc/posts/top50score","w+");
	fprintf(top50_fd, "名次 代号            昵称                                     积分      \n");
	fprintf(top50_fd, "==== ======================================================== ==========\n");
	for(idx=0; idx<50; idx++)
		fprintf(top50_fd, "[%2d] %-16s%-40s %-10d\n", 
				idx+1, p_scorelist[idx].s->userid, 
				userlist[ p_scorelist[idx].i ]->username,
				p_scorelist[idx].s->base_score);
	fflush(top50_fd);
	fclose(logfd);
	sprintf(fname, "%d年%2d月%2d日积分总量排名Top 50", local_time->tm_year+1900, local_time->tm_mon+1, local_time->tm_mday);
//	post_file(NULL, "", "etc/posts/top50score", "BBSLists", fname, 0, 1, getSession());
	post_file(NULL, "", "etc/posts/top50score", "ScoreRecords", fname, 0, 1, getSession());

	//增量排名
	qsort(p_scorelist, num_of_users, sizeof(struct score_sort), cmp_ex_socre);
	//发文至ScoreRecords
	top50_fd = fopen("etc/posts/top50exscore","w+");
	fprintf(top50_fd, "名次 代号            昵称                                     积分      \n");
	fprintf(top50_fd, "==== ======================================================== ==========\n");
	for(idx=0; idx<50; idx++)
		fprintf(top50_fd, "[%2d] %-16s%-40s %-10d\n", 
				idx+1, p_scorelist[idx].s->userid, 
				userlist[ p_scorelist[idx].i ]->username,
				p_scorelist[idx].s->ex_score);
	fflush(top50_fd);
	fclose(logfd);
	sprintf(fname, "%d年%2d月%2d日积分增量排名Top 50", local_time->tm_year+1900, local_time->tm_mon+1, local_time->tm_mday);
//	post_file(NULL, "", "etc/posts/top50exscore", "BBSLists", fname, 0, 1, getSession());
	post_file(NULL, "", "etc/posts/top50exscore", "ScoreRecords", fname, 0, 1, getSession());

	return 0;
}
Beispiel #7
0
static int encode_and_post(newspost_data *data, SList *file_list,
			    SList *parfiles) {
	int number_of_parts;
	int number_of_files;
	int i;
	file_entry *file_data = NULL;
	int retval = NORMAL;
	char *data_buffer = 
		(char *) malloc(get_buffer_size_per_encoded_part(data));
	Buff *subject = NULL;
	Buff *text_buffer = NULL;

	/* create the socket */
	ui_socket_connect_start(data->address->data);
	retval = socket_create(data->address->data, data->port);
	if (retval < 0)
		return retval;

	ui_socket_connect_done();

	/* log on to the server */
	ui_nntp_logon_start(data->address->data);
	if (nntp_logon(data) == FALSE) {
		socket_close();
		return LOGON_FAILED;
	}
	ui_nntp_logon_done();

	if (data->text == TRUE) {
		file_data = file_list->data;
		/* post */
		text_buffer = read_text_file(text_buffer, file_data->filename->data);
		if(text_buffer != NULL)
			retval = nntp_post(data->subject->data, data, text_buffer->data,
					   text_buffer->length, TRUE);
	}
	else {
		/* post any sfv files... */
		if (data->sfv != NULL) {
			file_data = file_entry_alloc(file_data);
			file_data->filename = 
				buff_create(file_data->filename, "%s", data->sfv->data);
			if (stat(data->sfv->data, &file_data->fileinfo) == -1)
				ui_sfv_gen_error(data->sfv->data, errno);
			else {
				retval = post_file(data, file_data, 1, 1,
						   "SFV File", data_buffer);
				if (retval < 0)
					return retval;

				unlink(data->sfv->data);
			}
			free(file_data);
		}

		number_of_files = slist_length(file_list);

		/* if there's a prefix, post that */
		if (data->prefix != NULL) {
			ui_posting_prefix_start(data->prefix->data);

			file_data = (file_entry *) file_list->data;
			number_of_parts = 
				get_number_of_encoded_parts(data, file_data);
			subject = make_subject(subject, data, 1 , number_of_files,
				     file_data->filename->data, 0 , number_of_parts,
				     "File");

			text_buffer = read_text_file(text_buffer, data->prefix->data);
			if (text_buffer != NULL) {
				retval = nntp_post(subject->data, data, text_buffer->data, 
						   text_buffer->length, TRUE);
				if (retval == POSTING_NOT_ALLOWED)
					return retval;
				else if (retval == POSTING_FAILED) {
					/* dont bother retrying...
					   who knows what's in that file */
					ui_posting_prefix_failed();
					retval = NORMAL;
				}
				else if (retval == NORMAL)
					ui_posting_prefix_done();
			}
			else
				ui_posting_prefix_failed();

			buff_free(subject);
		}
	
		/* post the files */
		i = 1;
		while (file_list != NULL) {

			file_data = (file_entry *) file_list->data;

			retval = post_file(data, file_data, i, number_of_files,
					   "File", data_buffer);
			if (retval < 0)
				return retval;

			i++;
			file_list = slist_next(file_list);
		}

		/* post any par files */
		i = 1;
		file_list = parfiles;
		number_of_files = slist_length(parfiles);
		while (file_list != NULL) {

			file_data = (file_entry *) file_list->data;

			retval = post_file(data, file_data, i, number_of_files,
					   "PAR File", data_buffer);
			if (retval < 0)
				return retval;

			unlink(file_data->filename->data);
			buff_free(file_data->filename);
			free(file_data);
			i++;
			file_list = slist_next(file_list);
		}
		slist_free(parfiles);
	}

	nntp_logoff();
	socket_close();
	
	free(data_buffer);
	buff_free(text_buffer);

	return retval;
}
Beispiel #8
0
/*
create table `toplog` (
 `id` int unsigned NOT NULL auto_increment,
 `userid` char(15) NOT NULL default '',
 `bname` char(31) NOT NULL default '',
 `title` char(81) NOT NULL default '',
 `time` timestamp NOT NULL,
 `date` date NOT NULL,
 `topth` int NOT NULL default '1',
 `count` int NOT NULL default '0',
 `threadid` int unsigned NOT NULL default '0',
 PRIMARY KEY (`id`),
 KEY userid (`userid`),
 KEY bname(`bname`, `threadid`),
 KEY date(`date`),
 UNIQUE top (`date`,`topth`)
) TYPE=MyISAM COMMENT='toplog';

create table `toplog_all` (
 `id` int unsigned NOT NULL auto_increment,
 `userid` char(15) NOT NULL default '',
 `bname` char(31) NOT NULL default '',
 `title` char(81) NOT NULL default '',
 `time` timestamp NOT NULL,
 `date` date NOT NULL,
 `topth` int NOT NULL default '1',
 `count` int NOT NULL default '0',
 `threadid` int unsigned NOT NULL default '0',
 PRIMARY KEY (`id`),
 KEY userid (`userid`),
 KEY bname(`bname`, `threadid`),
 KEY date(`date`),
) TYPE=MyISAM COMMENT='toplog_all';
*/
int log_top()
{
    MYSQL s;
    char sqlbuf[500];
    char newtitle[161];
    int i;
    char newts[20];
    time_t now;
    struct tm ptime;

    mysql_init(&s);

    if (! my_connect_mysql(&s)) {
        return 0;;
    }

    for (i=0;i<topnum;i++) {

        mysql_escape_string(newtitle, top[i].title, strlen(top[i].title));

#ifdef NEWSMTH
        MYSQL_RES *res;
        MYSQL_ROW row;
        sprintf(sqlbuf, "SELECT id FROM toplog_all WHERE date=CURDATE() AND bname='%s' AND threadid=%d; ", top[i].board, top[i].groupid);
        if (mysql_real_query(&s, sqlbuf, strlen(sqlbuf))) {
            printf("%s\n", mysql_error(&s));
        } else {
            res = mysql_store_result(&s);
            row = mysql_fetch_row(res);
            if (row==NULL) {
                char title[STRLEN],file[STRLEN];
                // auto post top10 to ShiDa
                sprintf(title, "[%s] %s", top[i].board,top[i].title);
                sprintf(file, "boards/%s/%s", top[i].board,top[i].filename);
                post_file(NULL, "", file , "ShiDa", title, 0, 1, getSession());
                // insert into toplog_all
                sprintf(sqlbuf, "INSERT INTO toplog_all VALUES (NULL,'%s','%s','%s','%s',CURDATE(),'%d','%d','%d');",top[i].userid, top[i].board, newtitle, tt2timestamp(top[i].date,newts), i+1, top[i].number, top[i].groupid);
                if (mysql_real_query(&s, sqlbuf, strlen(sqlbuf))) {
                    printf("%s\n", mysql_error(&s));
                }
            } else {
                // update toplog_all
                sprintf(sqlbuf,"UPDATE toplog_all SET userid='%s',bname='%s',title='%s',count='%d',time='%s',threadid='%d' WHERE date=CURDATE() AND bname='%s' AND threadid=%d;;", top[i].userid, top[i].board, newtitle, top[i].number, tt2timestamp(top[i].date,newts), top[i].groupid, top[i].board, top[i].groupid);
                if (mysql_real_query(&s, sqlbuf, strlen(sqlbuf))) {
                    printf("%s\n", mysql_error(&s));
                }
            }
        }
        time(&now);
        ptime = *localtime(&now);
        if (ptime.tm_hour == 23) {
            total_post_top10(top[i].groupid,top[i].board,top[i].title);
        }
#endif

        sprintf(sqlbuf,"UPDATE toplog SET userid='%s',bname='%s',title='%s',count='%d',time='%s',threadid='%d' WHERE date=CURDATE() AND topth='%d';", top[i].userid, top[i].board, newtitle, top[i].number, tt2timestamp(top[i].date,newts), top[i].groupid, i+1);

        if (mysql_real_query(&s, sqlbuf, strlen(sqlbuf))) {
            printf("%s\n", mysql_error(&s));
            continue;
        }
        if ((int)mysql_affected_rows(&s) <= 0) {
            sprintf(sqlbuf, "INSERT INTO toplog VALUES (NULL,'%s','%s','%s','%s',CURDATE(),'%d','%d','%d');",top[i].userid, top[i].board, newtitle, tt2timestamp(top[i].date,newts), i+1, top[i].number, top[i].groupid);
            if (mysql_real_query(&s, sqlbuf, strlen(sqlbuf))) {
                printf("%s\n", mysql_error(&s));
                continue;
            }
        }
    }

    mysql_close(&s);

    return 1;
}
Beispiel #9
0
unsigned int close_datafile(const char *name, FILE *f) {
	fprintf(f, "\n}\n}\n");
	fclose(f);
	// printf("OK\n");
	return post_file(name);
}
Beispiel #10
0
int main(int argc, char* argv[]) {
	int c;
	char *dbname = (char *)DBNAME;
	char *dbinst = (char *)DBINST;
	char *hostname = (char *)HOSTNAME;
	char *datadir = NULL;
	char *verdesc = NULL;
	char *verstr = NULL;
	char *prefix = NULL;
	unsigned int version = 0;
	char *schemastr = NULL;
	unsigned short usage = 0;
	unsigned short dblist = 0;
	unsigned short schemalist = 0;
	unsigned short prefixlist = 0;
	unsigned short trusted = 1;
	unsigned char term = '\0';

	// source files
	char udd_sql3[BUFLEN] = NULLSTR;
	char cert_yaml[BUFLEN] = NULLSTR;
	char gfxids_yaml[BUFLEN] = NULLSTR;
	char iconids_yaml[BUFLEN] = NULLSTR;
	char typeids_yaml[BUFLEN] = NULLSTR;
	char blueprints_yaml[BUFLEN] = NULLSTR;

	// SQL things
	int db3_rc;
	SQLRETURN ret;
	SQLCHAR connStrOut[BUFLEN] = NULLSTR;
	SQLCHAR dsn[BUFLEN] = NULLSTR;
	SQLCHAR auth[BUFLEN] = NULLSTR;
	SQLCHAR usr[BUFLEN] = NULLSTR;
	SQLCHAR pwd[BUFLEN] = NULLSTR;
	SQLSMALLINT connStrLen;

	// set globals
	GZIP_FLAG = 1;
	JSONP_FLAG = 1;
	SCHEMA = 0;
	JSON_DIR = NULL;
	H_ENV = SQL_NULL_HENV;
	H_DBC = SQL_NULL_HDBC;
	H_DBC2 = SQL_NULL_HDBC;
	DB3_UD = NULL;

	while ((c = getopt(argc, argv, "i:o:d:u:p:n:N:s:x:hvXDSZP")) != -1) {
		switch (c) {
		case 'i':
			datadir = (char *)malloc(BUFLEN);
			strlcpy(datadir, optarg, BUFLEN);
			term = datadir[strlen(datadir) - 1];
			if (term != PATHSEP) {
				strlcat(datadir, SZPATHSEP, BUFLEN);
			}
			break;
		case 'o':
			JSON_DIR = (char *)malloc(BUFLEN);
			strlcpy(JSON_DIR, optarg, BUFLEN);
			term = JSON_DIR[strlen(JSON_DIR) - 1];
			if (term != PATHSEP) {
				strlcat(JSON_DIR, SZPATHSEP, BUFLEN);
			}
			break;
		case 'x':
			prefix = (char *)malloc(BUFLEN);
			strlcpy(prefix, optarg, BUFLEN);
			break;
		case 'd':
			dbname = (char *)malloc(BUFLEN);
			strlcpy(dbname, optarg, BUFLEN);
			break;
		case 'n':
			verstr = (char *)malloc(BUFLEN);
			strlcpy(verstr, optarg, BUFLEN);
			break;
		case 'N':
			verdesc = (char *)malloc(BUFLEN);
			strlcpy(verdesc, optarg, BUFLEN);
			break;
		case 's':
			schemastr = (char *)malloc(BUFLEN);
			strlcpy(schemastr, optarg, BUFLEN);
			break;
		case 'S':
			schemalist = 1;
			break;
		case 'v':
			printf("sdd2json version %d.%d.%d", SDD2JSON_V_MAJOR, SDD2JSON_V_MINOR, SDD2JSON_V_PATCH);
			return 0;
		case 'D':
			dblist = 1;
			break;
		case 'u':
			trusted = 0;
			strlcpy(usr, optarg, BUFLEN);
			break;
		case 'p':
			trusted = 0;
			strlcpy(pwd, optarg, BUFLEN);
			break;
		case 'P':
			JSONP_FLAG = 0;
			break;
		case 'Z':
			GZIP_FLAG = 0;
			break;
		case 'X':
			prefixlist = 1;
		case '?':
			printf("\n");
			usage = 1;
			break;
		}
	}

	if (1 == schemalist) {
		for (unsigned int i = 0; i < VERS_N; i++) {
			printf("%s:\tversion %d;\tschema %d\n", VERS[i].version_desc, VERS[i].version_id, VERS[i].schema_id);
		}
		return 0;
	}

	if (1 == prefixlist) {
		printf("\tcrp\n");
		printf("\tdgm\n");
		printf("\tinv\n");
		printf("\tmap\n");
		printf("\tram\n");
		printf("\tsta\n");
		return 0;
	}

	if (usage < 1 && datadir == NULL) {
		fprintf(stderr, "EVE static data dir path is required\n");
		usage = 1;
	}

	if (usage < 1 && verstr == NULL) {
		fprintf(stderr, "static data version ID is required\n");
		usage = 1;
	}

	if (usage > 0) return dump_usage();

	// parse version/schema from params and known values
	if (verstr != NULL) {
		version = atoi(verstr);
	}
	if (version == 0) {
		fprintf(stderr, "the static data version ID provided is invalid: %s\n", verstr);
		return 1;
	}
	unsigned int found_version = 0;
	for (unsigned int i = 0; i < VERS_N; i++) {
		if (VERS[i].version_id == version) {
			found_version = 1;
			SCHEMA = VERS[i].schema_id;
			if (NULL == verdesc) {
				verdesc = (char *)malloc(BUFLEN);
				strlcpy(verdesc, VERS[i].version_desc, BUFLEN);
			}
			break;
		}
	}
	if (1 != found_version) {
		fprintf(stderr, "warning: using unknown static data version ID: %d\n", version);
	}
	if (schemastr != NULL) {
		if (0 != SCHEMA) {
			fprintf(stderr, "warning: overriding known schema ID\n");
		}
		SCHEMA = atoi(schemastr);
	}
	if (0 == SCHEMA) {
		fprintf(stderr, "schema ID is required\n");
		return 1;
	}
	printf("static data: '%s', version %d, schema %d\n", verdesc, version, SCHEMA);

	// validate input/schema
	printf("checking input: %s - ", datadir);
	if (ACCESS(datadir, 0) != 0) {
		printf("err\n");
		fprintf(stderr, "could not access output path\n");
		return 1;
	}
		
	if (SCHEMA >= 100038) {
		strlcpy(cert_yaml, datadir, BUFLEN);
		strlcat(cert_yaml, "certificates.yaml", BUFLEN);
		if (ACCESS(cert_yaml, 0) != 0) {
			printf("err\n");
			fprintf(stderr, "could not access %s\n", cert_yaml);
			return 1;
		}
	}

	if (SCHEMA >= 100038) {
		strlcpy(gfxids_yaml, datadir, BUFLEN);
		strlcat(gfxids_yaml, "graphicIDs.yaml", BUFLEN);
		if (ACCESS(gfxids_yaml, 0) != 0) {
			printf("err\n");
			fprintf(stderr, "could not access %s\n", gfxids_yaml);
			return 1;
		}
	}

	if (SCHEMA >= 100038) {
		strlcpy(iconids_yaml, datadir, BUFLEN);
		strlcat(iconids_yaml, "iconIDs.yaml", BUFLEN);
		if (ACCESS(iconids_yaml, 0) != 0) {
			printf("err\n");
			fprintf(stderr, "could not access %s\n", iconids_yaml);
			return 1;
		}
	}

	if (SCHEMA >= 100038) {
		strlcpy(typeids_yaml, datadir, BUFLEN);
		strlcat(typeids_yaml, "typeIDs.yaml", BUFLEN);
		if (ACCESS(typeids_yaml, 0) != 0) {
			printf("err\n");
			fprintf(stderr, "could not access %s\n", typeids_yaml);
			return 1;
		}
	}

	if (SCHEMA >= 100038) {
		strlcpy(udd_sql3, datadir, BUFLEN);
		strlcat(udd_sql3, "universeDataDx.db", BUFLEN);
		if (ACCESS(udd_sql3, 0) != 0) {
			printf("err\n");
			fprintf(stderr, "could not access %s\n", udd_sql3);
			return 1;
		}
	}

	if (SCHEMA >= 100038) {
		strlcpy(blueprints_yaml, datadir, BUFLEN);
		strlcat(blueprints_yaml, "blueprints.yaml", BUFLEN);
		if (ACCESS(blueprints_yaml, 0) != 0) {
			printf("err\n");
			fprintf(stderr, "could not access %s\n", blueprints_yaml);
			return 1;
		}
	}

	printf("OK\n");

	// validate output
	if (JSON_DIR == NULL) {
		JSON_DIR = (char *)malloc(2 * BUFLEN);
		strlcpy(JSON_DIR, datadir, 2 * BUFLEN);
		strlcat(JSON_DIR, SDD, 2* BUFLEN);
		strlcat(JSON_DIR, SZPATHSEP, 2 * BUFLEN);
	}
	printf("checking output: %s - ", JSON_DIR);
	if (ACCESS(JSON_DIR, 0) != 0) {
		if (MKDIR(JSON_DIR) != 0) {
			printf("err\n");
			fprintf(stderr, "could not create output path\n");
			return 1;
		}
		if (ACCESS(JSON_DIR, 0) != 0) {
			printf("err\n");
			fprintf(stderr, "could not access output path\n");
			return 1;
		}
	}
	printf("OK\n");

	// connect to SQLLITE dbs
	printf("connecting to [%s] - ", udd_sql3);

	db3_rc = sqlite3_open(udd_sql3, &DB3_UD);
	if (SQLITE_OK != db3_rc) return dump_db3_error(DB3_UD, 1);
	printf("OK\n");

	// connect to SQL server
	if (0 != trusted) {
		SNPRINTF(auth, BUFLEN, "Trusted_Connection=yes");
	}
	else {
		SNPRINTF(auth, BUFLEN, "User ID=%s;Password=%s", usr, pwd);
	}
	printf("connecting to [%s\\%s] using [%s] - ", hostname, dbinst, auth);

	ret = SQLAllocHandle(SQL_HANDLE_ENV, SQL_NULL_HENV, &H_ENV);
	if (!SQL_SUCCEEDED(ret)) return dump_sql_error(ret, SQL_HANDLE_ENV, H_ENV, 1);
	ret = SQLSetEnvAttr(H_ENV, SQL_ATTR_ODBC_VERSION, (void *)SQL_OV_ODBC3_80, 0);
	if (!SQL_SUCCEEDED(ret)) return dump_sql_error(ret, SQL_HANDLE_ENV, H_ENV, 1);

	if (dblist > 0) {
		printf("list drivers\n");
		unsigned short ret = check_drivers(1);
		close_handles();
		return ret;
	}

	if (0 != check_drivers(0)) {
		printf("err\n");
		fprintf(stderr, "SQL server driver not found\n");
		close_handles();
		return 1;
	}

	ret = SQLAllocHandle(SQL_HANDLE_DBC, H_ENV, &H_DBC);
	if (!SQL_SUCCEEDED(ret)) return dump_sql_error(ret, SQL_HANDLE_ENV, H_ENV, 1);
	ret = SQLAllocHandle(SQL_HANDLE_DBC, H_ENV, &H_DBC2);
	if (!SQL_SUCCEEDED(ret)) return dump_sql_error(ret, SQL_HANDLE_ENV, H_ENV, 1);

	SNPRINTF(dsn, BUFLEN, "Driver={%s};Server=%s\\%s;Database=%s;%s;", SQLDRV, hostname, dbinst, dbname, auth);
	ret = SQLDriverConnect(H_DBC, NULL, dsn, strnlen(dsn, BUFLEN), connStrOut, BUFLEN, &connStrLen, SQL_DRIVER_NOPROMPT);
	if (!SQL_SUCCEEDED(ret)) return dump_sql_error(ret, SQL_HANDLE_DBC, H_DBC, 1);
	ret = SQLDriverConnect(H_DBC2, NULL, dsn, strnlen(dsn, BUFLEN), connStrOut, BUFLEN, &connStrLen, SQL_DRIVER_NOPROMPT);
	if (!SQL_SUCCEEDED(ret)) return dump_sql_error(ret, SQL_HANDLE_DBC, H_DBC2, 1);

	printf("OK\n");

	// create metainfo file
	char metafile[BUFLEN] = NULLSTR;
	strlcpy(metafile, JSON_DIR, BUFLEN);
	strlcat(metafile, "metainf.json", BUFLEN);
	FILE *f = fopen(metafile, "w");
	if (f == NULL) {
		printf("err\n");
		fprintf(stderr, "error opening meta file: %s", metafile);
		close_handles();
		return 1;
	}
	printf("OK\n");
	fprintf(f, "{\n");
	fprintf(f, "\"formatID\":%d,\n", FORMAT_ID);
	fprintf(f, "\"schema\":%d,\n", SCHEMA);
	fprintf(f, "\"copy\":\"%s\",\n", CCPR);
	fprintf(f, "\"version\":%d,\n", version);
	fprintf(f, "\"verdesc\":\"%s\",\n", verdesc);
	fprintf(f, "\"tables\":{\n");

	// do stuff
	int rc = 0;
	int comma = 0;

	if (NULL == prefix || strncmp(prefix, "crp", 3) == 0) {
		if (comma++ > 0) fprintf(f, ",\n");
		rc = create_crp(f);
		if (rc != 0) {
			close_handles();
			fclose(f);
			return 1;
		}
	}

	if (NULL == prefix || strncmp(prefix, "dgm", 3) == 0) {
		if (comma++ > 0) fprintf(f, ",\n");
		rc = create_dgm(f, cert_yaml);
		if (rc != 0) {
			close_handles();
			fclose(f);
			return 1;
		}
	}

	if (NULL == prefix || strncmp(prefix, "inv", 3) == 0) {
		if (comma++ > 0) fprintf(f, ",\n");
		rc = create_inv(f, typeids_yaml, iconids_yaml);
		if (rc != 0) {
			close_handles();
			fclose(f);
			return 1;
		}
	}

	if (NULL == prefix || strncmp(prefix, "map", 3) == 0) {
		if (comma++ > 0) fprintf(f, ",\n");
		rc = create_map(f);
		if (0 != rc) {
			close_handles();
			fclose(f);
			return 1;
		}
	}

	if (NULL == prefix || strncmp(prefix, "ram", 3) == 0) {
		if (comma++ > 0) fprintf(f, ",\n");
		ret = create_ram(f, blueprints_yaml);
		if (!SQL_SUCCEEDED(ret)) {
			close_handles();
			fclose(f);
			return 1;
		}
	}

	if (NULL == prefix || strncmp(prefix, "sta", 3) == 0) {
		if (comma++ > 0) fprintf(f, ",\n");
		ret = create_sta(f);
		if (!SQL_SUCCEEDED(ret)) {
			close_handles();
			fclose(f);
			return 1;
		}
	}

	fprintf(f, "\n}\n"); // end of sources

	// clean up connections
	fprintf(f, "}\n");
	fclose(f);
	printf("metainf - ", metafile);
	post_file("metainf");

	close_handles();

	free(datadir);
	free(verdesc);
	free(verstr);
	free(prefix);
	free(JSON_DIR);

	printf("\nall done!\n");

	return 0;
}