static gdImagePtr loadshapeimage(char *name) { gdImagePtr rv = 0; char *shapeimagefile,*suffix; FILE *in = NULL; if ((shapeimagefile=safefile(name))) { #ifndef MSWIN32 in = fopen (shapeimagefile, "r"); #else in = fopen (shapeimagefile, "rb"); #endif } if (!in) agerr(AGERR, "couldn't open image file %s\n",shapeimagefile); else { suffix = strrchr(shapeimagefile,'.'); if (!suffix) suffix = shapeimagefile; else suffix++; if (!strcasecmp(suffix,"wbmp")) rv = gdImageCreateFromWBMP(in); #ifdef WITH_GIF else if (!strcasecmp(suffix,"gif")) rv = gdImageCreateFromGif(in); #endif #ifdef HAVE_LIBPNG else if (!strcasecmp(suffix,"png")) rv = gdImageCreateFromPng(in); #endif #ifdef HAVE_LIBJPEG else if (!strcasecmp(suffix,"jpeg")||!strcasecmp(suffix,"jpg")) rv = gdImageCreateFromJpeg(in); #endif else if (!strcasecmp(suffix,"xbm")) rv = gdImageCreateFromXbm(in); else agerr(AGERR, "image file %s suffix not recognized\n",name); fclose(in); if (!rv) agerr(AGERR, "image file %s contents were not recognized\n",name); } return rv; }
/* cat_libfile: * Write library files onto the given file pointer. * arglib is an NULL-terminated array of char* * Each non-trivial entry should be the name of a file to be included. * stdlib is an NULL-terminated array of char* * Each of these is a line of a standard library to be included. * If any item in arglib is the empty string, the stdlib is not used. * The stdlib is printed first, if used, followed by the user libraries. * We check that for web-safe file usage. */ void cat_libfile(FILE * ofp, char **arglib, char **stdlib) { FILE *fp; char *p, **s, *bp; int i, use_stdlib = TRUE; /* check for empty string to turn off stdlib */ if (arglib) { for (i = 0; use_stdlib && ((p = arglib[i])); i++) { if (*p == '\0') use_stdlib = FALSE; } } if (use_stdlib) for (s = stdlib; *s; s++) { fputs(*s, ofp); fputc('\n', ofp); } if (arglib) { for (i = 0; (p = arglib[i]) != 0; i++) { if (*p == '\0') continue; /* ignore empty string */ p = safefile(p); /* make sure filename is okay */ if ((fp = fopen(p, "r"))) { while ((bp = Fgets(fp))) fputs(bp, ofp); } else agerr(AGWARN, "can't open library file %s\n", p); } } }
int relay6_script( char *scriptpath, struct sockaddr_in6 *client, struct dhcp6 *dh6, int len ) { struct dhcp6_optinfo optinfo; struct dhcp6opt *optend; int i, j, iapds, ianas, envc, elen, ret = 0; char **envp, *s, *t; struct dhcp6_listval *v; pid_t pid, wpid; /* if a script is not specified, do nothing */ if (scriptpath == NULL || strlen(scriptpath) == 0) return -1; /* only replies are interesting */ if (dh6->dh6_msgtype != DH6_REPLY) { if (dh6->dh6_msgtype != DH6_ADVERTISE) { dprintf(LOG_INFO, FNAME, "forward msg#%d to client?", dh6->dh6_msgtype); return -1; } return 0; } /* parse options */ optend = (struct dhcp6opt *)((caddr_t) dh6 + len); dhcp6_init_options(&optinfo); if (dhcp6_get_options((struct dhcp6opt *)(dh6 + 1), optend, &optinfo) < 0) { dprintf(LOG_INFO, FNAME, "failed to parse options"); return -1; } /* initialize counters */ iapds = 0; ianas = 0; envc = 2; /* we at least include the address and the terminator */ /* count the number of variables */ for (v = TAILQ_FIRST(&optinfo.iapd_list); v; v = TAILQ_NEXT(v, link)) iapds++; envc += iapds; for (v = TAILQ_FIRST(&optinfo.iana_list); v; v = TAILQ_NEXT(v, link)) ianas++; envc += ianas; /* allocate an environments array */ if ((envp = malloc(sizeof (char *) * envc)) == NULL) { dprintf(LOG_NOTICE, FNAME, "failed to allocate environment buffer"); dhcp6_clear_options(&optinfo); return -1; } memset(envp, 0, sizeof (char *) * envc); /* * Copy the parameters as environment variables */ i = 0; /* address */ t = addr2str((struct sockaddr *) client); if (t == NULL) { dprintf(LOG_NOTICE, FNAME, "failed to get address of client"); ret = -1; goto clean; } elen = sizeof (client_str) + 1 + strlen(t) + 1; if ((s = envp[i++] = malloc(elen)) == NULL) { dprintf(LOG_NOTICE, FNAME, "failed to allocate string for client"); ret = -1; goto clean; } memset(s, 0, elen); snprintf(s, elen, "%s=%s", client_str, t); /* IAs */ j = 0; for (v = TAILQ_FIRST(&optinfo.iapd_list); v; v = TAILQ_NEXT(v, link)) { if ((s = envp[i++] = iapd2str(j++, v)) == NULL) { ret = -1; goto clean; } } j = 0; for (v = TAILQ_FIRST(&optinfo.iana_list); v; v = TAILQ_NEXT(v, link)) { if ((s = envp[i++] = iana2str(j++, v)) == NULL) { ret = -1; goto clean; } } /* launch the script */ pid = fork(); if (pid < 0) { dprintf(LOG_ERR, FNAME, "failed to fork: %s", strerror(errno)); ret = -1; goto clean; } else if (pid) { int wstatus; do { wpid = wait(&wstatus); } while (wpid != pid && wpid > 0); if (wpid < 0) dprintf(LOG_ERR, FNAME, "wait: %s", strerror(errno)); else { dprintf(LOG_DEBUG, FNAME, "script \"%s\" terminated", scriptpath); } } else { char *argv[2]; int fd; argv[0] = scriptpath; argv[1] = NULL; if (safefile(scriptpath)) { dprintf(LOG_ERR, FNAME, "script \"%s\" cannot be executed safely", scriptpath); exit(1); } if (foreground == 0 && (fd = open("/dev/null", O_RDWR)) != -1) { dup2(fd, STDIN_FILENO); dup2(fd, STDOUT_FILENO); dup2(fd, STDERR_FILENO); if (fd > STDERR_FILENO) close(fd); } execve(scriptpath, argv, envp); dprintf(LOG_ERR, FNAME, "child: exec failed: %s", strerror(errno)); exit(0); } clean: for (i = 0; i < envc; i++) free(envp[i]); free(envp); dhcp6_clear_options(&optinfo); return ret; }
int client6_script( char *scriptpath, int state, struct dhcp6_optinfo *optinfo ) { int i, dnsservers, ntpservers, dnsnamelen, envc, elen, ret = 0; int sipservers, sipnamelen; int nisservers, nisnamelen; int nispservers, nispnamelen; int bcmcsservers, bcmcsnamelen; char **envp, *s; char reason[] = "REASON=NBI"; struct dhcp6_listval *v; pid_t pid, wpid; /* if a script is not specified, do nothing */ if (scriptpath == NULL || strlen(scriptpath) == 0) return -1; /* initialize counters */ dnsservers = 0; ntpservers = 0; dnsnamelen = 0; sipservers = 0; sipnamelen = 0; nisservers = 0; nisnamelen = 0; nispservers = 0; nispnamelen = 0; bcmcsservers = 0; bcmcsnamelen = 0; envc = 2; /* we at least include the reason and the terminator */ /* count the number of variables */ for (v = TAILQ_FIRST(&optinfo->dns_list); v; v = TAILQ_NEXT(v, link)) dnsservers++; envc += dnsservers ? 1 : 0; for (v = TAILQ_FIRST(&optinfo->dnsname_list); v; v = TAILQ_NEXT(v, link)) { dnsnamelen += v->val_vbuf.dv_len; } envc += dnsnamelen ? 1 : 0; for (v = TAILQ_FIRST(&optinfo->ntp_list); v; v = TAILQ_NEXT(v, link)) ntpservers++; envc += ntpservers ? 1 : 0; for (v = TAILQ_FIRST(&optinfo->sip_list); v; v = TAILQ_NEXT(v, link)) sipservers++; envc += sipservers ? 1 : 0; for (v = TAILQ_FIRST(&optinfo->sipname_list); v; v = TAILQ_NEXT(v, link)) { sipnamelen += v->val_vbuf.dv_len; } envc += sipnamelen ? 1 : 0; for (v = TAILQ_FIRST(&optinfo->nis_list); v; v = TAILQ_NEXT(v, link)) nisservers++; envc += nisservers ? 1 : 0; for (v = TAILQ_FIRST(&optinfo->nisname_list); v; v = TAILQ_NEXT(v, link)) { nisnamelen += v->val_vbuf.dv_len; } envc += nisnamelen ? 1 : 0; for (v = TAILQ_FIRST(&optinfo->nisp_list); v; v = TAILQ_NEXT(v, link)) nispservers++; envc += nispservers ? 1 : 0; for (v = TAILQ_FIRST(&optinfo->nispname_list); v; v = TAILQ_NEXT(v, link)) { nispnamelen += v->val_vbuf.dv_len; } envc += nispnamelen ? 1 : 0; for (v = TAILQ_FIRST(&optinfo->bcmcs_list); v; v = TAILQ_NEXT(v, link)) bcmcsservers++; envc += bcmcsservers ? 1 : 0; for (v = TAILQ_FIRST(&optinfo->bcmcsname_list); v; v = TAILQ_NEXT(v, link)) { bcmcsnamelen += v->val_vbuf.dv_len; } envc += bcmcsnamelen ? 1 : 0; /* allocate an environments array */ if ((envp = malloc(sizeof (char *) * envc)) == NULL) { dprintf(LOG_NOTICE, FNAME, "failed to allocate environment buffer"); return -1; } memset(envp, 0, sizeof (char *) * envc); /* * Copy the parameters as environment variables */ i = 0; /* reason */ if ((envp[i++] = strdup(reason)) == NULL) { dprintf(LOG_NOTICE, FNAME, "failed to allocate reason strings"); ret = -1; goto clean; } /* "var=addr1 addr2 ... addrN" + null char for termination */ if (dnsservers) { elen = sizeof (dnsserver_str) + (INET6_ADDRSTRLEN + 1) * dnsservers + 1; if ((s = envp[i++] = malloc(elen)) == NULL) { dprintf(LOG_NOTICE, FNAME, "failed to allocate strings for DNS servers"); ret = -1; goto clean; } memset(s, 0, elen); snprintf(s, elen, "%s=", dnsserver_str); for (v = TAILQ_FIRST(&optinfo->dns_list); v; v = TAILQ_NEXT(v, link)) { char *addr; addr = in6addr2str(&v->val_addr6, 0); strlcat(s, addr, elen); strlcat(s, " ", elen); } } if (ntpservers) { elen = sizeof (ntpserver_str) + (INET6_ADDRSTRLEN + 1) * ntpservers + 1; if ((s = envp[i++] = malloc(elen)) == NULL) { dprintf(LOG_NOTICE, FNAME, "failed to allocate strings for NTP servers"); ret = -1; goto clean; } memset(s, 0, elen); snprintf(s, elen, "%s=", ntpserver_str); for (v = TAILQ_FIRST(&optinfo->ntp_list); v; v = TAILQ_NEXT(v, link)) { char *addr; addr = in6addr2str(&v->val_addr6, 0); strlcat(s, addr, elen); strlcat(s, " ", elen); } } if (dnsnamelen) { elen = sizeof (dnsname_str) + dnsnamelen + 1; if ((s = envp[i++] = malloc(elen)) == NULL) { dprintf(LOG_NOTICE, FNAME, "failed to allocate strings for DNS name"); ret = -1; goto clean; } memset(s, 0, elen); snprintf(s, elen, "%s=", dnsname_str); for (v = TAILQ_FIRST(&optinfo->dnsname_list); v; v = TAILQ_NEXT(v, link)) { strlcat(s, v->val_vbuf.dv_buf, elen); strlcat(s, " ", elen); } } if (sipservers) { elen = sizeof (sipserver_str) + (INET6_ADDRSTRLEN + 1) * sipservers + 1; if ((s = envp[i++] = malloc(elen)) == NULL) { dprintf(LOG_NOTICE, FNAME, "failed to allocate strings for SIP servers"); ret = -1; goto clean; } memset(s, 0, elen); snprintf(s, elen, "%s=", sipserver_str); for (v = TAILQ_FIRST(&optinfo->sip_list); v; v = TAILQ_NEXT(v, link)) { char *addr; addr = in6addr2str(&v->val_addr6, 0); strlcat(s, addr, elen); strlcat(s, " ", elen); } } if (sipnamelen) { elen = sizeof (sipname_str) + sipnamelen + 1; if ((s = envp[i++] = malloc(elen)) == NULL) { dprintf(LOG_NOTICE, FNAME, "failed to allocate strings for SIP domain name"); ret = -1; goto clean; } memset(s, 0, elen); snprintf(s, elen, "%s=", sipname_str); for (v = TAILQ_FIRST(&optinfo->sipname_list); v; v = TAILQ_NEXT(v, link)) { strlcat(s, v->val_vbuf.dv_buf, elen); strlcat(s, " ", elen); } } if (nisservers) { elen = sizeof (nisserver_str) + (INET6_ADDRSTRLEN + 1) * nisservers + 1; if ((s = envp[i++] = malloc(elen)) == NULL) { dprintf(LOG_NOTICE, FNAME, "failed to allocate strings for NIS servers"); ret = -1; goto clean; } memset(s, 0, elen); snprintf(s, elen, "%s=", nisserver_str); for (v = TAILQ_FIRST(&optinfo->nis_list); v; v = TAILQ_NEXT(v, link)) { char *addr; addr = in6addr2str(&v->val_addr6, 0); strlcat(s, addr, elen); strlcat(s, " ", elen); } } if (nisnamelen) { elen = sizeof (nisname_str) + nisnamelen + 1; if ((s = envp[i++] = malloc(elen)) == NULL) { dprintf(LOG_NOTICE, FNAME, "failed to allocate strings for NIS domain name"); ret = -1; goto clean; } memset(s, 0, elen); snprintf(s, elen, "%s=", nisname_str); for (v = TAILQ_FIRST(&optinfo->nisname_list); v; v = TAILQ_NEXT(v, link)) { strlcat(s, v->val_vbuf.dv_buf, elen); strlcat(s, " ", elen); } } if (nispservers) { elen = sizeof (nispserver_str) + (INET6_ADDRSTRLEN + 1) * nispservers + 1; if ((s = envp[i++] = malloc(elen)) == NULL) { dprintf(LOG_NOTICE, FNAME, "failed to allocate strings for NIS+ servers"); ret = -1; goto clean; } memset(s, 0, elen); snprintf(s, elen, "%s=", nispserver_str); for (v = TAILQ_FIRST(&optinfo->nisp_list); v; v = TAILQ_NEXT(v, link)) { char *addr; addr = in6addr2str(&v->val_addr6, 0); strlcat(s, addr, elen); strlcat(s, " ", elen); } } if (nispnamelen) { elen = sizeof (nispname_str) + nispnamelen + 1; if ((s = envp[i++] = malloc(elen)) == NULL) { dprintf(LOG_NOTICE, FNAME, "failed to allocate strings for NIS+ domain name"); ret = -1; goto clean; } memset(s, 0, elen); snprintf(s, elen, "%s=", nispname_str); for (v = TAILQ_FIRST(&optinfo->nispname_list); v; v = TAILQ_NEXT(v, link)) { strlcat(s, v->val_vbuf.dv_buf, elen); strlcat(s, " ", elen); } } if (bcmcsservers) { elen = sizeof (bcmcsserver_str) + (INET6_ADDRSTRLEN + 1) * bcmcsservers + 1; if ((s = envp[i++] = malloc(elen)) == NULL) { dprintf(LOG_NOTICE, FNAME, "failed to allocate strings for BCMC servers"); ret = -1; goto clean; } memset(s, 0, elen); snprintf(s, elen, "%s=", bcmcsserver_str); for (v = TAILQ_FIRST(&optinfo->bcmcs_list); v; v = TAILQ_NEXT(v, link)) { char *addr; addr = in6addr2str(&v->val_addr6, 0); strlcat(s, addr, elen); strlcat(s, " ", elen); } } if (bcmcsnamelen) { elen = sizeof (bcmcsname_str) + bcmcsnamelen + 1; if ((s = envp[i++] = malloc(elen)) == NULL) { dprintf(LOG_NOTICE, FNAME, "failed to allocate strings for BCMC domain name"); ret = -1; goto clean; } memset(s, 0, elen); snprintf(s, elen, "%s=", bcmcsname_str); for (v = TAILQ_FIRST(&optinfo->bcmcsname_list); v; v = TAILQ_NEXT(v, link)) { strlcat(s, v->val_vbuf.dv_buf, elen); strlcat(s, " ", elen); } } /* launch the script */ pid = fork(); if (pid < 0) { dprintf(LOG_ERR, FNAME, "failed to fork: %s", strerror(errno)); ret = -1; goto clean; } else if (pid) { int wstatus; do { wpid = wait(&wstatus); } while (wpid != pid && wpid > 0); if (wpid < 0) dprintf(LOG_ERR, FNAME, "wait: %s", strerror(errno)); else { dprintf(LOG_DEBUG, FNAME, "script \"%s\" terminated", scriptpath); } } else { char *argv[2]; int fd; argv[0] = scriptpath; argv[1] = NULL; if (safefile(scriptpath)) { dprintf(LOG_ERR, FNAME, "script \"%s\" cannot be executed safely", scriptpath); exit(1); } if (foreground == 0 && (fd = open("/dev/null", O_RDWR)) != -1) { dup2(fd, STDIN_FILENO); dup2(fd, STDOUT_FILENO); dup2(fd, STDERR_FILENO); if (fd > STDERR_FILENO) close(fd); } execve(scriptpath, argv, envp); dprintf(LOG_ERR, FNAME, "child: exec failed: %s", strerror(errno)); exit(0); } clean: for (i = 0; i < envc; i++) free(envp[i]); free(envp); return ret; }