implemented network_{receive,send} & {receive,send}_info
[my-code/ivac.git] / src / inet.c
1 /* inet.c -- network management stuff
2  *
3  * author: hackbard@hackdaworld.dyndns.org
4  *
5  */
6
7 #include "inet.h"
8
9 int network_init(t_ivac *ivac) {
10   
11   sockaddr_in addr;
12  
13   puts("[ivac] inet: initializing network ...");
14
15   memset(ivac->net.connection,0,MAX_CONNECTIONS*sizeof(t_connection));
16   ivac->net.c_count=0;
17   ivac->net.sendmask=0;
18
19   if((ivac->net.l_fd=socket(AF_INET,SOCK_STREAM,0))==-1) {
20     perror("[ivac] inet.c: socket call");
21     return ERROR;
22   }
23
24   memset(&addr,0,sizeof(struct sockaddr));
25   addr.sin_family=AF_INET;
26   addr.sin_port=htons(ivac->net.l_port);
27   addr.sin_addr.s_addr=INADDR_ANY;
28
29   if(bind(ivac->net.l_fd,(struct sockaddr *)&addr,
30           sizeof(struct sockaddr))==-1) {
31     perror("[ivac] inet.c: bind call");
32     return ERROR;
33   }
34
35   printf("[ivac] inet: listen on %s port %d.\n",inet_ntoa(addr.sin_addr.s_addr)
36                                                ,ivac->net.l_port);
37
38   return SUCCESS;
39 }
40
41 int network_manage_connection(t_ivac *ivac) {
42
43   int i;
44   sockaddr_in addr;
45   
46   for(i=0;i<MAX_CONNECTIONS;i++) {
47
48     if(ivac->net.connection[i].status&C_IN_USE) {
49
50       if(ivac->net.connection[i].status&C_HANGUP) {
51         if(close(ivac->net.connection[i].fd)==-1) {
52           perror("[ivac] inet.c: close call");
53           return ERROR;
54         }
55         ivac->net.connection[i].status=0;
56       }
57
58       if(ivac->net.connection[i].status&C_INFO_A) {
59
60         if(!ivac->net.connection[i].status&C_SOCKET) {
61           if((ivac->net.connection[i].fd=socket(AF_INET,SOCK_STREAM,0))==-1) {
62             perror("[ivac] inet.c: socket call");
63             return ERROR;
64           }
65         }
66
67         if(!ivac->net.connection[i].status&C_ESTABL) {
68
69           memset(&addr,0,sizeof(struct sockaddr));
70           addr.sin_family=AF_INET;
71           addr.sin_port=htons(ivac->net.connection[i].port);
72           addr.sin_addr_s_addr=inet_aton(ivac->net.connection[i].ip);
73           
74           if(connect(ivac->net.connection[i].fd,(struct sockaddr *)&addr,
75                      sizeof(struct sockaddr))==-1) {
76             perror("[ivac] inet.c: connect call");
77             return ERROR;
78           }
79
80         }
81
82       }
83
84     }
85
86   }
87
88   return SUCCESS;
89 }
90  
91 int network_send(int fd,unsigned char *data,int datasize) {
92
93   int count,left;
94
95   count=0;
96   left=datasize;
97
98   while(left) {
99     if((count=write(fd,data+datasize-left,left))==-1) {
100       perror("[ivac] inet.c: write call");
101       return ERROR;
102     }
103     left-=count;
104   }
105
106   return SUCCESS;
107 }
108
109 int network_receive(int fd,unsigned char *data,int datasize) {
110
111   int count,retval;
112
113   retval=1;
114   count=0;
115
116   while(retval) {
117     if((retval=read(fd,data+count,datasize-count))==-1) {
118       perror("[ivac] inet.c: read call");
119       return ERROR;
120     }
121     count+=retval;
122   }
123
124   return count;
125 }
126
127 int send_info(int fd,t_ivac *ivac) {
128
129   char data[SEND_I_MAX];
130   int size;
131
132   size=strlen(ivac->name);
133
134   data[0]=SEND_I_NAME;
135   data[1]=size;
136   strncpy(data+2,ivac->name,size);
137   size+=2;
138
139   data[size+1]=SEND_I_CAP;
140   data[size+2]=sizeof(unsigned char);
141   data[size+3]=ivac->net.cap;
142   size+=(sizeof(unsigned char)+2);
143
144   data[size+1]=SEND_I_AVCAP;
145   data[size+2]=sizeof(unsigned short);
146   data[size+2+sizeof(unsigned short)];
147   size+=(sizeof(unsigned short)+2);
148
149   if(network_send(fd,data,size)==ERROR) {
150     puts("[ivac] inet.c: send_info failed");
151     return ERROR;
152   }
153
154   return SUCCESS;
155 }
156
157 int receive_info(int i,t_ivac *ivac) {
158
159   char data[CHAR_USERNAME+2];
160   int count,length;
161
162   if((length=network_receive(ivac->net.connection[i].fd,
163                              data,SEND_I_MAX))==ERROR) {
164     puts("[ivac] inet.c: receive_info failed");
165     return ERROR;
166   }
167
168   while(length-count) {
169     switch(data[count]) {
170       case SEND_I_NAME:
171         strncpy(ivac->net.connection[i].name,data[count+2],data[count+1]);
172         ivac->net.connection[i].name[data[count+2]]='\0';
173         count+=(data[count+2]+2);
174         break;
175       case SEND_I_G_CAP:
176         ivac->net.connection[i].cap=data[count+4];
177         count+=(sizeof(unsigned char)+2);
178         break;
179       case SEND_I_AV_CAP:
180         ivac->net.connection[i].avcap=data[count+3]<<8;
181         ivac->net.connection[i].avcap|=data[count+4];
182         count+=(sizeof(unsigned short)+2);
183         break;
184       default:
185         puts("[ivac] inet.c: receive_info, unknown character");
186         return ERROR;
187     }
188   }
189     
190   return SUCCESS;
191 }