static void fillSpecialObject(ObjectPtr object, void (*fn) (FILE *, char *), void *closure) { FILE *tmp = NULL; char *buf = NULL; int rc, len, offset; if (object->flags & OBJECT_INPROGRESS) return; buf = get_chunk(); if (buf == NULL) { abortObject(object, 503, internAtom("Couldn't allocate chunk")); goto done; } tmp = tmpfile(); if (tmp == NULL) { abortObject(object, 503, internAtom(pstrerror(errno))); goto done; } (*fn) (tmp, closure); fflush(tmp); rewind(tmp); offset = 0; while (1) { len = fread(buf, 1, CHUNK_SIZE, tmp); if (len <= 0 && ferror(tmp)) { abortObject(object, 503, internAtom(pstrerror(errno))); goto done; } if (len <= 0) break; rc = objectAddData(object, buf, offset, len); if (rc < 0) { abortObject(object, 503, internAtom("Couldn't add data to object")); goto done; } offset += len; } object->length = offset; done: if (buf) dispose_chunk(buf); if (tmp) fclose(tmp); notifyObject(object); }
int fork_bnetd(int foreground) { int pid; #ifdef DO_DAEMONIZE if (!foreground) { if (chdir("/")<0) { eventlog(eventlog_level_error,__FUNCTION__,"could not change working directory to / (chdir: %s)",pstrerror(errno)); return -1; } switch ((pid = fork())) { case -1: eventlog(eventlog_level_error,__FUNCTION__,"could not fork (fork: %s)",pstrerror(errno)); return -1; case 0: /* child */ break; default: /* parent */ return pid; } //threadPool.size_controller().resize(1); #ifndef WITH_D2 close(STDINFD); close(STDOUTFD); close(STDERRFD); #endif # ifdef HAVE_SETPGID if (setpgid(0,0)<0) { eventlog(eventlog_level_error,__FUNCTION__,"could not create new process group (setpgid: %s)",pstrerror(errno)); return -1; } # else # ifdef HAVE_SETPGRP # ifdef SETPGRP_VOID if (setpgrp()<0) { eventlog(eventlog_level_error,__FUNCTION__,"could not create new process group (setpgrp: %s)",pstrerror(errno)); return -1; } # else if (setpgrp(0,0)<0) { eventlog(eventlog_level_error,__FUNCTION__,"could not create new process group (setpgrp: %s)",pstrerror(errno)); return -1; } # endif # else # ifdef HAVE_SETSID if (setsid()<0) { eventlog(eventlog_level_error,__FUNCTION__,"could not create new process group (setsid: %s)",pstrerror(errno)); return -1; } # else # error "One of setpgid(), setpgrp(), or setsid() is required" # endif # endif # endif } return 0; #endif return 0; }
void err_recvmsg(int err) { fprintf(stderr, "error: recvmsg(2) syscall failed\n"); perrno(err); pstrerror(err); fflush(stderr); }
void err_inet_ntop(int err) { fprintf(stderr, "error: inet_ntop(3) syscall failed\n"); perrno(err); pstrerror(err); fflush(stderr); }
void err_getaddrinfo(int err) { fprintf(stderr, "error: getaddrinfo(3) syscall failed\n"); perrno(err); pstrerror(err); fflush(stderr); }
void err_write(int err) { fprintf(stderr, "error: write(2) syscall failed\n"); perrno(err); pstrerror(err); fflush(stderr); }
void err_getsockname(int err) { fprintf(stderr, "error: getsockname(2) syscall failed\n"); perrno(err); pstrerror(err); fflush(stderr); }
void err_fopen(int err) { fprintf(stderr, "error: mmap(3) syscall failed\n"); perrno(err); pstrerror(err); fflush(stderr); }
void err_cmd_create(int err) { fprintf(stderr, "error: cmd_create() function call failed\n"); perrno(err); pstrerror(err); fflush(stderr); }
void err_recvfrom(int err) { fprintf(stderr, "error: recvfrom(2) syscall failed\n"); switch (err) { case EAGAIN: fprintf(stderr, " The socket is marked non-blocking and the receive operation\n"); fprintf(stderr, " would block, or a receive timeout had been set and the timeout\n"); fprintf(stderr, " expired before data was received.\n"); break; case EBADF: fprintf(stderr, " The argument s is an invalid descriptor.\n"); break; case ECONNREFUSED: fprintf(stderr, " A remote host refused to allow the network connection (typically\n"); fprintf(stderr, " because it is not running the requested service).\n"); break; case EFAULT: fprintf(stderr, " The receive was interrupted by delivery of a signal before any\n"); fprintf(stderr, " data were available.\n"); break; case EINVAL: fprintf(stderr, " Invalid argument passed.\n"); break; case ENOMEM: fprintf(stderr, " The socket is associated with a connection-oriented protocol and\n"); fprintf(stderr, " has not been connected (see connect(2) and accept(2)).\n"); break; case ENOTSOCK: fprintf(stderr, " The argument s does not refer to a socket.\n"); break; } perrno(err); pstrerror(err); fflush(stderr); }
void err_chdir(int err) { fprintf(stderr, "error: chdir(2) failed to change directory - %d\n", err); perrno(err); pstrerror(err); fflush(stderr); }
void err_malloc(int err) { fprintf(stderr, "error: malloc(3) failed to allocate memory - %d\n", err); perrno(err); pstrerror(err); fflush(stderr); }
void err_kill(int err) { fprintf(stderr, "error: kill system call failed\n"); perrno(err); pstrerror(err); fflush(stderr); }
void err_fstat(int err) { fprintf(stderr, "error: fstat(2) syscall failed\n"); perrno(err); pstrerror(err); fflush(stderr); }
void err_shmctl(int err) { fprintf(stderr, "error: shmctl(2) syscall failed\n"); perrno(err); pstrerror(err); fflush(stderr); }
void err_exec(int err) { /* Numberic constants mentioned in the man page for execve(2) cannot * be handled explicitly here because I have no idea where they are * defined on this system. */ fprintf(stderr, "error: exec family command failed\n"); perrno(err); pstrerror(err); fflush(stderr); }
void really_do_log_error_v(int type, int e, const char *f, va_list args) { if((type & LOGGING_MAX & logLevel) != 0) { char *es = pstrerror(e); if(es == NULL) es = "Unknown error"; vfprintf(logF, f, args); fprintf(logF, ": %s\n", es); } }
void err_inet_pton(int err) { fprintf(stderr, "error: inet_pton(3) syscall failed\n"); switch (err) { /* errno may not be set, in this case it is a special error */ case 0: fprintf(stderr, " Source host does not contain a character string representing\n"); fprintf(stderr, " a valid network address in the specified address family\n"); break; case EAFNOSUPPORT: fprintf(stderr, " Domain does not contain a valid address family\n"); perrno(err); pstrerror(err); break; default: perrno(err); pstrerror(err); break; } fflush(stderr); }
void err_bind(int err) { fprintf(stderr, "error: bind(2) syscall failed\n"); switch (err) { case EACCES: fprintf(stderr, "The address is protected, and the user is not the super-user.\n"); fprintf(stderr, "If domain is AF_UNIX: Search permission is denied on a component\n"); fprintf(stderr, "of the path prefix. (See also path_resolution(2).)\n"); break; case EBADF: fprintf(stderr, "sockfd is not a valid descriptor.\n"); break; case EINVAL: fprintf(stderr, "The socket is already bound to an address.\n"); fprintf(stderr, "If domain is AF_UNIX: The addrlen is wrong, or the socket was not\n"); fprintf(stderr, "in the AF_UNIX family.\n"); break; case ENOTSOCK: fprintf(stderr, "Argument is a descriptor for a file, not a socket.\n"); break; case EFAULT: fprintf(stderr, "If domain is AF_UNIX: my_addr points outside the user's accessible\n"); fprintf(stderr, "address space.\n"); break; case ELOOP: fprintf(stderr, "If domain is AF_UNIX: Too many symbolic links were encountered in\n"); fprintf(stderr, "resolving my_addr.\n"); break; case ENAMETOOLONG: fprintf(stderr, "If domain is AF_UNIX: `struct sockaddr' is too long.\n"); break; case ENOENT: fprintf(stderr, "If domain is AF_UNIX: The file does not exist.\n"); break; case ENOMEM: fprintf(stderr, "If domain is AF_UNIX: Insufficient kernel memory was available.\n"); break; case ENOTDIR: fprintf(stderr, "If domain is AF_UNIX: A component of the path prefix is not a\n"); fprintf(stderr, "directory.\n"); break; case EROFS: fprintf(stderr, "If domain is AF_UNIX: The socket inode would reside on a\n"); fprintf(stderr, "read-only file system.\n"); break; } perrno(err); pstrerror(err); fflush(stderr); }
void err_fork(int err) { fprintf(stderr, "error: fork(2) system call failed\n"); switch(err) { case EAGAIN: fprintf(stderr, " fork cannot allocate sufficient memory to copy the parent's page\n"); fprintf(stderr, " tables and allocate a task structure for the child.\n"); break; case ENOMEM: fprintf(stderr, " fork failed to allocate the necessary kernel structures because\n"); fprintf(stderr, " memory is tight.\n"); break; } perrno(err); pstrerror(err); fflush(stderr); }
void err_dsh_send(int err) { fprintf(stderr, "error: dsh_send() function call failed\n"); switch(err) { #ifndef __OpenBSD__ case ECANCELED: fprintf(stderr, " Send operation was cancelled.\n"); break; #endif case ETIMEDOUT: fprintf(stderr, " Send operation timed out waiting for reply.\n"); break; } perrno(err); pstrerror(err); fflush(stderr); }
void err_freopen(int err) { fprintf(stderr, "error: freopen() function caused an error\n"); switch(err) { case EINVAL: fprintf(stderr, " The mode provided to fopen, fdopen, or freopen was invalid.\n"); break; case ENOMEM: fprintf(stderr, " Not enough memory.\n"); break; default: fprintf(stderr, " freopen() unknown errno type encountered\n"); } perrno(err); pstrerror(err); fflush(stderr); }
/* * This routine returns the number of miliseconds that have passed since one second * before it is first called. This is used for timing fields in some packets. */ extern unsigned int get_ticks(void) { static int first=1; static long beginsec; struct timeval tv; if (gettimeofday(&tv,NULL)<0) { eventlog(eventlog_level_error,__FUNCTION__,"could not get time (gettimeofday: %s)",pstrerror(errno)); return 0; } if (first) { beginsec = tv.tv_sec-1; first = 0; } return (unsigned int)((tv.tv_sec-beginsec)*1000+tv.tv_usec/1000); }
static AtomPtr internAtomErrorV(int e, const char *f, va_list args) { char *es = pstrerror(e); AtomPtr atom; char *s1, *s2; int n, rc; va_list args_copy; if(f) { va_copy(args_copy, args); s1 = vsprintf_a(f, args_copy); va_end(args_copy); if(s1 == NULL) return NULL; n = strlen(s1); } else { s1 = NULL; n = 0; } s2 = malloc(n + 70); if(s2 == NULL) { free(s1); return NULL; } if(s1) { strcpy(s2, s1); free(s1); } rc = snprintf(s2 + n, 69, f ? ": %s" : "%s", es); if(rc < 0 || rc >= 69) { free(s2); return NULL; } atom = internAtomN(s2, n + rc); free(s2); return atom; }
void err_wait(int err) { fprintf(stderr, "error: wait() family function caused an error\n"); switch(err) { case ECHILD: fprintf(stderr, " Child does not exist for this process\n"); break; case EINVAL: fprintf(stderr, " Invalid options\n"); break; case EINTR: fprintf(stderr, " Unblocked signal or SIGCHLD was caught while WNOHANG was not set\n"); break; default: fprintf(stderr, " wait family type error has occurred\n"); break; } perrno(err); pstrerror(err); fflush(stderr); }
extern int get_socket_limit(void) { int socklimit = 0; #ifdef HAVE_GETRLIMIT struct rlimit rlim; if(getrlimit(RLIM_NUMFILES, &rlim) < 0) eventlog(eventlog_level_error, __FUNCTION__, "getrlimit returned error: %s", pstrerror(errno)); socklimit = rlim.rlim_cur; #else /* FIXME: WIN32: somehow get WSAData win32 socket limit here */ #endif #if !(defined HAVE_POLL || defined HAVE_KQUEUE || defined HAVE_EPOLL) if(!socklimit || FD_SETSIZE < socklimit) socklimit = FD_SETSIZE; #endif /* make socket limit smaller than file limit to make sure log files, db connections and save files will still work */ socklimit -= 64; return socklimit; }
t_list * realmlist_load(char const * filename) { FILE * fp; unsigned int line; unsigned int pos; unsigned int len; t_addr * raddr; char * temp, *temp2; char * buff; char * name; char * desc; t_realm * realm; t_list * list_head = NULL; if (!filename) { eventlog(eventlog_level_error,__FUNCTION__,"got NULL filename"); return NULL; } if (!(fp = fopen(filename,"r"))) { eventlog(eventlog_level_error,__FUNCTION__,"could not open realm file \"%s\" for reading (fopen: %s)",filename,pstrerror(errno)); return NULL; } list_head = list_create(); for (line=1; (buff = file_get_line(fp)); line++) { for (pos=0; buff[pos]=='\t' || buff[pos]==' '; pos++); if (buff[pos]=='\0' || buff[pos]=='#') { continue; } if ((temp = strrchr(buff,'#'))) { unsigned int endpos; *temp = '\0'; len = strlen(buff)+1; for (endpos=len-1; buff[endpos]=='\t' || buff[endpos]==' '; endpos--); buff[endpos+1] = '\0'; } /* skip any separators */ for (temp = buff; *temp && (*temp == ' ' || *temp == '\t');temp++); if (*temp != '"') { eventlog(eventlog_level_error,__FUNCTION__,"malformed line %u in file \"%s\" (no realmname)",line,filename); continue; } temp2 = temp + 1; /* find the next " */ for (temp = temp2; *temp && *temp != '"';temp++); if (*temp != '"' || temp == temp2) { eventlog(eventlog_level_error,__FUNCTION__,"malformed line %u in file \"%s\" (no realmname)",line,filename); continue; } /* save the realmname */ *temp = '\0'; name = xstrdup(temp2); /* eventlog(eventlog_level_trace, __FUNCTION__,"found realmname: %s",name); */ /* skip any separators */ for(temp = temp + 1; *temp && (*temp == '\t' || *temp == ' ');temp++); if (*temp == '"') { /* we have realm description */ temp2 = temp + 1; /* find the next " */ for(temp = temp2;*temp && *temp != '"';temp++); if (*temp != '"' || temp == temp2) { eventlog(eventlog_level_error,__FUNCTION__,"malformed line %u in file \"%s\" (no valid description)",line,filename); xfree(name); continue; } /* save the description */ *temp = '\0'; desc = xstrdup(temp2); /* eventlog(eventlog_level_trace, __FUNCTION__,"found realm desc: %s",desc); */ /* skip any separators */ for(temp = temp + 1; *temp && (*temp == ' ' || *temp == '\t');temp++); } else desc = xstrdup("\0"); temp2 = temp; /* find out where address ends */ for(temp = temp2 + 1; *temp && *temp != ' ' && *temp != '\t';temp++); if (*temp) *temp++ = '\0'; /* if is not the end of the file, end addr and move forward */ /* eventlog(eventlog_level_trace, __FUNCTION__,"found realm ip: %s",temp2); */ if (!(raddr = addr_create_str(temp2,0,BNETD_REALM_PORT))) /* 0 means "this computer" */ { eventlog(eventlog_level_error,__FUNCTION__,"invalid address value for field 3 on line %u in file \"%s\"",line,filename); xfree(name); xfree(desc); continue; } if (!(realm = realm_create(name,desc,addr_get_ip(raddr),addr_get_port(raddr)))) { eventlog(eventlog_level_error,__FUNCTION__,"could not create realm"); addr_destroy(raddr); xfree(name); xfree(desc); continue; } addr_destroy(raddr); xfree(name); xfree(desc); list_prepend_data(list_head,realm); } file_get_line(NULL); // clear file_get_line buffer if (fclose(fp)<0) eventlog(eventlog_level_error,__FUNCTION__,"could not close realm file \"%s\" after reading (fclose: %s)",filename,pstrerror(errno)); return list_head; }
static int mailbox_delete(t_mailbox * mailbox, unsigned int idx) { char * filename; char const * dentry; unsigned int i; int rez; if (mailbox==NULL) { eventlog(eventlog_level_error,__FUNCTION__,"got NULL mailbox"); return -1; } if (mailbox->maildir==NULL) { eventlog(eventlog_level_error,__FUNCTION__,"got NULL maildir"); return -1; } p_rewinddir(mailbox->maildir); dentry = NULL; /* if idx < 1 we should not crash :) */ for(i=0;i<idx && (dentry=p_readdir(mailbox->maildir))!=NULL;i++) if (dentry[0]=='.') i--; if (dentry==NULL) { eventlog(eventlog_level_error,__FUNCTION__,"index out of range"); return -1; } filename=xmalloc(strlen(dentry)+1+strlen(mailbox->path)+1); sprintf(filename,"%s/%s",mailbox->path,dentry); rez=remove(filename); if (rez<0) { eventlog(eventlog_level_info,__FUNCTION__,"could not remove file \"%s\" (remove: %s)",filename,pstrerror(errno)); } xfree(filename); return rez; }
extern int tracker_send_report(t_addrlist const * laddrs) { t_addr const * addrl; t_elem const * currl; t_addr const * addrt; t_elem const * currt; t_trackpacket packet; struct utsname utsbuf; struct sockaddr_in tempaddr; t_laddr_info * laddr_info; char tempa[64]; char tempb[64]; if (addrlist_get_length(track_servers)>0) { std::memset(&packet,0,sizeof(packet)); bn_short_nset(&packet.packet_version,(unsigned short)TRACK_VERSION); /* packet.port is set below */ bn_int_nset(&packet.flags, 0); std::strncpy((char *)packet.server_location, prefs_get_location(), sizeof(packet.server_location)); bn_byte_set(&packet.server_location[sizeof(packet.server_location)-1],'\0'); std::strncpy((char *)packet.software, PVPGN_SOFTWARE, sizeof(packet.software)); bn_byte_set(&packet.software[sizeof(packet.software)-1],'\0'); std::strncpy((char *)packet.version, PVPGN_VERSION, sizeof(packet.version)); bn_byte_set(&packet.version[sizeof(packet.version)-1],'\0'); std::strncpy((char *)packet.server_desc, prefs_get_description(), sizeof(packet.server_desc)); bn_byte_set(&packet.server_desc[sizeof(packet.server_desc)-1],'\0'); std::strncpy((char *)packet.server_url, prefs_get_url(), sizeof(packet.server_url)); bn_byte_set(&packet.server_url[sizeof(packet.server_url)-1],'\0'); std::strncpy((char *)packet.contact_name, prefs_get_contact_name(), sizeof(packet.contact_name)); bn_byte_set(&packet.contact_name[sizeof(packet.contact_name)-1],'\0'); std::strncpy((char *)packet.contact_email, prefs_get_contact_email(), sizeof(packet.contact_email)); bn_byte_set(&packet.contact_email[sizeof(packet.contact_email)-1],'\0'); bn_int_nset(&packet.users,connlist_login_get_length()); bn_int_nset(&packet.channels,channellist_get_length()); bn_int_nset(&packet.games,gamelist_get_length()); bn_int_nset(&packet.uptime,server_get_uptime()); bn_int_nset(&packet.total_logins,connlist_total_logins()); bn_int_nset(&packet.total_games,gamelist_total_games()); if (uname(&utsbuf)<0) { eventlog(eventlog_level_warn,__FUNCTION__,"could not get platform info (uname: %s)",pstrerror(errno)); std::strncpy((char *)packet.platform,"",sizeof(packet.platform)); } else { std::strncpy((char *)packet.platform, utsbuf.sysname, sizeof(packet.platform)); bn_byte_set(&packet.platform[sizeof(packet.platform)-1],'\0'); } LIST_TRAVERSE_CONST(laddrs,currl) { addrl = (t_addr*)elem_get_data(currl); if (!(laddr_info = (t_laddr_info*)addr_get_data(addrl).p)) { eventlog(eventlog_level_error,__FUNCTION__,"address data is NULL"); continue; } if (laddr_info->type!=laddr_type_bnet) continue; /* don't report IRC, telnet, and other non-game ports */ bn_short_nset(&packet.port,addr_get_port(addrl)); LIST_TRAVERSE_CONST(track_servers,currt) { addrt = (t_addr*)elem_get_data(currt); std::memset(&tempaddr,0,sizeof(tempaddr)); tempaddr.sin_family = PSOCK_AF_INET; tempaddr.sin_port = htons(addr_get_port(addrt)); tempaddr.sin_addr.s_addr = htonl(addr_get_ip(addrt)); if (!addr_get_addr_str(addrl,tempa,sizeof(tempa))) std::strcpy(tempa,"x.x.x.x:x"); if (!addr_get_addr_str(addrt,tempb,sizeof(tempb))) std::strcpy(tempa,"x.x.x.x:x"); /* eventlog(eventlog_level_debug,__FUNCTION__,"sending tracking info from %s to %s",tempa,tempb); */ if (psock_sendto(laddr_info->usocket,&packet,sizeof(packet),0,(struct sockaddr *)&tempaddr,(psock_t_socklen)sizeof(tempaddr))<0) eventlog(eventlog_level_warn,__FUNCTION__,"could not send tracking information from %s to %s (psock_sendto: %s)",tempa,tempb,pstrerror(errno)); }
void err_sendmsg(int err) { fprintf(stderr, "error: sendmsg(2) syscall failed\n"); switch (err) { case EACCES: fprintf(stderr, " (For Unix domain sockets, which are identified by pathname)\n"); fprintf(stderr, " Write permission is denied on the destination socket file, or\n"); fprintf(stderr, " search permission is denied for one of the directories the path\n"); fprintf(stderr, " prefix. (See path_resolution(2).)\n"); break; case EAGAIN: fprintf(stderr, " The socket is marked non-blocking and the requested operation\n"); fprintf(stderr, " would block.\n"); break; case EBADF: fprintf(stderr, " An invalid descriptor was specified.\n"); break; case ECONNRESET: fprintf(stderr, " Connection reset by peer.\n"); break; case EDESTADDRREQ: fprintf(stderr, " The socket is not connection-mode, and no peer address is set.\n"); break; case EFAULT: fprintf(stderr, " An invalid user space address was specified for a parameter.\n"); break; case EINTR: fprintf(stderr, " A signal occurred before any data was transmitted.\n"); break; case EINVAL: fprintf(stderr, " Invalid argument passed.\n"); break; case EISCONN: fprintf(stderr, " The connection-mode socket was connected already but a recipient\n"); fprintf(stderr, " was specified. (Now either this error is returned, or the\n"); fprintf(stderr, " recipient specification is ignored.)\n"); break; case EMSGSIZE: fprintf(stderr, " The socket type requires that message be sent atomically, and\n"); fprintf(stderr, " the size of the message to be sent made this impossible.\n"); break; case ENOBUFS: fprintf(stderr, " The output queue for a network interface was full. This gener-\n"); fprintf(stderr, " ally indicates that the interface has stopped sending, but may\n"); fprintf(stderr, " be caused by transient congestion. (Normally, this does not\n"); fprintf(stderr, " occur in Linux. Packets are just silently dropped when a device\n"); fprintf(stderr, " queue overflows.)\n"); break; case ENOMEM: fprintf(stderr, " No memory available.\n"); break; case ENOTCONN: fprintf(stderr, " The socket is not connected, and no target has been given.\n"); break; case ENOTSOCK: fprintf(stderr, " The argument s is not a socket.\n"); break; case EOPNOTSUPP: fprintf(stderr, " Some bit in the flags argument is inappropriate for the socket\n"); fprintf(stderr, " type.\n"); break; case EPIPE: fprintf(stderr, " The local end has been shut down on a connection oriented\n"); fprintf(stderr, " socket. In this case the process will also receive a SIGPIPE\n"); fprintf(stderr, " unless MSG_NOSIGNAL is set.\n"); break; } perrno(err); pstrerror(err); fflush(stderr); }