comparison src/protocols/irc/irc.c @ 5211:0241d6b6702d

[gaim-migrate @ 5581] Wrote a new debugging API, and of course core/ui split it. Debug statements can now have debug levels and categories, for future filtering of stuff, and color highlighting. It's nifty, m'kay? committer: Tailor Script <tailor@pidgin.im>
author Christian Hammond <chipx86@chipx86.com>
date Sat, 26 Apr 2003 06:46:08 +0000
parents fefad67de2c7
children abe4d103e300
comparison
equal deleted inserted replaced
5210:39bb2a35f8d9 5211:0241d6b6702d
1308 pos = htonl(gaim_xfer_get_bytes_sent(xfer)); 1308 pos = htonl(gaim_xfer_get_bytes_sent(xfer));
1309 1309
1310 write(xfer->fd, (char *)&pos, 4); 1310 write(xfer->fd, (char *)&pos, 4);
1311 } 1311 }
1312 1312
1313 /* NOTE: This was taken from irssi. Thanks irssi! */
1314
1315 static gboolean
1316 is_numeric(const char *str, char end_char)
1317 {
1318 g_return_val_if_fail(str != NULL, FALSE);
1319
1320 if (*str == '\0' || *str == end_char)
1321 return FALSE;
1322
1323 while (*str != '\0' && *str != end_char) {
1324 if (*str < '0' || *str > '9')
1325 return FALSE;
1326
1327 str++;
1328 }
1329
1330 return TRUE;
1331 }
1332
1333 #define get_params_match(params, pos) \
1334 (is_numeric(params[pos], '\0') && \
1335 is_numeric(params[(pos)+1], '\0') && atol(params[(pos)+1]) < 65536 && \
1336 is_numeric(params[(pos)+2], '\0'))
1337
1338 /* Return number of parameters in `params' that belong to file name.
1339 Normally it's paramcount-3, but I don't think anything forbids of
1340 adding some extension where there could be more parameters after
1341 file size.
1342
1343 MIRC sends filenames with spaces quoted ("file name"), but I'd rather
1344 not trust that entirely either. At least some clients that don't really
1345 understand the problem with spaces in file names sends the file name
1346 without any quotes. */
1347 static int
1348 get_file_params_count(char **params, int paramcount)
1349 {
1350 int pos, best;
1351
1352 if (*params[0] == '"') {
1353 /* quoted file name? */
1354 for (pos = 0; pos < paramcount - 3; pos++) {
1355 if (params[pos][strlen(params[pos]) - 1] == '"' &&
1356 get_params_match(params, pos + 1)) {
1357
1358 return pos + 1;
1359 }
1360 }
1361 }
1362
1363 best = paramcount - 3;
1364
1365 for (pos = paramcount - 3; pos > 0; pos--) {
1366 if (get_params_match(params, pos))
1367 best = pos;
1368 }
1369
1370 return best;
1371 }
1372
1313 static void 1373 static void
1314 handle_ctcp(struct gaim_connection *gc, char *to, char *nick, 1374 handle_ctcp(struct gaim_connection *gc, char *to, char *nick,
1315 char *msg, char *word[], char *word_eol[]) 1375 char *msg, char *word[], char *word_eol[])
1316 { 1376 {
1317 struct irc_data *id = gc->proto_data; 1377 struct irc_data *id = gc->proto_data;
1323 "Multi-protocol Messaging Client: " WEBSITE "\001"); 1383 "Multi-protocol Messaging Client: " WEBSITE "\001");
1324 irc_send_notice (gc, nick, buf); 1384 irc_send_notice (gc, nick, buf);
1325 g_snprintf(out, sizeof(out), ">> CTCP VERSION requested from %s", nick); 1385 g_snprintf(out, sizeof(out), ">> CTCP VERSION requested from %s", nick);
1326 do_error_dialog(out, _("IRC CTCP info"), GAIM_INFO); 1386 do_error_dialog(out, _("IRC CTCP info"), GAIM_INFO);
1327 } 1387 }
1328 if (!g_ascii_strncasecmp(msg, "CLIENTINFO", 10)) { 1388 else if (!g_ascii_strncasecmp(msg, "CLIENTINFO", 10)) {
1329 g_snprintf(buf, sizeof(buf), "\001CLIENTINFO USERINFO CLIENTINFO VERSION\001"); 1389 g_snprintf(buf, sizeof(buf), "\001CLIENTINFO USERINFO CLIENTINFO VERSION\001");
1330 irc_send_notice (gc, nick, buf); 1390 irc_send_notice (gc, nick, buf);
1331 g_snprintf(out, sizeof(out), ">> CTCP CLIENTINFO requested from %s", nick); 1391 g_snprintf(out, sizeof(out), ">> CTCP CLIENTINFO requested from %s", nick);
1332 do_error_dialog(out, _("IRC CTCP info"), GAIM_INFO); 1392 do_error_dialog(out, _("IRC CTCP info"), GAIM_INFO);
1333 } 1393 }
1334 if (!g_ascii_strncasecmp(msg, "USERINFO", 8)) { 1394 else if (!g_ascii_strncasecmp(msg, "USERINFO", 8)) {
1335 g_snprintf(buf, sizeof(buf), "\001USERINFO Alias: %s\001", gc->account->alias); 1395 g_snprintf(buf, sizeof(buf), "\001USERINFO Alias: %s\001", gc->account->alias);
1336 irc_send_notice (gc, nick, buf); 1396 irc_send_notice (gc, nick, buf);
1337 g_snprintf(out, sizeof(out), ">> CTCP USERINFO requested from %s", nick); 1397 g_snprintf(out, sizeof(out), ">> CTCP USERINFO requested from %s", nick);
1338 do_error_dialog(out, _("IRC CTCP info"), GAIM_INFO); 1398 do_error_dialog(out, _("IRC CTCP info"), GAIM_INFO);
1339 } 1399 }
1340 if (!g_ascii_strncasecmp(msg, "ACTION", 6)) { 1400 else if (!g_ascii_strncasecmp(msg, "ACTION", 6)) {
1341 char *po = strchr(msg + 6, 1); 1401 char *po = strchr(msg + 6, 1);
1342 char *tmp; 1402 char *tmp;
1343 if (po) *po = 0; 1403 if (po) *po = 0;
1344 tmp = g_strconcat("/me", msg + 6, NULL); 1404 tmp = g_strconcat("/me", msg + 6, NULL);
1345 handle_privmsg(gc, to, nick, tmp); 1405 handle_privmsg(gc, to, nick, tmp);
1346 g_free(tmp); 1406 g_free(tmp);
1347 } 1407 }
1348 if (!g_ascii_strncasecmp(msg, "PING", 4)) { 1408 else if (!g_ascii_strncasecmp(msg, "PING", 4)) {
1349 g_snprintf(buf, sizeof(buf), "\001%s\001", msg); 1409 g_snprintf(buf, sizeof(buf), "\001%s\001", msg);
1350 irc_send_notice (gc, nick, buf); 1410 irc_send_notice (gc, nick, buf);
1351 g_snprintf(out, sizeof(out), ">> CTCP PING requested from %s", nick); 1411 g_snprintf(out, sizeof(out), ">> CTCP PING requested from %s", nick);
1352 do_error_dialog(out, _("IRC CTCP info"), GAIM_INFO); 1412 do_error_dialog(out, _("IRC CTCP info"), GAIM_INFO);
1353 } 1413 }
1354 if (!g_ascii_strncasecmp(msg, "DCC CHAT", 8)) { 1414 else if (!g_ascii_strncasecmp(msg, "DCC CHAT", 8)) {
1355 char **chat_args = g_strsplit(msg, " ", 5); 1415 char **chat_args = g_strsplit(msg, " ", 5);
1356 char ask[1024]; 1416 char ask[1024];
1357 struct dcc_chat *dccchat = g_new0(struct dcc_chat, 1); 1417 struct dcc_chat *dccchat = g_new0(struct dcc_chat, 1);
1358 dccchat->gc = gc; 1418 dccchat->gc = gc;
1359 g_snprintf(dccchat->ip_address, sizeof(dccchat->ip_address), chat_args[3]); 1419 g_snprintf(dccchat->ip_address, sizeof(dccchat->ip_address), chat_args[3]);
1360 dccchat->port=atoi(chat_args[4]); 1420 dccchat->port=atoi(chat_args[4]);
1361 g_snprintf(dccchat->nick, sizeof(dccchat->nick), nick); 1421 g_snprintf(dccchat->nick, sizeof(dccchat->nick), nick);
1362 g_snprintf(ask, sizeof(ask), _("%s would like to establish a DCC chat"), nick); 1422 g_snprintf(ask, sizeof(ask), _("%s would like to establish a DCC chat"), nick);
1363 do_ask_dialog(ask, _("This requires a direct connection to be established between the two computers. Messages sent will not pass through the IRC server"), dccchat, _("Connect"), dcc_chat_init, _("Cancel"), dcc_chat_cancel, my_protocol->handle, FALSE); 1423 do_ask_dialog(ask, _("This requires a direct connection to be established between the two computers. Messages sent will not pass through the IRC server"), dccchat, _("Connect"), dcc_chat_init, _("Cancel"), dcc_chat_cancel, my_protocol->handle, FALSE);
1364 } 1424 }
1365 1425 else if (!g_ascii_strncasecmp(msg, "DCC SEND", 8)) {
1366
1367 if (!g_ascii_strncasecmp(msg, "DCC SEND", 8)) {
1368 struct gaim_xfer *xfer; 1426 struct gaim_xfer *xfer;
1369 char **send_args; 1427 char **send_args;
1370 char *ip, *filename; 1428 char *ip, *filename;
1371 struct irc_xfer_data *xfer_data; 1429 struct irc_xfer_data *xfer_data;
1372 size_t size; 1430 size_t size;
1431 int param_count, file_params, len;
1373 int port; 1432 int port;
1374 1433
1375 send_args = g_strsplit(msg, " ", 6); 1434 /* Okay, this is ugly, but should get us past "DCC SEND" */
1376 send_args[5][strlen(send_args[5])-1] = 0; 1435 msg = strstr(msg, "DCC SEND");
1436 msg = strchr(msg, ' ') + 1;
1437 msg = strchr(msg, ' ') + 1;
1438
1439 /* SEND <file name> <address> <port> <size> [...] */
1440 send_args = g_strsplit(msg, " ", -1);
1441
1442 for (param_count = 0; send_args[param_count] != NULL; param_count++)
1443 ;
1444
1445 if (param_count < 4) {
1446 char buf[IRC_BUF_LEN];
1447
1448 g_snprintf(buf, sizeof(buf),
1449 _("Received an invalid file send request from %s."),
1450 nick);
1451
1452 do_error_dialog(buf, _("IRC Error"), GAIM_ERROR);
1453
1454 return;
1455 }
1456
1457 file_params = get_file_params_count(send_args, param_count);
1458
1459 /* send_args[paramcount - 1][strlen(send_args[5])-1] = 0; */
1377 1460
1378 /* Give these better names. */ 1461 /* Give these better names. */
1379 ip = send_args[3]; 1462 ip = send_args[file_params];
1380 filename = send_args[2]; 1463 port = atoi(send_args[file_params + 1]);
1381 size = atoi(send_args[5]); 1464 size = atoi(send_args[file_params + 2]);
1382 port = atoi(send_args[4]); 1465
1466 send_args[file_params] = NULL;
1467
1468 filename = g_strjoinv(" ", send_args);
1469
1470 g_strfreev(send_args);
1471
1472 len = strlen(filename);
1473
1474 if (len > 1 && *filename == '"' && filename[len - 1] == '"') {
1475 /* "file name" - MIRC sends filenames with spaces like this */
1476 filename[len - 1] = '\0';
1477 g_memmove(filename, filename + 1, len);
1478 }
1383 1479
1384 /* Setup the IRC-specific transfer data. */ 1480 /* Setup the IRC-specific transfer data. */
1385 xfer_data = g_malloc0(sizeof(struct irc_xfer_data)); 1481 xfer_data = g_malloc0(sizeof(struct irc_xfer_data));
1386 xfer_data->ip = ip; 1482 xfer_data->ip = ip;
1387 xfer_data->port = port; 1483 xfer_data->port = port;
1408 id->file_transfers = g_slist_append(id->file_transfers, xfer); 1504 id->file_transfers = g_slist_append(id->file_transfers, xfer);
1409 1505
1410 /* Now perform the request! */ 1506 /* Now perform the request! */
1411 gaim_xfer_request(xfer); 1507 gaim_xfer_request(xfer);
1412 } 1508 }
1413
1414 /*write_to_conv(c, out, WFLAG_SYSTEM, NULL, time(NULL), -1);*/
1415 } 1509 }
1416 1510
1417 static gboolean 1511 static gboolean
1418 irc_parse(struct gaim_connection *gc, char *buf) 1512 irc_parse(struct gaim_connection *gc, char *buf)
1419 { 1513 {