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
68 int recv_line(int sockd, char* out) {
69 int i = 0;
70 char c = '\0';
71
72 while(c != '\n') {
73 recv(sockd, &c, 1, 0);
74 out[i] = c;
75 i++;
76 }
77 out[i] = '\0';
78 return i;
79 }
80
81
82
83 int doloop(int sockd, int ret) {
84 char buf[buflen];
85 char resp[buflen];
86 int len;
87
88 while(1) {
89 len = recv_line(sockd, buf);
90 if(len == 0) continue;
91 //if(len == -1) return -1;
92
93 printf("--- %s", buf);
94
95 if(strncmp(buf, "PING", 4) == 0) {
96 strcpy(resp, "PONG ");
97 strcat(resp, &buf[5]);
98 send(sockd, resp, strlen(resp), 0);
99
100 printf("%s", resp);
101
102 if(ret == 1) return 0;
103 continue;
104 }
105
106 if(strstr(buf, "Looking up your hostname") != NULL) {
107 // Receive next line
108 recv_line(sockd, buf);
109 printf(buf);
110 return 0;
111 }
112 len = 0;
113 }
114
115 return 0;
116 }
117
118
119 int irc_auth(int sockd, char* nick, char* user) {
120 char nickstr[buflen];
121 char userstr[buflen];
122 char joinstr[buflen];
123 char sendstr[buflen];
124
125 // Compose NICK statement
126 strcpy(nickstr, "NICK ");
127 strcat(nickstr, nick);
128 strcat(nickstr, "\n");
129
130 // Compose NICK statement
131 strcpy(userstr, "USER ");
132 strcat(userstr, nick);
133 strcat(userstr, " 0 * :");
134 strcat(userstr, user);
135 strcat(userstr, "\n");
136
137 // Compose the JOIN statement
138 strcpy(joinstr, "JOIN #general\n");
139
140 // Compose the PRIVMSG
141 strcpy(sendstr, "PRIVMSG #general :I'm here!\n");
142
143
144
145 // Wait for hostname identification
146 doloop(sockd, 1);
147
148 // Send NICK command
149 send(sockd, nickstr, strlen(nickstr), 0);
150 printf("%s\n", nickstr);
151
152 // Send USER command
153 send(sockd, userstr, strlen(userstr), 0);
154 printf("%s\n", userstr);
155
156 // Wait for ping and send pong response
157 doloop(sockd, 1);
158
159 sleep(1);
160
161 // Send JOIN command
162 send(sockd, joinstr, strlen(joinstr), 0);
163 printf(joinstr);
164
165 // Send a channel message
166 send(sockd, sendstr, strlen(sendstr), 0);
167 printf(sendstr);
168
169 //send(sockd, "QUIT\n", 6, 0);
170
171 doloop(sockd, 0);
172 printf("FIN!\n");
173
174 return 0;
175 }
176
177
178 int main(int argc, char* argv[]) {
179 char *server = argv[1];
180 char *port = argv[2];
181
182 int socket_desc;
183
184 socket_desc = newconn(server, port);
185
186 if(socket_desc == -1) {
187 printf("Connection error\n");
188 return 1;
189 }
190
191 irc_auth(socket_desc, "nullspoon", "nullspoon");
192
193 // Cleanup
194 close(socket_desc);
195
196 return 0;
197 }
|