#include "unix.h" #include "conf.h" #include "irc.h" static int sock_perms(char fname[]) { // first get group by name struct group *group; if ((group = getgrnam(SOCKETGROUP)) == NULL) { fprintf(stderr,"no such group: %s\n",SOCKETGROUP); return -1; } // set group on socket if (chown(fname, -1, group->gr_gid) == -1) { perror("chown"); return -1; } // get current permissions, so we can modify them. struct stat sb; if (stat(fname, &sb) == -1) { perror("stat"); return -1; } if (chmod(fname, sb.st_mode|S_IWGRP) == -1) { perror("chmod"); return -1; } return 0; } // takes filename, returns socket fd // or -1 or whatever int unix_setup(char filename[]) { unlink(filename); int sock = socket(AF_UNIX, SOCK_DGRAM, 0); if (sock == -1) { perror("(unix) socket"); return -1; } struct sockaddr_un name; memset(&name, 0, sizeof name); name.sun_family = AF_UNIX; strncpy(name.sun_path, filename, (sizeof name.sun_path)-1); if (bind(sock, (struct sockaddr *)&name, sizeof name) == -1) { perror("(unix) bind"); return -1; } if (sock_perms(filename) == -1) { fprintf(stderr,"warning: couldn't correctly set up permissions on %s\n",filename); } return sock; } // reads a message from the fd in question, and sends it to irc int unix_handle(int fd, char chname[]) { // PRIVMSG #{chname} :{message} // 123456789 12 3 4 // 512 >= 13 + strlen(chname) + length of message // chname can be max 16 bytes, so worst case // 512 >= 13 + 16 + length of message // 483 >= length of message // 480 is slightly pessimistic but it's a rounder number. // (one more byte for null terminator needed by snprintf) unsigned char buf[481]; if (strlen(chname) > 16) { fprintf(stderr,"channel name %s is longer than 16 bytes, ignoring\n",chname); return -1; } ssize_t amt; if ((amt = recv(fd, buf, sizeof buf-1,0)) == -1) { perror("recv"); return -1; } else if (amt == 0) { fputs("unix eof\n",stderr); return -1; } else { int i; for (i=0;i 512) { fprintf(stderr,"irc message was somehow too long (this should never happen) (%d)/512\n",s); return -1; } if (irc_sendall(msg, s) == -1) { perror("sendall"); return -1; }; return 0; } }