1 /**
2 * Copyright (C) 2016 Aaron Ball <nullspoon@oper.io>
3 *
4 * Ircbot is free software: you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation, either version 3 of the License, or
7 * (at your option) any later version.
8 *
9 * Ircbot is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with ircbot. If not, see <http://www.gnu.org/licenses/>.
16 */
17 #include <stdio.h>
18 #include <stdlib.h>
19 #include <unistd.h>
20 #include <string.h>
21 #include <errno.h>
22
23 /* Networking libs */
24 #include <arpa/inet.h>
25 #include <sys/types.h>
26 #include <sys/socket.h>
27 #include <netdb.h>
28
29 #include "common.h"
30
31 #define buflen 512
32
33 int newconn(char* addr, char* port) {
34 int status;
35 int socket_desc;
36 struct addrinfo hints, *p;
37 struct addrinfo *servinfo;
38
39 // Ensure our struct is empty
40 memset(&hints, 0, sizeof(hints));
41
42 // Set hints struct
43 hints.ai_flags = AI_PASSIVE;
44 hints.ai_family = AF_UNSPEC;
45 hints.ai_socktype = SOCK_STREAM;
46
47 if((status = getaddrinfo(addr, port, &hints, &servinfo)) != 0) {
48 fprintf(stderr, "getaddrinfo error: %s\n", gai_strerror(status));
49 exit(1);
50 }
51
52 // Iterrate the dns entries
53 for(p = servinfo;p != NULL; p = p->ai_next) {
54 // Attempt to create socket
55 socket_desc = socket(p->ai_family, p->ai_socktype, p->ai_protocol);
56
57 // If socket creation failed, skip entry
58 if (socket_desc == -1) continue;
59
60 // Attempt to connect. If successful, break out of loop
61 if (connect(socket_desc, p->ai_addr, p->ai_addrlen) != -1) break;
62 }
63
64 return socket_desc;
65 }
66
67 // int newconn(char* addr, int port) {
68 // int socket_desc;
69 // struct sockaddr_in server;
70 //
71 // socket_desc = socket(AF_INET, SOCK_STREAM, 0);
72 //
73 // server.sin_family = AF_INET;
74 // server.sin_port = htons(port);
75 // server.sin_addr.s_addr = inet_addr(addr);
76 //
77 // if(connect(socket_desc, (struct sockaddr *)&server, sizeof(server)) < 0) {
78 // return -1;
79 // }
80 //
81 // return socket_desc;
82 // }
83
84 int recv_line(int sockd, char* out) {
85 int i = 0;
86 char c = '\0';
87
88 while(c != '\n') {
89 recv(sockd, &c, 1, 0);
90 out[i] = c;
91 i++;
92 }
93 out[i] = '\0';
94 return i;
95 }
96
97
98
99 int doloop(int sockd, int ret) {
100 char buf[buflen];
101 char resp[buflen];
102 int len;
103
104 while(1) {
105 len = recv_line(sockd, buf);
106 if(len == 0) continue;
107 //if(len == -1) return -1;
108
109 printf("--- %s", buf);
110
111 if(strncmp(buf, "PING", 4) == 0) {
112 strcpy(resp, "PONG ");
113 strcat(resp, &buf[5]);
114 send(sockd, resp, strlen(resp), 0);
115
116 printf("%s", resp);
117
118 if(ret == 1) return 0;
119 continue;
120 }
121
122 if(strstr(buf, "Looking up your hostname") != NULL) {
123 // Receive next line
124 recv_line(sockd, buf);
125 printf(buf);
126 return 0;
127 }
128 len = 0;
129 }
130
131 return 0;
132 }
133
134
135 int irc_auth(int sockd, char* nick, char* user) {
136 char nickstr[buflen];
137 char userstr[buflen];
138 char joinstr[buflen];
139 char sendstr[buflen];
140
141 // Compose NICK statement
142 strcpy(nickstr, "NICK ");
143 strcat(nickstr, nick);
144 strcat(nickstr, "\n");
145
146 // Compose NICK statement
147 strcpy(userstr, "USER ");
148 strcat(userstr, nick);
149 strcat(userstr, " 0 * :");
150 strcat(userstr, user);
151 strcat(userstr, "\n");
152
153 // Compose the JOIN statement
154 strcpy(joinstr, "JOIN #general\n");
155
156 // Compose the PRIVMSG
157 strcpy(sendstr, "PRIVMSG #general :I'm here!\n");
158
159
160
161 // Wait for hostname identification
162 doloop(sockd, 1);
163
164 // Send NICK command
165 send(sockd, nickstr, strlen(nickstr), 0);
166 printf("%s\n", nickstr);
167
168 // Send USER command
169 send(sockd, userstr, strlen(userstr), 0);
170 printf("%s\n", userstr);
171
172 // Wait for ping and send pong response
173 doloop(sockd, 1);
174
175 sleep(1);
176
177 // Send JOIN command
178 send(sockd, joinstr, strlen(joinstr), 0);
179 printf(joinstr);
180
181 // Send a channel message
182 send(sockd, sendstr, strlen(sendstr), 0);
183 printf(sendstr);
184
185 //send(sockd, "QUIT\n", 6, 0);
186
187 doloop(sockd, 0);
188 printf("FIN!\n");
189
190 return 0;
191 }
192
193
194 int main(int argc, char* argv[]) {
195 char *server = argv[1];
196 char *port = argv[2];
197
198 int socket_desc;
199
200 //socket_desc = newconn("93.95.228.145", 6667);
201 socket_desc = newconn(server, port);
202
203 if(socket_desc == -1) {
204 printf("Connection error\n");
205 return 1;
206 }
207
208 //printf("Connected to %s on port %d\n", addr, port);
209 irc_auth(socket_desc, "swarley", "swarley");
210 //return_ping(socket_desc);
211
212 close(socket_desc);
213 return 0;
214 }
|