1 /*
2 
3     Copyright (C) 2009,2015,2016 Alois Schloegl <alois.schloegl@gmail.com>
4     This file is part of the "BioSig for C/C++" repository
5     (biosig4c++) at http://biosig.sf.net/
6 
7     BioSig is free software; you can redistribute it and/or
8     modify it under the terms of the GNU General Public License
9     as published by the Free Software Foundation; either version 3
10     of the License, or (at your option) any later version.
11 
12     This program is distributed in the hope that it will be useful,
13     but WITHOUT ANY WARRANTY; without even the implied warranty of
14     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15     GNU General Public License for more details.
16 
17     You should have received a copy of the GNU General Public License
18     along with this program.  If not, see <http://www.gnu.org/licenses/>.
19 
20 */
21 
22 
23 #include "biosig-network.h"
24 
25 #include <ctype.h>
26 #include <errno.h>
27 #ifndef _WIN32
28 # include <pwd.h>
29 #endif
30 #include <sys/stat.h>
31 #include <stdarg.h>
32 #include <stdio.h>
33 #include <stdlib.h>
34 
35 
36 
main(int argc,char * argv[])37 int main (int argc, char *argv[]) {
38 
39 	int s=0;
40     	register int sd;
41 	struct stat info;
42 	int state;
43 
44 	sd = bscs_connect(argv[1]);
45 
46    	if(sd<0) {
47       		perror("cannot connect ");
48       		exit(1);
49    	}
50 
51 	fprintf(stdout,"client 122 %i %s <%s>\n",errno,strerror(errno),getenv("HOME"));
52 
53 	char path2keys[1024];
54 	char *str;
55 #ifdef _WIN32
56 	str = strncpy(path2keys,getenv("HOME"),1023);
57 #elif 0
58 	// TODO: getpwuid can cause a memory leak in glibc2.15 and earlier
59 	struct passwd *p = getpwuid(geteuid());
60 	str = strncpy(path2keys,p->pw_dir,1023);
61 	//path2keys = strdup(p->pw_dir);
62 	if (VERBOSE_LEVEL>7)  fprintf(stdout,"Name:%s\nPw:%s\nuid/gui: %i/%i\nreal name: %s\n$HOME:%s\nSHELL:%s\n",p->pw_name,p->pw_passwd,p->pw_uid,p->pw_gid,p->pw_gecos,p->pw_dir,p->pw_shell);
63 #endif
64 	str += strlen(path2keys);
65 	str[0] = FILESEP;
66 	str = (char*)memcpy(str+1,".biosig",7)+7;
67 	str[0] = FILESEP;
68 	str[1] = 0;
69 	size_t path2keysLength = strlen(path2keys);
70 	stat(path2keys, &info);
71 	if (!(S_ISDIR(info.st_mode)))
72 		mkdir(path2keys,S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH); // read/write/search permissions for owner and group, and with read/search permissions for others.
73 
74 	SERVER_STATE = STATE_INIT;
75 
76 	HDRTYPE *hdr=constructHDR(0,0);
77 	uint64_t ID = 0;
78 
79 //	bscs_send_msg(sd,"Hello Server");
80 	fprintf(stdout,"client 125 %i %s\n",errno,strerror(errno));
81 
82 	char clbuf[1000];
83 	char *cmd;
84 	while (1) {
85 		fprintf(stdout,"prompt$:");
86 	     	cmd = fgets(clbuf,1000,stdin);
87 
88 		if (!strncasecmp(clbuf,"exit",4) || !strncasecmp(clbuf,"bye",3)) {
89 			fprintf(stdout,"\n%p>\n",cmd);
90 			bscs_close(sd);
91 			close(sd);
92 			break;
93 		}
94 //		fprintf(stdout,"cmd=<%s> %i\n",cmd,strncasecmp(cmd,"close",5));
95 
96 		if (cmd[0]=='!')
97 			system(cmd+1);
98 		else if (!strncasecmp(cmd,"ow+c",4)) {
99 			ID = 0;
100 			s=bscs_open(sd, &ID);
101 			fprintf(stdout,"ow ID=%016"PRIx64" s=%i %08x\n",ID,s,s);
102 			s=bscs_close(sd);
103 			fprintf(stdout,"c ID=%016"PRIx64" s=%i %08x\n",ID,s,s);
104 		}
105 		else if (!strncasecmp(cmd,"or+c",4)) {
106 			ID = htole64(0x233ab6dfc96f664fLL);
107 			s=bscs_open(sd, &ID);
108 			fprintf(stdout,"or ID=%016"PRIx64" s=%i %08x\n",ID,s,s);
109 //		   	hdr->TYPE = unknown;
110 //			getfiletype(hdr);
111 			bscs_requ_hdr(sd,hdr);
112 			bscs_requ_dat(sd,0,hdr->NRec,hdr);
113 //			bscs_requ_evt(sd,hdr);
114 			s=bscs_close(sd);
115 			fprintf(stdout,"c ID=%016"PRIx64" s=%i %08x\n",ID,s,s);
116 		}
117 		else if (!strncasecmp(cmd,"openr",5)) {
118 			ID = htole64(0x233ab6dfc96f664fLL);
119 
120 			ID = htole64(0x233ab6dfc96f664fLL);
121 			fprintf(stdout,"or ID=%016"PRIx64" s=%i %08x\n",ID,s,s);
122 			s=bscs_open(sd, &ID);
123 		}
124 		else if (!strncasecmp(cmd,"openw",5)) {
125 			char *fn = cmd+5;
126 			char *ix;
127 		     	while (isspace(fn[0])) fn++;
128 		     	ix = fn;
129 		     	while (!isspace(ix[0])) ix++;
130 		     	ix[0]=0;
131 
132 		     	hdr = sopen(fn,"r",hdr);
133 
134 			ID = 0;
135 			s=bscs_open(sd, &ID);
136 			fprintf(stdout,"openw: ID=%016"PRIx64" s=%i %08x\n",ID,s,s);
137 		}
138 		else if (!strncasecmp(cmd,"sendhdr",7)) {
139 			s= bscs_send_hdr(sd, hdr);
140 		}
141 		else if (!strncasecmp(cmd,"senddat",7)) {
142 			s= bscs_send_dat(sd, hdr->AS.rawdata, hdr->AS.bpb*hdr->AS.length);
143 			fprintf(stdout,"sent dat %i\n",s);
144 		}
145 		else if (!strncasecmp(cmd,"sendevt",7)) {
146 			if (hdr->TYPE != GDF) hdrEVT2rawEVT(hdr);
147 			if (hdr->EVENT.N>0) s= bscs_send_evt(sd, hdr);
148 		}
149 
150 		else if (!strncasecmp(cmd,"hdr",3)) {
151 			bscs_requ_hdr(sd,hdr);
152 		}
153 		else if (!strncasecmp(cmd,"show1",5)) {
154 			hdr2ascii(hdr,stdout,1);
155 		}
156 		else if (!strncasecmp(cmd,"show2",5)) {
157 			hdr2ascii(hdr,stdout,2);
158 		}
159 		else if (!strncasecmp(cmd,"show3",5)) {
160 			hdr2ascii(hdr,stdout,3);
161 		}
162 		else if (!strncasecmp(cmd,"show4",5)) {
163 			hdr2ascii(hdr,stdout,4);
164 		}
165 		else if (!strncasecmp(cmd,"dat",3)) {
166 			bscs_requ_dat(sd,0,hdr->NRec,hdr);
167 		}
168 		else if (!strncasecmp(cmd,"evt",3)) {
169 			bscs_requ_evt(sd,hdr);
170 		}
171 		else if (!strncasecmp(cmd,"ow",2)) {
172 			ID = 0;
173 			s=bscs_open(sd, &ID);
174 			fprintf(stdout,"ow ID=%016"PRIx64" s=%i %08x\n",ID,s,s);
175 		}
176 		else if (!strncasecmp(cmd,"close",5)) {
177 			s=bscs_close(sd);
178 			fprintf(stdout,"oc ID=%016"PRIx64" s=%i %08x\n",ID,s,s);
179 		}
180 		else if (!strncasecmp(cmd,"requ ",5)) {
181 			char *fn = cmd+5;
182 			char *ix;
183 		     	while (isspace(fn[0])) fn++;
184 		     	ix = fn;
185 		     	while (!isspace(ix[0])) ix++;
186 		     	ix[0]=0;
187 		     	cat64(fn,&ID);
188 			bscs_open(sd, &ID);
189 fprintf(stdout,"11 %i\n",hdr->EVENT.N);
190 			bscs_requ_hdr(sd,hdr);
191 		   	hdr->TYPE = unknown;
192 fprintf(stdout,"12 %i\n",hdr->EVENT.N);
193 			getfiletype(hdr);
194 fprintf(stdout,"13 %s %i\n",GetFileTypeString(hdr->TYPE),hdr->EVENT.N);
195 			bscs_requ_hdr(sd,hdr);
196 fprintf(stdout,"14a %i %i %i\n",0,(int)hdr->NRec,hdr->EVENT.N);
197 			bscs_requ_dat(sd,0,hdr->NRec,hdr);
198 fprintf(stdout,"14b %i\n",hdr->EVENT.N);
199 //			bscs_requ_evt(sd,hdr);
200 fprintf(stdout,"14c %i\n",hdr->EVENT.N);
201 		   	if (hdr->TYPE == GDF) {
202 fprintf(stdout,"15\n");
203 				;//hdr2ascii(hdr,stdout,3);
204 fprintf(stdout,"16 %i\n",hdr->EVENT.N);
205 			}
206 			bscs_close(sd);
207 		}
208 		else if (!strncasecmp(cmd,"send ",5)) {
209 			char *fn = cmd+5;
210 			char *ix;
211 		     	while (isspace(fn[0])) fn++;
212 		     	ix = fn;
213 		     	while (!isspace(ix[0])) ix++;
214 		     	ix[0]=0;
215 
216 		     	hdr = sopen(fn,"r",NULL);
217 //			if (hdr->TYPE!=GDF) {
218 			if (serror2(hdr)) {
219 				stat(fn, &info);
220 		     		FILE *fid = fopen(fn,"r");
221 		     		if (fid==NULL)
222 			     		fprintf(stdout,"file %s not found\n",fn);
223 		     		else {
224 
225 			     		uint8_t *buf = (uint8_t*) malloc(info.st_size);
226 					ssize_t count = fread(buf, 1, info.st_size, fid);
227 			     		fclose(fid);
228 
229 					ID = 0;
230 					if ((state = bscs_open(sd,&ID))) // write-open
231 						fprintf(stdout,"BSCS_OPEN failed: state=%08x\n",state);
232 					else
233 					{
234 				     		/* write key file */
235 						char *tmp = strrchr(fn,FILESEP);
236 						if (tmp==NULL) tmp = fn;
237 						strcpy(path2keys+path2keysLength,tmp);
238 
239 						fid = fopen(path2keys,"w");	// TODO: prevent overwritting
240 						fprintf(fid,"key4biosig: host=%s ID=%016"PRIx64" ",argv[1],ID);
241 						fclose(fid);
242 
243 						fprintf(stdout,"open_w ID=%016"PRIx64"\n",ID);
244 						hdr->HeadLen = count;
245 						bscs_send_dat(sd, buf, count);
246 						bscs_close(sd);
247 					}
248 					free(buf);
249 		     		}
250 		     	}
251 		     	else {
252 
253 				sread_raw(0,hdr->NRec,hdr,1,NULL,0); 	// collapse rawdata (remove obsolete channels)
254 				size_t bpb = bpb8_collapsed_rawdata(hdr)>>3;
255 				if (serror2(hdr)) {
256 					sclose(hdr);
257 					exit(-1);
258 				}
259 
260 				ID = 0;
261 				bscs_open(sd,&ID); // write-open
262 		     		/* write key file */
263 
264 				char *tmp = strrchr(fn,FILESEP);
265 				if (tmp==NULL) tmp = fn;
266 				strcpy(path2keys+path2keysLength,tmp);
267 
268 				FILE *fid = fopen(path2keys,"w");	// TODO: prevent overwritting
269 				if (fid==NULL)
270 					fprintf(stdout,"error: %i %s\n",errno, strerror(errno));
271 
272 				fprintf(fid,"bscs://%s/%016"PRIx64"",argv[1],ID);
273 				fclose(fid);
274 
275 				fprintf(stdout,"open_w  ID=%016"PRIx64" len=%"PRIiPTR"\n",ID,hdr->AS.length);
276 				s= bscs_send_hdr(sd, hdr);
277 				fprintf(stdout,"sent hdr %i %i\n",s,hdr->AS.bpb);
278 
279 				s = bscs_send_dat(sd, hdr->AS.rawdata, hdr->AS.length*bpb);
280 				fprintf(stdout,"sent dat %i %"PRIiPTR"\n",s,bpb);
281 
282 				if (hdr->TYPE != GDF) hdrEVT2rawEVT(hdr);
283 				if (hdr->EVENT.N>0) s= bscs_send_evt(sd, hdr);
284 				fprintf(stdout,"sent evt %i\n",s);
285 				s = bscs_close(sd);
286 				fprintf(stdout,"closed %08x\n",s);
287 
288 			     	sclose(hdr);
289 			}
290 		}
291 	}
292 
293     /*
294      * We can simply use close() to terminate the
295      * connection, since we're done .
296      */
297 //    bscs_disconnect(sd);
298 	return(0);
299 }
300