ClusterMembership::ClusterMembership(const IpAddress &bindaddr, const IpAddress &clusteraddr, int ifindex)
{
	// Set qhand to null initially
	qhand = 0;
	// Open multicast socket...
	sock = makesock(bindaddr);
	// Join multicast group(s)
	multisetup(sock, bindaddr, ifindex);
	// Make it nonblocking.
	SetNonBlocking(sock);
	this->clusteraddr = clusteraddr;
	this->localaddr = bindaddr;
	// Record the startup time
	gettimeofday(& starttime, 0);
	effectiveWeight = 0;
	// Add our own host to "nodes"
	nodes[bindaddr] = NodeInfo();
	nodes[bindaddr].isme = true;
	nodes[bindaddr].isup = true;
	nodes[bindaddr].weight = effectiveWeight;
}
Beispiel #2
0
int main(int argc, char *argv[]) {
	if (argv[1] == NULL) {
		puts("missing parameters");
		return 0;
	}
	char service[100];
	int fd[USER_NUM + 2];
	fd_set fdsets;
	uint32_t request[4];
	uint32_t response[22];
	int i,j,k,n;
	int error;

	strcpy(service, argv[1]);
	
	fd[0] = makesock(service);

	if (fd[0] < 0) {
		printf("unable to create socket, connection, or binding %i\n", fd[0]);
		return 0;
	}
	printf("binding success! sock: %i\n", fd[0]);
	
	error = listen(fd[0], USER_NUM);
	if (error < 0) {
		fprintf(stderr,"unable to listen error: %s(%d)\n", gai_strerror(error), error);
		return 0;
	}
	printf("listen success!\n");

	for(i=1;i<USER_NUM+2;i++) {
		fd[i] = -1;
	}
	//int msg_length, n;

	int sockCount = 1;
	srand((unsigned)time(NULL));
	struct timeval tv;
	time_t timer;
	struct sockaddr_storage ss;
	timer = time(NULL);
	socklen_t sl;
	sl = sizeof(ss);

	while(sockCount <= USER_NUM)
	{
		FD_ZERO(&fdsets);
		tv.tv_sec = 0;
		tv.tv_usec = 10;
		for (i=0; i<sockCount; i++) {
			if (fd[i] != (-1)) {
				FD_SET(fd[i], &fdsets);
			}
		}

		if ((n = select(FD_SETSIZE, &fdsets, NULL, NULL, &tv)) == -1) {
			printf("error in select");
		}

		if (FD_ISSET(fd[0], &fdsets) != 0) {
			printf("adding new user. current user count: %d\n", sockCount);
			fd[sockCount] = accept(fd[0], (struct sockaddr *)&ss, &sl);
			if (fd[sockCount] < 0) {
				fprintf(stderr,"socket error: %s(%d)\n", gai_strerror(fd[sockCount]), fd[sockCount]);
			}
			printf("new user accepted: %d\n", sockCount);
			sockCount++;
		}
	}

	timer = time(NULL);
	int turn = 0;

	struct gamePlayer players[USER_NUM];
	struct company companies[COMPANY_NUM];

	for (i=0;i<COMPANY_NUM;i++) {
		companies[i].price = 50 + rand()%100;
	}

	for (i=0;i<USER_NUM;i++) {
		players[i].budget[0] = 10000;
		players[i].count = 0;
		players[i].key = randomHash();
		response[0] = players[i].key;
		response[1] = 0x00000000;
		for (k=0; k<COMPANY_NUM; k++) {
			players[i].tickets[k] = 0;
			players[i].purchase[k] = 0;
			players[i].sale[k] = 0;
			response[2*k+2] = k;
			response[2*k+3] = companies[k].price;
		}
		for (k=0; k<22; k++) {
			uint32_t tmp = htonl(response[k]);
			write(fd[i+1],&tmp,sizeof(tmp));
		}
	}

	for(;;)
	{	
		tv.tv_sec = 0;
		tv.tv_usec = 10;

		if (difftime(time(NULL), timer) > 1) {
			int company_p[COMPANY_NUM];
			for(i=0; i<COMPANY_NUM; i++) {
				company_p[i] = 0;
			}
			printf("15 seconds has passed\n");
			for (i=1; i<USER_NUM+1; i++) {
				if (fd[i] != (-1)) {
					if (FD_ISSET(fd[i], &fdsets)) {
						for (k=0; k<4; k++) {
							error = read(fd[i], &request[k], sizeof(request[k]));
							request[k] = ntohl(request[k]);
						}
						response[0] = request[0];
						for (k=0; k<COMPANY_NUM; k++) {
							response[2*k+2] = k;
							response[2*k+3] = 0x00000000;
						}

						response[1] = status(players[i-1], companies, request[0], request[1], request[2], request[3], turn);
						//printf("response code for user %d is %x\n", i-1, response[1]);

						if (response[1] == ACCEPT) {
							if(request[1] == PURCHASE) {
								players[i-1].purchase[request[2]] += request[3];
								printf("purchasing company id: %d (price: %d) quantity: %d\n",request[2], companies[request[2]].price, request[3]);
							} else {
								players[i-1].sale[request[2]] += request[3];
								printf("selling company id: %d (price: %d) quantity: %d\n",request[2], companies[request[2]].price, request[3]);
							}
							response[request[2]*2+3] = request[3];
						} else if (response[1] == ERR_PUR) {
							response[request[2]*2+3] = request[3];
							printf("!ERROR in purchasing company id: %d (price: %d) quantity: %d\nYour current budget is %d\n\n",request[2], companies[request[2]].price, request[3], players[i-1].budget[turn]);
						} else if (response[1] == ERR_SAL) {
							response[request[2]*2+3] = request[3];
							printf("!ERROR in selling company id: %d (price: %d) quantity: %d\nYou only have %d tickets\n\n",request[2], companies[request[2]].price, request[3], players[i-1].tickets[request[2]]);
						}

						for (k=0; k<22; k++) {
							uint32_t tmp = htonl(response[k]);
							write(fd[i],&tmp,sizeof(tmp));
						}
					}
				} else {
					printf("fd[%d] is -1\n", i);
				}
				k=0;
				printf("\n==== User ID: %d on Turn %d ====\n", i-1, turn);
				for(j=0; j<COMPANY_NUM; j++) {
					printf("company id: %d\npurchasing %d tickets, selling %d tickets\n BEFORE: %d tickets left", j, players[i-1].purchase[j], players[i-1].sale[j], players[i-1].tickets[j]);
					k += (players[i-1].purchase[j] - players[i-1].sale[j]) * companies[j].price;
					//purchase 
					players[i-1].tickets[j] += players[i-1].purchase[j];
					company_p[j] += players[i-1].purchase[j];
					players[i-1].purchase[j] = 0;
					//sale
					players[i-1].tickets[j] -= players[i-1].sale[j];
					company_p[j] -= players[i-1].sale[j];
					players[i-1].sale[j] = 0;
					printf(" AFTER: %d tickets left\n", players[i-1].tickets[j]);
				}
				printf("left over budget BEFORE: %d and k: %d\n", players[i-1].budget[turn], k);
				players[i-1].budget[turn] -= k;
				//printf("left over budget %d\n======\n", players[i-1].budget[turn]);
				players[i-1].count = 0;
			}
			int addition = 0;
			for (k=0; k<COMPANY_NUM; k++) {
				addition += company_p[k];
			}
			if (addition == 0) {
				for (k=0; k<COMPANY_NUM; k++) {
					companies[k].price = companies[k].price - 5 + rand()%11;
				}
			} else {
				for (k=0; k<COMPANY_NUM; k++) {
					companies[k].price = companies[k].price - 5 + rand()%11 + companies[k].price/10*company_p[k]/addition;
				}
			}
			turn++;
			if (turn != 12*PLAY_YEARS) {
				for(i=0; i<USER_NUM; i++) {
					players[i].budget[turn] = players[i].budget[turn-1];
					players[i].key = randomHash();
					response[0] = players[i].key;
					response[1] = 0x00000000;
					for (k=0; k<COMPANY_NUM; k++) {
						response[2*k+2] = k;
						response[2*k+3] = companies[k].price;
					}
					for (k=0; k<22; k++) {
						uint32_t tmp = htonl(response[k]);
						write(fd[i+1], &tmp, sizeof(tmp));
					}
				}
				printf("=== TURN: %d ===\n", turn);
				for (k=0; k<COMPANY_NUM; k++) {
					response[2*k+2] = k;
					response[2*k+3] = companies[k].price;
					printf("%d : %i\n", k, companies[k].price);
				}
				printf("======\n");
			}
			timer = time(NULL);
		}
		if (turn == 12*PLAY_YEARS) {
			response[0] = 0x00000000;
			response[1] = 0x00000002;
			int rank[USER_NUM];
			int list[USER_NUM];
			int u;
			for (i=0; i<USER_NUM; i++) {
				list[i] = players[i].budget[turn-1];
			}
			for (i=0; i<USER_NUM; i++) {
				u = 0;
				for (j=0; j<USER_NUM; j++) {
					if (list[j] > list[u]) {
						u = j;
					}
				}
				list[u] = 0;
				rank[i] = u;
			}
			for (i=0; i<USER_NUM; i++) {
				j = 0;
				while(i != rank[j]) {
					j++;
				}
				response[2] = j+1;
				response[3] = players[i].budget[turn-1];
				for (k=0; k<4; k++) {
					uint32_t tmp = htonl(response[k]);
					write(fd[i+1],&tmp,sizeof(tmp));
				}
			}
			break;
		}
		FD_ZERO(&fdsets);
		for (i=0; i<USER_NUM+1; i++) {
			if (fd[i] != (-1)) {
				FD_SET(fd[i], &fdsets);
			}
		}

		if ((n = select(FD_SETSIZE, &fdsets, NULL, NULL, &tv)) == -1) {
			printf("error in select");
		}

		if (FD_ISSET(fd[0], &fdsets) != 0) {
			fd[USER_NUM+1] = accept(fd[0], (struct sockaddr *)&ss, &sl);
			printf("too many user has tried to connect\n");
			close(fd[USER_NUM+1]);
		}

		for (i=1; i<USER_NUM+1; i++) {
			if (fd[i] != (-1)) {
				if (FD_ISSET(fd[i], &fdsets)) {
					//printf("fd[%d] ready for read\n", i);
					for (k=0; k<4; k++) {
						read(fd[i], &request[k], sizeof(request[k]));
						request[k] = ntohl(request[k]);
					}

					response[0] = request[0];
					for (k=0; k<COMPANY_NUM; k++) {
						response[2*k+2] = k;
						response[2*k+3] = 0x00000000;
					}

					response[1] = status(players[i-1], companies, request[0], request[1], request[2], request[3], turn);
					//printf("response code for user %d is %x\n", i-1, response[1]);

					if (response[1] == ACCEPT) {
						if(request[1] == PURCHASE) {
							players[i-1].purchase[request[2]] += request[3];
							printf("purchasing company id: %d (price: %d) quantity: %d\n",request[2], companies[request[2]].price, request[3]);
						} else {
							players[i-1].sale[request[2]] += request[3];
							printf("selling company id: %d (price: %d) quantity: %d\n",request[2], companies[request[2]].price, request[3]);
						}
						response[request[2]*2+3] = request[3];
					} else if (response[1] == ERR_PUR) {
						response[request[2]*2+3] = request[3];
						printf("!ERROR in purchasing company id: %d (price: %d) quantity: %d\nYour current budget is %d\n\n",request[2], companies[request[2]].price, request[3], players[i-1].budget[turn]);
					} else if (response[1] == ERR_SAL) {
						response[request[2]*2+3] = request[3];
						printf("!ERROR in selling company id: %d (price: %d) quantity: %d\nYou only have %d tickets\n\n",request[2], companies[request[2]].price, request[3], players[i-1].tickets[request[2]]);
					}

					for (k=0; k<22; k++) {
						uint32_t tmp = htonl(response[k]);
						write(fd[i],&tmp, sizeof(tmp));
					}

					players[i-1].count++;
				}
			} else {
				printf("fd[%d] is -1\n", i);
			}
		}						
	}
	printf("connection finished!\n");
	return 0;
}
int main(int argc, char const* argv[]) {


	int sock, error;
	uint32_t get_data;
	uint32_t stock_data[ELEM];
	uint32_t default_data[ELEM];

	char host[16];
	char port[16];
	strcpy(host, argv[1]);
	strcpy(port, argv[2]);

	sock = makesock(port);
	printf("sock : %d\n", sock);

	int i;

	// game start
	while(true) {
		get_data = getData(&sock, stock_data);
		if(stock_data[1] == LIST) {
			printf("can connect to game.\n");
			break;
		}
	}

	bool list_flag = false;
	uint32_t math;
	uint32_t buy_id;
	uint32_t code = stock_data[1];
	uint32_t value;
	uint32_t key = stock_data[0];
	int turn = 0;
	uint32_t budget = 10000;

	// company and my_stock
	uint32_t my_stock[COMPANY];
	struct Company company[COMPANY];
	struct Company tmp_company[COMPANY];
	int j;
	for(j = 0; j < COMPANY; j++) {
		my_stock[j] = 0;
		default_data[j] = stock_data[j];
		company[j].id = j;
		company[j].price = stock_data[3+j*2];
		company[j].ave = stock_data[3+j*2];
		company[j].pattern = 0;
		company[j].prev_pattern = 0;
	}
	print_company_info(company);

	printf("\n");
	printf("game start.\n");
	printf("begin *** budget: %u, key: %u, code: %x\n", budget, key, stock_data[1]);

	int read_len;
	uint32_t tmp_data[ELEM];
	int s;
	bool is_minus = true;
	bool is_math = true;

	// doing game
	for(s = 0; s < TURNS; s++) {

		int a;
		read_len = -1;
		turn++;
		int n = 0;

		//list_flag = true;
		printf("\n ====== begin turn %d. before request. ======\n", s+1);
		for(i = 0; i < 5; i++) {
			
			if(key == 0 && code == END) {
				printf("my_lank is ....... %u\n", tmp_data[2]);
				exit(-1);
				break;
			}



			bool check_flag = false;

			if(turn == 1) {
				math = 10;
				buy_id = i;
				code = PURCHASE;
				check_flag = true;
			} else if(turn >= 59) {
					math = my_stock[i+n];
					buy_id = i+n;
					code = SALE;
					check_flag = true;
					n = 5;
			} else {
				int c;
				uint32_t m;
				for(c = n; c < COMPANY; c++) {
					
					m = 100;
					if(company[i].pattern < company[i].prev_pattern) {
						while(m <= 0) {
							if(is_minus_budget(budget, value, m) == true) {
								break;
							}
							m--;
						}
						if(m == 0) {
							continue;
						}
						math = m;
						buy_id = i;
						code = PURCHASE;
						check_flag = true;
						n = c;
						printf("buy check: company_id: %u, math: %u\n", buy_id, math);
						break;
					}
					if(company[i].pattern > company[i].prev_pattern) {
						math = my_stock[i];
						buy_id = i;
						code = SALE;
						check_flag = true;
						n = c;
						printf("sale check: company_id: %u, math: %u\n", buy_id, math);
						break;
					}
				}
			}

			if(check_flag == false) {
				continue;
			}

		
			request(&sock, &key, &math, &buy_id, &code);
			int l = getData(&sock, tmp_data);
			check_code(&tmp_data[1]);
			value = company[buy_id].price;
			if(tmp_data[1] != ACCEPT) {
				printf("\nnot accepted request.\n");
			} else {
				printf("\naccepted request.\n");
				status(&budget, my_stock, &turn, &buy_id, &code, &math, &value);
				//status(&budget, my_stock, &turn, &math, &buy_id, &code, &value);
			}
		}

		printf("\n ------- stayng ------\n");

		//while(list_flag == true) {
		while(1) {

			read_len = getData(&sock, tmp_data);
			check_code(&tmp_data[1]);
			code = tmp_data[1];
			if(code == ACCEPT || code == ERR_CODE || code == ERR_KEY || code == ERR_REQ || code == ERR_ID || code == ERR_PUR || code == ERR_SAL) {
				continue;
			}
			if(code != LIST) {
				continue;
			} else {
				dump_data(tmp_data);
				key = tmp_data[0];
				code = tmp_data[1];
				set_company_info(tmp_data, company, &turn);
				print_company_info(company);
				//list_flag = false;
				break;
			}
		}
		
		// read list
		printf("result -> budget: %u, turn: %d, key: %u, code: %x\n", budget, turn, tmp_data[0], tmp_data[1]);
		printf("turn %d end\n", s + 1);
	}
	
	return 0;
}
int main(int argc, char const* argv[]) {

	//struct addrinfo hints, *ai, *ai0;
	int sock, error;
	uint32_t get_data;
	uint32_t stock_data[ELEM];
	uint32_t default_data[ELEM];
	/*
	int buf_len;
	uint32_t buf;
	*/

	char host[16];
	char port[16];
	strcpy(host, argv[1]);
	strcpy(port, argv[2]);

	sock = makesock(port);
	printf("sock : %d\n", sock);

	int i;

	// game start
	while(true) {
		get_data = getData(&sock, stock_data);
		if(stock_data[1] == LIST) {
			printf("can connect to game.\n");
			break;
		}
	}

	//printf("\n");
	//printf("first dump.\n");
	//dump_data(stock_data);
/*
	printf("2222222222\n");
		get_data = getData(&sock, stock_data);
	printf("3333333333\n");
		get_data = getData(&sock, stock_data);
*/


	bool list_flag = false;
	uint32_t math;
	uint32_t buy_id;
	uint32_t code = stock_data[1];
	uint32_t value;
	uint32_t key = stock_data[0];
	int turn = 0;
	uint32_t budget = 10000;

	uint32_t my_stock[COMPANY];
	int j;
	for(j = 0; j < COMPANY; j++) {
		my_stock[j] = 0;
	}

	printf("\n");
	printf("game start.\n");

	int read_len = -1;
	int buy_flag = 0;

	int s;
	// doing game
	//while(1) {
	for(s = 0; s < TURNS; s++) {

		uint32_t tmp_data[ELEM];
		//printf("turn begin -> budget: %d, turn: %d, key: %u, code: %x\n", budget, s + 1, stock_data[0], stock_data[1]);

		int a;
		/*
		for(a = 0; a < 22; a++) {
			printf("%u, ", stock_data[a]);
		}
		*/
		//status(&budget, my_stock, &s, &math, &buy_id, &code);
		read_len = -1;
		//if(read_len = getData(sock, stock_data) > 0 && stock_data[1] == 0 && read_len >= 22) {


/*
		while(1) {
			if(read_len = getData(&sock, stock_data) > 0) {
				break;
			}
		}
*/
		/*
		math = 10;
		buy_id = 1;
		code = PURCHASE;
		request(&sock, stock_data, &math, &buy_id, &code);
*/
		//stock_data[1] = 0;
		//if(read_len = getData(&sock, tmp_data) > 0 && tmp_data[1] == LIST) {
		

		list_flag = true;
		printf("\n ====== begin turn. before request. ======\n");


		for(i = 0; i < 5; i++) {
			if(s % 2 == 0) {
				code = PURCHASE;
			} else {
				code = SALE;
			}

			math = 10;
			buy_id = i;
			key = tmp_data[0];
			//request(&sock, stock_data, &math, &buy_id, &code);
			request(&sock, &key, &math, &buy_id, &code);
			int l;
			l = getData(&sock, tmp_data);
			if(tmp_data[1] != ACCEPT) {
				printf("\nnot accepted request.\n");
			} else {
				printf("\naccepted request.\n");
				status(&budget, my_stock, &s, &math, &buy_id, &code);
			//	status(&budget, my_stock, &turn, &math, &buy_id, &code);
			}
		}



		while(list_flag == true) {
			
			if(read_len = getData(&sock, tmp_data) > 0 && tmp_data[1] == LIST) {
				//if(tmp_data[1] == LIST) {
				code = tmp_data[1];
				key = tmp_data[0];
				tmp_data[1] = 0x11111111;
				list_flag = false;
				//	tmp_data[1] = 0;
			}
			//if(stock_data[1] == LIST) {
			//}

			/*
			if(stock_data[1] == 0x001) {
				list_flag = true;
				turn++;
			} else if(stock_data[2] == 0x002) {
				printf("last budget is %d\n", budget);
				break;
			}*/
			//if(list_flag == true) {
						//list_flag = false;
			//}
		}
		
		
		
		// read list
		printf("result -> budget: %d, turn: %d, key: %u, code: %x\n", budget, s + 1, tmp_data[0], tmp_data[1]);

	}
	
	return 0;
}
Beispiel #5
0
int main(
    int argc,
    char **argv)
{
    scmcon *testconp = NULL;
    scmcon *realconp = NULL;
    scm *scmp = NULL;
    FILE *sfile = NULL;
    char *thedelfile = NULL;
    char *topdir = NULL;
    char *thefile = NULL;
    char *outfile = NULL;
    char *outfull = NULL;
    char *outdir = NULL;
    char *tmpdsn = NULL;
    char *ne;
    char *porto = NULL;
    char errmsg[1024];
    char *skifile = NULL;
    int ians = 0;
    int do_create = 0;
    int do_delete = 0;
    int do_sockopts = 0;
    int do_fileopts = 0;
    int use_filelist = 0;
    int perpetual = 0;
    int really = 0;
    int trusted = 0;
    int force = 0;
    int allowex = 0;
    int sta = 0;
    int s;
    int c;

    (void)setbuf(stdout, NULL);
    if (argc <= 1)
    {
        usage();
        return (1);
    }
    while ((c = getopt(argc, argv, "t:xyhad:f:F:lLwz:pm:c:s")) != EOF)
    {
        switch (c)
        {
        case 'a':
            allowex = 1;
            break;
        case 't':
            do_create++;
            topdir = optarg;
            break;
        case 'x':
            do_delete++;
            break;
        case 'y':
            force++;
            break;
        case 'D':
            trusted++;
        case 'd':
            thedelfile = optarg;
            break;
        case 'F':
            trusted++;
        case 'f':
            thefile = optarg;
            break;
        case 'L':
            trusted++;
        case 'l':
            use_filelist++;
            break;
        case 'w':
            do_sockopts++;
            break;
        case 'z':
            do_fileopts++;
            porto = optarg;
            break;
        case 'p':
            perpetual++;
            break;
        case 'c':
            skifile = optarg;
            break;
        case 'h':
            usage();
            return (0);
        case 's':
            strict_profile_checks = 1;  // global from myssl.c
            strict_profile_checks_cms = 1;      // global from roa_validate.c
            break;
        default:
            (void)fprintf(stderr, "Invalid option '%c'\n", c);
            usage();
            return (1);
        }
    }
    // if there is anything left in argv, or no operation specified, warn user
    if (optind < argc)
    {
        (void)printf("Extra arguments at the end of the command line.\n");
        usage();
        return (1);
    }
    if ((do_create + do_delete + do_sockopts + do_fileopts) == 0 &&
            thefile == 0 && thedelfile == 0 && skifile == 0 && use_filelist == 0)
    {
        (void)printf("You need to specify at least one operation "
                     "(e.g. -f file).\n");
        usage();
        return (1);
    }
    OPEN_LOG("rcli", LOG_USER);
    if (!my_config_load())
    {
        LOG(LOG_ERR, "can't load configuration");
        exit(EXIT_FAILURE);
    }
    if (force == 0)
    {
        if (do_delete > 0)
        {
            ians = yorn("Do you REALLY want to delete all database tables");
            if (ians <= 0)
            {
                LOG(LOG_NOTICE, "Delete operation cancelled");
                return (1);
            }
            really++;
        }
        if ((do_create > 0) && (really == 0))
        {
            ians = yorn("Do you REALLY want to create all database tables");
            if (ians <= 0)
            {
                LOG(LOG_NOTICE, "Create operation cancelled");
                return (1);
            }
            really++;
        }
    }
    scmp = initscm();
    if (scmp == NULL)
    {
        LOG(LOG_ERR, "Internal error: cannot initialize database schema");
        return (-2);
    }
    /*
     * If a create or delete operation is being performed, then a test dsn
     * will be needed; create it now and defer the creation of the real dsn
     * until later. Otherwise, create the real dsn.
     *
     * A test dsn is needed for operations that operate on the overall
     * database state as opposed to the rpki tables, namely the create and
     * delete operations.
     */
    if ((do_create + do_delete) > 0)
    {
        /*
         * Note that in the following line, we do not intend to edit
         * the database named "information_schema".  We are simply
         * filling in the "database name" parameter with something
         * that is guaranteed to be valid for MySQL.
         */
        tmpdsn = makedsnscm(scmp->dsnpref, "information_schema",
                            CONFIG_DATABASE_USER_get(),
                            CONFIG_DATABASE_PASSWORD_get());
        if (tmpdsn == NULL)
        {
            membail();
            return (-1);
        }
        testconp = connectscm(tmpdsn, errmsg, 1024);
        memset(tmpdsn, 0, strlen(tmpdsn));
        free((void *)tmpdsn);
        if (testconp == NULL)
        {
            LOG(LOG_ERR, "Cannot connect to DSN: %s", errmsg);
            freescm(scmp);
            return (-1);
        }
    }
    else
    {
        realconp = connectscm(scmp->dsn, errmsg, 1024);
        if (realconp == NULL)
        {
            LOG(LOG_ERR, "Cannot connect to DSN %s: %s", scmp->dsn,
                errmsg);
            freescm(scmp);
            return (-1);
        }
    }
    /*
     * Process command line options in the following order: delete, create,
     * dofile, dodir, listener.
     */
    if (do_delete > 0)
        sta = deleteop(testconp, scmp);
    if ((do_create > 0) && (sta == 0))  /* first phase of create */
        sta = createop(testconp, scmp);
    /*
     * Don't need the test connection any more
     */
    if (testconp != NULL)
    {
        disconnectscm(testconp);
        testconp = NULL;
    }
    /*
     * If there has been an error or if we're done because the database was
     * just deleted and not re-created, bail out.
     */
    if (sta < 0 || (do_delete > 0 && do_create == 0))
    {
        if (realconp != NULL)
            disconnectscm(realconp);
        freescm(scmp);
        if (tdir != NULL)
            free((void *)tdir);
        return (sta);
    }
    /*
     * If a connection to the real DSN has not been opened yet, open it now.
     */
    if (realconp == NULL)
    {
        realconp = connectscm(scmp->dsn, errmsg, 1024);
        if (realconp == NULL)
        {
            LOG(LOG_ERR, "Cannot connect to DSN %s: %s",
                scmp->dsn, errmsg);
            freescm(scmp);
            if (tdir != NULL)
                free((void *)tdir);
            return (-1);
        }
    }
    /*
     * If a create operation was requested, complete it now.
     */
    if ((do_create > 0) && (sta == 0))
        sta = create2op(scmp, realconp, topdir);
    /*
     * If the top level repository directory is not set, then retrieve it from
     * the database.
     */
    if ((tdir == NULL) && (sta == 0))
    {
        tdir = retrieve_tdir(scmp, realconp, &sta);
        if (tdir == NULL)
            LOG(LOG_ERR,
                "Cannot retrieve top level repository info from DB");
    }
    if (sta == 0)
    {
        LOG(LOG_INFO, "Top level repository directory is %s", tdir);
        tdirlen = strlen(tdir);
    }
    /*
     * Setup for actual SSL operations
     */
    OpenSSL_add_all_algorithms();
    ERR_load_crypto_strings();
    LOG(LOG_NOTICE, "Rsync client session started");
    if (thefile != NULL && sta == 0)
    {
        // Check that the file is in the repository, ask if not and force is
        // off
        sta = splitdf(NULL, NULL, thefile, &outdir, &outfile, &outfull);
        if (sta == 0)
        {
            if (strncmp(tdir, outdir, tdirlen) != 0 && force == 0)
            {
                ians =
                    yorn("That file is not in the repository. Proceed anyway");
                if (ians <= 0)
                    sta = 1;
            }
            // if ( strstr(outdir, "TRUST") != NULL )
            // trusted++;
            // if the user has declared it to be trusted
            // ask for verification unless force is set
            if (trusted > 0 && force == 0 && sta == 0)
            {
                ians = yorn("Really declare this file as trusted");
                if (ians <= 0)
                    sta = 1;
            }
            if (sta == 1)
                LOG(LOG_NOTICE, "File operation cancelled");
            if (sta == 0)
            {
                LOG(LOG_INFO, "Attempting add: %s", outfile);
                setallowexpired(allowex);
                sta = add_object(scmp, realconp, outfile, outdir, outfull,
                                 trusted);
                if (sta < 0)
                {
                    LOG(LOG_ERR,
                        "Add failed: %s: error %s (%d)",
                        thefile, err2string(sta), sta);
                    if (sta == ERR_SCM_SQL)
                    {
                        ne = geterrorscm(realconp);
                        if (ne != NULL && ne != 0)
                            LOG(LOG_ERR, "\t%s", ne);
                    }
                }
                else
                    LOG(LOG_INFO, "Add succeeded: %s", outfile);
            }
            free((void *)outdir);
            free((void *)outfile);
            free((void *)outfull);
        }
        else
            LOG(LOG_ERR, "%s (%d)", err2string(sta), sta);
    }
    if (use_filelist > 0 && sta == 0)
    {
        char *line = NULL;
        size_t len = 0;
        ssize_t read;
        int status;

        setallowexpired(allowex);
        while ((read = getline(&line, &len, stdin)) != -1)
        {
            if (read == 0)
                continue;

            // Trim newline and skip line if empty
            if (line[read - 1] == '\n')
                line[read - 1] = '\0';
            if (strlen(line) == 0)
                continue;

            // Split directory and file components of path
            status = splitdf(NULL, NULL, line, &outdir, &outfile, &outfull);
            if (status != 0)
            {
                LOG(LOG_ERR, "%s (%d)", err2string(status), status);
                continue;
            }

            LOG(LOG_INFO, "Attempting add: %s", outfile);

            // Warn if file not within repository directory
            if (strncmp(tdir, outdir, tdirlen) != 0)
                LOG(LOG_WARNING, "%s is not in the repository", line);

            // Add
            status = add_object(scmp, realconp, outfile, outdir, outfull,
                                trusted);
            if (status == 0)
            {
                LOG(LOG_INFO, "Add succeeded: %s", outfile);
            }
            else
            {
                LOG(LOG_ERR, "Add failed: %s: error %s (%d)",
                    line, err2string(status), status);
                if (status == ERR_SCM_SQL)
                {
                    ne = geterrorscm(realconp);
                    if (ne != NULL && ne != 0)
                        LOG(LOG_ERR, "\t%s", ne);
                }
            }
            free((void *)outdir);
            free((void *)outfile);
            free((void *)outfull);
        }

        free(line);
    }
    if (thedelfile != NULL && sta == 0)
    {
        sta = splitdf(NULL, NULL, thedelfile, &outdir, &outfile, &outfull);
        if (sta == 0)
        {
            sta = delete_object(scmp, realconp, outfile, outdir, outfull, 0);
            if (sta < 0)
            {
                LOG(LOG_ERR,
                    "Could not delete file %s: error %s (%d)",
                    thedelfile, err2string(sta), sta);
                if (sta == ERR_SCM_SQL)
                {
                    ne = geterrorscm(realconp);
                    if (ne != NULL && ne != 0)
                        LOG(LOG_ERR, "\t%s", ne);
                }
            }
            else
                LOG(LOG_INFO, "Delete operation succeeded (%s removed)",
                    thedelfile);
            free((void *)outdir);
            free((void *)outfile);
            free((void *)outfull);
        }
        else
            LOG(LOG_ERR, "Error: %s (%d)", err2string(sta), sta);
    }
    if ((do_sockopts + do_fileopts) > 0 && sta == 0)
    {
        int protos = (-1);
        const int max_makesock_attempts = 10;
        int makesock_failures = 0;
        do
        {
            if (do_sockopts > 0)
            {
                uint16_t port = CONFIG_RPKI_PORT_get();
                s = makesock(port, &protos);
                if (s < 0)
                {
                    makesock_failures++;
                    LOG(LOG_ERR,
                        "Failed to listen on port %" PRIu16 " (failure #%d)", port,
                        makesock_failures);
                    sleep(1);
                    if (makesock_failures >= max_makesock_attempts)
                    {
                        LOG(LOG_ERR,
                            "%d failed attempts to create socket. Aborting.",
                            max_makesock_attempts);
                        sta = -1;
                        break;
                    }
                }
                else
                {
                    makesock_failures = 0;
                    FLUSH_LOG();
                    sta = sockline(scmp, realconp, s);
                    LOG(LOG_INFO, "Socket connection closed");
                    FLUSH_LOG();
                    (void)close(s);
                }
            }
            if (do_fileopts > 0 && porto != NULL)
            {
                if (!isatty(0))
                {
                    LOG(LOG_DEBUG, "Opening stdin");
                    sfile = stdin;
                    sta = fileline(scmp, realconp, sfile);
                }
                else
                {
                    LOG(LOG_DEBUG, "Opening a socket cmdfile %s", porto);
                    sfile = fopen(porto, "r");
                    if (sfile == NULL)
                        LOG(LOG_ERR, "Could not open cmdfile");
                    else
                    {
                        sta = fileline(scmp, realconp, sfile);
                        LOG(LOG_DEBUG, "Cmdfile closed");
                        (void)fclose(sfile);
                    }
                }
            }
            if (sta == 0 && skifile)
            {
                LOG(LOG_DEBUG, "Starting skifile %s", skifile);
                sta = read_SKI_blocks(scmp, realconp, skifile);
                if (sta > 0)
                    sta = 0;
                if (sta)
                    LOG(LOG_ERR, "Error with skifile: %s (%d)",
                        err2string(sta), sta);
            }
        } while (perpetual > 0);
        if (protos >= 0)
            (void)close(protos);
    }
    if (sta == 0 && skifile)
    {
        LOG(LOG_DEBUG, "Starting skifile %s", skifile);
        sta = read_SKI_blocks(scmp, realconp, skifile);
        if (sta > 0)
            sta = 0;
        if (sta)
            LOG(LOG_ERR, "Error with skifile: %s (%d)", err2string(sta),
                sta);
    }
    (void)ranlast(scmp, realconp, "RSYNC");
    sqcleanup();
    if (realconp != NULL)
        disconnectscm(realconp);
    freescm(scmp);
    if (tdir != NULL)
        free((void *)tdir);
    LOG(LOG_NOTICE, "Rsync client session ended");
    config_unload();
    CLOSE_LOG();
    return (sta);
}
Beispiel #6
0
void
rpc_init(char *name, int prog, int vers, void (*dispatch)(), int defport)
{
	struct sockaddr_in saddr;
	SVCXPRT	*transp;
	int	sock;
	socklen_t asize;

	asize = sizeof(saddr);
	sock = 0;
	if (getsockname(0, (struct sockaddr *) &saddr, &asize) == 0
	    && saddr.sin_family == AF_INET) {
		socklen_t ssize = sizeof (int);
		int fdtype = 0;
		if (getsockopt(0, SOL_SOCKET, SO_TYPE,
				(char *)&fdtype, &ssize) == -1)
			xlog(L_FATAL, "getsockopt failed: %s", strerror(errno));
		/* inetd passes a UDP socket or a listening TCP socket.
		 * listen will fail on a connected TCP socket(passed by rsh).
		 */
		if (!(fdtype == SOCK_STREAM && listen(0,5) == -1)) {
			_rpcfdtype = fdtype;
			_rpcpmstart = 1;
		}
	}
	if (!_rpcpmstart) {
		pmap_unset(prog, vers);
		sock = RPC_ANYSOCK;
	}

	if ((_rpcfdtype == 0) || (_rpcfdtype == SOCK_DGRAM)) {
		static SVCXPRT *last_transp = NULL;
 
		if (_rpcpmstart == 0) {
			if (last_transp
			    && (!defport || defport == last_transp->xp_port)) {
				transp = last_transp;
				goto udp_transport;
			}
			if (defport == 0)
				sock = RPC_ANYSOCK;
			else if ((sock = makesock(defport, IPPROTO_UDP)) < 0) {
				xlog(L_FATAL, "%s: cannot make a UDP socket\n",
						name);
			}
		}
		if (sock == RPC_ANYSOCK)
			sock = svcudp_socket (prog, 1);
		transp = svcudp_create(sock);
		if (transp == NULL) {
			xlog(L_FATAL, "cannot create udp service.");
		}
      udp_transport:
		if (!svc_register(transp, prog, vers, dispatch, IPPROTO_UDP)) {
			xlog(L_FATAL, "unable to register (%s, %d, udp).",
					name, vers);
		}
		last_transp = transp;
	}

	if ((_rpcfdtype == 0) || (_rpcfdtype == SOCK_STREAM)) {
		static SVCXPRT *last_transp = NULL;

		if (_rpcpmstart == 0) {
			if (last_transp
			    && (!defport || defport == last_transp->xp_port)) {
				transp = last_transp;
				goto tcp_transport;
			}
			if (defport == 0)
				sock = RPC_ANYSOCK;
			else if ((sock = makesock(defport, IPPROTO_TCP)) < 0) {
				xlog(L_FATAL, "%s: cannot make a TCP socket\n",
						name);
			}
		}
		if (sock == RPC_ANYSOCK)
			sock = svctcp_socket (prog, 1);
		transp = svctcp_create(sock, 0, 0);
		if (transp == NULL) {
			xlog(L_FATAL, "cannot create tcp service.");
		}
      tcp_transport:
		if (!svc_register(transp, prog, vers, dispatch, IPPROTO_TCP)) {
			xlog(L_FATAL, "unable to register (%s, %d, tcp).",
					name, vers);
		}
		last_transp = transp;
	}

	if (_rpcpmstart) {
		signal (SIGALRM, closedown);
		alarm (_RPCSVC_CLOSEDOWN);
	}
}