예제 #1
0
int main(int argc, char* argv[]) {

	int n, nr, nw;
	char* key, *value, *operation;

	/*Check arguments*/
	char* usage = "Usage ./client <N> <NR> <NW> PUT/GET <key> {<value>}";
	if (argc < 6) {
		fprintf(stderr, "%s", usage);
		exit(0);
	} else {
		if (!strcmp(argv[4], "PUT") && argc > 7) {
			fprintf(stderr, "%s", usage);
			exit(0);
		} else if (!strcmp(argv[4], "GET") && argc > 6) {
			fprintf(stderr, "%s", usage);
			exit(0);
		}
	}

	/*store arguments*/
	n = atoi(argv[1]);
	nr = atoi(argv[2]);
	nw = atoi(argv[3]);
	operation = argv[4];
	key = argv[5];
	if (argc == 7) {
		value = argv[6];
	}

	fprintf(stderr, "\n");
	/*calculate NL_MAX*/
	if (!strcmp(operation, "GET")) {
		if (nr + nw > n) {
			int nl_max_1 = (nr + nw - n) / 2;
			int nl_max_2 = nr / 2;
			NL_MAX = MIN(nl_max_1, nl_max_2);
			fprintf(stderr, "Atmost %d liers can be identified\n", NL_MAX);
		} else {
			fprintf(stderr, "Reading quorum condition is not met\n");
			return 0;
		}
	} else if (!strcmp(operation, "PUT")) {
		if (nr + nw > n && nw > n / 2) {
			int nl_max_1 = (nr + nw - n) / 2;
			int nl_max_2 = (2 * nw - n) / 2;
			NL_MAX = MIN(nl_max_1, nl_max_2);
			fprintf(stderr, "Atmost %d liers can be identified\n", NL_MAX);
		} else {
			fprintf(stderr, "Writing quorum condition is not met\n");
			return 0;
		}
	}
	fprintf(stderr, "\n");

	/*if (!strcmp(operation, "GET")) {
	 if (!((nr + nw > n + 2 * NL_MAX) && nr > 2 * NL_MAX)) {
	 fprintf(stderr, "GET NR NW conditions are not met\n");
	 return 0;
	 }
	 } else if (!strcmp(operation, "PUT")) {
	 if (!((nr + nw > n + 2 * NL_MAX) && nw > (2 * NL_MAX + n) / 2)) {
	 fprintf(stderr, "PUT NR NW conditions are not met\n");
	 return 0;
	 }
	 }*/

	/*Read server connection details from file*/
	FILE* fp_servers = fopen("server_loc.txt", "r");
	if (!fp_servers) {
		perror("Failed to open server_loc.txt file");
		return 0;
	}
	server_info_t* slist = NULL;

	int count = 0;
	char buff[MAX_PATH];

	while (fgets(buff, MAX_PATH, fp_servers) != NULL) {
		char hostname[MAX_PATH], port[MAX_PATH];
		parse(buff, hostname, port);
		char ip[MAX_PATH];

		if (getipaddress(hostname, ip)) {
			fprintf(stderr, "Failed to convert hostname to ipaddress");
			return -1;
		}

		/*check if the server is up or not and if not store it in */
		int connfd;
		struct sockaddr_in servaddr;
		servaddr.sin_family = AF_INET;
		if (!inet_pton(AF_INET, ip, &(servaddr.sin_addr.s_addr))) {
			perror("Failed to convert address");
			exit(0);
		}
		servaddr.sin_port = htons(atoi(port));
		connfd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
		if (connect(connfd, (struct sockaddr*) &servaddr, sizeof(servaddr))) {
			fprintf(stderr, "Invalid entry in file \"%s\" : ", buff);
			perror("");
			continue;
		}
		FILE* fp = fdopen(connfd, "r+");
		if (fgetc(fp) == 'v') {
			/*allocate memory to socket address list*/
			count++;
			slist = realloc(slist, sizeof(server_info_t) * count);
			if (!slist) {
				perror("failed to read server addresses from file");
				return 0;
			}
			//store id
			slist[count - 1].id = count - 1;
			//slist[count - 1].has_voted = 1;
			slist[count - 1].hostname = strdup(hostname);
			slist[count - 1].port = atoi(port);
			slist[count - 1].fp = fp;
		} else {
			fclose(fp);
		}
	}

	int i = 0;
	if (!strcmp(operation, "PUT")) {
		// send put command to each of the server
		for (i = 0; i < count; i++) {
			fprintf(slist[i].fp, "%s %s %s\n", operation, key, value);
			fflush(NULL);
		}

		//check if votes are received
		i = 0;
		int vote_count = 0;
		for (i = 0; i < count; i++) {
			//Read a character from server if it is v then its a vote other
			if (fgetc(slist[i].fp) == 'v') {
				//that means server has voted
				slist[i].has_voted = 1;
				fprintf(stderr, "vote received from %s %d\n", slist[i].hostname,
						slist[i].port);
				vote_count++;
			}
		}
		fprintf(stderr, "\n");

		//check PUT condition
		if (vote_count < nw) {
			fprintf(stderr,
					"PUT condition not met: number of votes received: %d and NW:%d",
					vote_count, nw);
			return 0;
		}
		fprintf(stderr, "\n");

		//get version number for hosts that have voted
		for (i = 0; i < count; i++) {
			//Read a character from server if it is v then its a vote other
			if (slist[i].has_voted == 1) {
				// ask for version number
				fprintf(slist[i].fp, "a\n");
				fflush(NULL);
				//read version number
				fscanf(slist[i].fp, "%d", &(slist[i].version));
				assert(fgetc(slist[i].fp) == '\n');
				fprintf(stderr, "version no: %d at %s %d\n", slist[i].version,
						slist[i].hostname, slist[i].port);
				fflush(NULL);
			}
		}
		fprintf(stderr, "\n");
		//calculate the correct version no and also liers

		struct version_list* vlist = NULL;
		int vcount = 0;
		/*Sort slist based on version number in descending order*/
		//void qsort ( void * base, size_t num, size_t size, int ( * comparator ) ( const void *, const void * ) );
		qsort(slist, count, sizeof(server_info_t), version_comparator);

		//work on top 2NLmax+1 elements
		for (i = 0; i < (2 * NL_MAX + 1); i++) {
			//check if each element is present in version list
			int j;
			for (j = 0; j < vcount; j++) {
				if (vlist[j].version == slist[i].version) {
					//increment the count and add that element to the list
					vlist[j].count++;
					//add that element to end of the list
					server_info_t* curr = vlist[j].head;
					//insert it at the head
					if (curr == NULL) {
						vlist[j].head = &slist[i];
						slist[i].next = NULL;
					} else {
						//insert it at the tail
						while (curr->next != NULL) {
							curr = curr->next;
						}
						curr->next = &slist[i];
						slist[i].next = NULL;
					}
					break;
				}
			}
			//check if that version element is present
			if (j == vcount) {
				vcount++;
				//allocate memory for a vnode and add the current entry to it
				vlist = realloc(vlist, sizeof(struct version_list) * vcount);
				vlist[vcount - 1].version = slist[i].version;
				vlist[vcount - 1].count = 1;
				vlist[vcount - 1].head = &slist[i];
				slist[i].next = NULL;
			}
		}
		//sort vlist
		qsort(vlist, vcount, sizeof(struct version_list), count_comparator);
		int correct_vno;
		correct_vno = vlist[0].version;

		//identify liers
		for (i = 1; i < vcount; i++) {
			server_info_t* head = vlist[i].head;
			while (head != NULL) {
				fprintf(stderr, "%s %d lied with version no:%d\n",
						head->hostname, head->port, head->version);
				fflush(NULL);
				head = head->next;
			}
		}

		fprintf(stderr, "\n");

		//update each voted server with key:value:correct_vno
		for (i = 0; i < count; i++) {
			if (slist[i].has_voted) {
				fprintf(slist[i].fp, "%s:%s:%d\n", key, value, correct_vno + 1);
				fprintf(stderr,
						"Updating: Key %s with Version %d Value %s at %s %d\n",
						key, correct_vno + 1, value, slist[i].hostname,
						slist[i].port);
				fflush(NULL);
			}
		}
		fprintf(stderr, "\n");
		//send commit operation to all voted servers
		for (i = 0; i < count; i++) {
			if (slist[i].has_voted) {
				fprintf(slist[i].fp, "a\n");
			}
		}

	} else if (!strcmp(operation, "GET")) {
		// send GET command to each of the server
		for (i = 0; i < count; i++) {
			fprintf(slist[i].fp, "%s %s\n", operation, key);
			fflush(NULL);
		}

		//check if votes are received
		i = 0;
		int vote_count = 0;
		for (i = 0; i < count; i++) {
			//Read a character from server if it is v then its a vote other
			int ch = fgetc(slist[i].fp);
			fflush(NULL);
			if (ch == 'v') {
				//that means server has voted
				slist[i].has_voted = 1;
				fprintf(stderr, "vote received from %s %d\n", slist[i].hostname,
						slist[i].port);
				vote_count++;
			}
		}
		//check GET condition
		if (vote_count < nr) {
			fprintf(stderr, "\n");
			fprintf(stderr,
					"GET condition not met: number of votes received: %d and NR:%d",
					vote_count, nr);
			return 0;
		}

		fprintf(stderr, "\n");

		char buff[MAX_PATH];
		//get version number for hosts that have voted
		for (i = 0; i < count; i++) {
			//Read a character from server if it is v then its a vote other
			if (slist[i].has_voted == 1) {
				// ask for version number
				fprintf(slist[i].fp, "a\n");
				fflush(NULL);
				//read version number
				fscanf(slist[i].fp, "%d", &(slist[i].version));
				assert(fgetc(slist[i].fp) == '\n');
				if ((slist[i].version)) {
					fscanf(slist[i].fp, "%s", buff);
					slist[i].key = strdup(buff);
					fscanf(slist[i].fp, "%s", buff);
					slist[i].value = strdup(buff);
				} else {
					fscanf(slist[i].fp, "%s", buff);
					slist[i].key = strdup("");
					fscanf(slist[i].fp, "%s", buff);
					slist[i].value = strdup("");
				}
				fprintf(stderr, "version no: %d at %s %d\n", slist[i].version,
						slist[i].hostname, slist[i].port);
				fflush(NULL);
			}
		}

		fprintf(stderr, "\n");

		//calculate correct value and identify liers
		struct version_list* vlist = NULL;
		int vcount = 0;
		/*Sort slist based on version number in descending order*/
		//void qsort ( void * base, size_t num, size_t size, int ( * comparator ) ( const void *, const void * ) );
		qsort(slist, count, sizeof(server_info_t), version_comparator);

		//work on top 2NLmax+1 elements
		for (i = 0; i < n && (slist[0].version == slist[i].version); i++) {
			//check if each element is present in version list
			int j;
			for (j = 0; j < vcount; j++) {
				if (strcmp(vlist[j].value, slist[i].value) == 0) {
					//increment the count and add that element to the list
					vlist[j].count++;
					//add that element to end of the list
					server_info_t* curr = vlist[j].head;
					//insert it at the head
					if (curr == NULL) {
						vlist[j].head = &slist[i];
						slist[i].next = NULL;
					} else {
						//insert it at the tail
						while (curr->next != NULL) {
							curr = curr->next;
						}
						curr->next = &slist[i];
						slist[i].next = NULL;
					}
					break;
				}
			}
			//check if that version element is present
			if (j == vcount) {
				vcount++;
				//allocate memory for a vnode and add the current entry to it
				vlist = realloc(vlist, sizeof(struct version_list) * vcount);
				vlist[vcount - 1].version = slist[i].version;
				if (slist[i].version) {
					vlist[vcount - 1].value = strdup(slist[i].value);
				} else {
					vlist[vcount - 1].value = "";
				}
				vlist[vcount - 1].count = 1;
				vlist[vcount - 1].head = &slist[i];
				slist[i].next = NULL;
			}
		}
		//sort vlist
		qsort(vlist, vcount, sizeof(struct version_list), count_comparator);
		int correct_vno;
		correct_vno = vlist[0].version;

		//identify liers
		int nr_liers = 0;
		for (i = 1; i < vcount && nr_liers < NL_MAX; i++) {
			server_info_t* head = vlist[i].head;
			while (head != NULL && nr_liers < NL_MAX) {
				fprintf(stderr, "%s %d lied with version no:%d\n",
						head->hostname, head->port, head->version);
				fflush(NULL);
				head = head->next;
				nr_liers++;
			}
		}
		fprintf(stderr, "\n");

		//print correct version numbers
		server_info_t* head = vlist[0].head;
		while (head != NULL) {
			fprintf(stderr, "highest version at %s %d with version no:%d\n",
					head->hostname, head->port, head->version);
			fflush(NULL);
			head = head->next;
		}
		fprintf(stderr, "\n");

		if (correct_vno) {
			fprintf(stderr, "Reading key/value :%s/%s\n", key, vlist[0].value);
		} else {
			fprintf(stderr, "No key value pair exists for key %s\n", key);
		}

		fprintf(stderr, "\n");

	} else {
		fprintf(stderr, "invalid command");
	}

	return 0;
}
예제 #2
0
int main (int argc, char** argv) 
{
	char* hostname;
	char* display;
	char* name;
	short port;
	int sock;
	int reply;
	int rval;
	int protoversion;
	char fullauth = 0;
	Byte opcode = OP_CLOSE;

        if (argc < 2) {
	       puts("Usage: floppyd_installtest [-f] Connect-String\n"
		    "-f\tDo full X-Cookie-Authentication");
	       return -1;
	}

	name = argv[1];
	if (strcmp(name, "-f") == 0) {
		fullauth = 1;
		name = argv[2];
	}

	rval = get_host_and_port(name, &hostname, &display, &port);
	
	if (!rval) return -1;

	sock = connect_to_server(getipaddress(hostname), port);

	if (sock == -1) {
		fprintf(stderr,
			"Can't connect to floppyd server on %s, port %i!\n",
			hostname, port);
		return -1;
	}
	
	protoversion = FLOPPYD_PROTOCOL_VERSION;
	while(1) {
	    reply = authenticate_to_floppyd(fullauth, sock, display,
					    protoversion);
	    if(protoversion == FLOPPYD_PROTOCOL_VERSION_OLD)
		break;
	    if(reply == AUTH_WRONGVERSION) {
		/* fall back on old version */
		protoversion = FLOPPYD_PROTOCOL_VERSION_OLD;
		continue;
	    }
	    break;
	}

	if (reply != 0) {
		fprintf(stderr, 
			"Connection to floppyd failed:\n"
			"%s\n", AuthErrors[reply]);
		return -1;
	}
	
	free(hostname);
	free(display);

	write_dword(sock, 1);
	write(sock, &opcode, 1);

	close(sock);

	return 0;
}
예제 #3
0
파일: vfapi-plugin.c 프로젝트: jinjoh/NOOR
HRESULT __stdcall VF_OpenFileFunc_Blen( 
	char *lpFileName, LPVF_FileHandle lpFileHandle )
{
	conndesc * rval;
	char * host;
	char * p;
	int port;
	SOCKET s_in;
	char buf[256];
	struct sockaddr_in      addr;
	FILE* fp;

	p = lpFileName;
	while (*p && *p != '.') p++;
	if (*p) p++;
	if (strcmp(p, "blu") != 0) {
		return VF_ERROR;
	}

	fp = fopen(lpFileName, "r");
	if (!fp) {
		return VF_ERROR;
	}
	fgets(buf, 256, fp);
	fclose(fp);

	host = buf;
	p = host;
	while (*p && *p != ':') p++;
	if (*p) p++;
	p[-1] = 0;
	port = atoi(p);
	if (!port) {
		port = 8080;
	}

	addr.sin_family = AF_INET;
	addr.sin_port = htons(port);
	addr.sin_addr.s_addr = getipaddress(host);

	s_in = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
	if (s_in < 0) {
		return VF_ERROR;
	}

	if (connect(s_in, (struct sockaddr*) &addr,
		    sizeof(addr)) < 0) {
		closesocket(s_in);
		return VF_ERROR;
	}

	rval = (conndesc*) malloc(sizeof(conndesc));

	rval->addr = addr;

	my_send(s_in, "GET /info.txt HTTP/1.0\n\n");

	for (;;) {
		char * key;
		char * val;

		if (my_gets(s_in, buf, 250) <= 0) {
			break;
		}

		key = buf;
		val = buf;
		while (*val && *val != ' ') val++;
		if (*val) {
			*val = 0;
			val++;
			
			if (strcmp(key, "width") == 0) {
				rval->width = atoi(val);
			} else if (strcmp(key, "height") == 0) {
				rval->height = atoi(val);
			} else if (strcmp(key, "start") == 0) {
				rval->start = atoi(val);
			} else if (strcmp(key, "end") == 0) {
				rval->end = atoi(val);
			} else if (strcmp(key, "rate") == 0) {
				rval->rate = atoi(val);
			} else if (strcmp(key, "ratescale") == 0) {
				rval->ratescale = atoi(val);
			}
		}
	}

	closesocket(s_in);

	*lpFileHandle = (VF_FileHandle) rval;

	return VF_OK;
}