static int /* O - 0 if available */ /* 1 if not available */ /* -1 error */ cups_local_auth(http_t *http) /* I - HTTP connection to server */ { #if defined(WIN32) || defined(__EMX__) /* * Currently WIN32 and OS-2 do not support the CUPS server... */ return (1); #else int pid; /* Current process ID */ FILE *fp; /* Certificate file */ char trc[16], /* Try Root Certificate parameter */ filename[1024]; /* Certificate filename */ _cups_globals_t *cg = _cupsGlobals(); /* Global data */ # if defined(HAVE_AUTHORIZATION_H) OSStatus status; /* Status */ AuthorizationItem auth_right; /* Authorization right */ AuthorizationRights auth_rights; /* Authorization rights */ AuthorizationFlags auth_flags; /* Authorization flags */ AuthorizationExternalForm auth_extrn; /* Authorization ref external */ char auth_key[1024]; /* Buffer */ char buffer[1024]; /* Buffer */ # endif /* HAVE_AUTHORIZATION_H */ DEBUG_printf(("7cups_local_auth(http=%p) hostaddr=%s, hostname=\"%s\"", (void *)http, httpAddrString(http->hostaddr, filename, sizeof(filename)), http->hostname)); /* * See if we are accessing localhost... */ if (!httpAddrLocalhost(http->hostaddr) && _cups_strcasecmp(http->hostname, "localhost") != 0) { DEBUG_puts("8cups_local_auth: Not a local connection!"); return (1); } # if defined(HAVE_AUTHORIZATION_H) /* * Delete any previous authorization reference... */ if (http->auth_ref) { AuthorizationFree(http->auth_ref, kAuthorizationFlagDefaults); http->auth_ref = NULL; } if (!getenv("GATEWAY_INTERFACE") && httpGetSubField2(http, HTTP_FIELD_WWW_AUTHENTICATE, "authkey", auth_key, sizeof(auth_key))) { status = AuthorizationCreate(NULL, kAuthorizationEmptyEnvironment, kAuthorizationFlagDefaults, &http->auth_ref); if (status != errAuthorizationSuccess) { DEBUG_printf(("8cups_local_auth: AuthorizationCreate() returned %d (%s)", (int)status, cssmErrorString(status))); return (-1); } auth_right.name = auth_key; auth_right.valueLength = 0; auth_right.value = NULL; auth_right.flags = 0; auth_rights.count = 1; auth_rights.items = &auth_right; auth_flags = kAuthorizationFlagDefaults | kAuthorizationFlagPreAuthorize | kAuthorizationFlagInteractionAllowed | kAuthorizationFlagExtendRights; status = AuthorizationCopyRights(http->auth_ref, &auth_rights, kAuthorizationEmptyEnvironment, auth_flags, NULL); if (status == errAuthorizationSuccess) status = AuthorizationMakeExternalForm(http->auth_ref, &auth_extrn); if (status == errAuthorizationSuccess) { /* * Set the authorization string and return... */ httpEncode64_2(buffer, sizeof(buffer), (void *)&auth_extrn, sizeof(auth_extrn)); httpSetAuthString(http, "AuthRef", buffer); DEBUG_printf(("8cups_local_auth: Returning authstring=\"%s\"", http->authstring)); return (0); } else if (status == errAuthorizationCanceled) return (-1); DEBUG_printf(("9cups_local_auth: AuthorizationCopyRights() returned %d (%s)", (int)status, cssmErrorString(status))); /* * Fall through to try certificates... */ } # endif /* HAVE_AUTHORIZATION_H */ # if defined(SO_PEERCRED) && defined(AF_LOCAL) /* * See if we can authenticate using the peer credentials provided over a * domain socket; if so, specify "PeerCred username" as the authentication * information... */ if ( # ifdef HAVE_GSSAPI _cups_strncasecmp(http->fields[HTTP_FIELD_WWW_AUTHENTICATE], "Negotiate", 9) && # endif /* HAVE_GSSAPI */ # ifdef HAVE_AUTHORIZATION_H !httpGetSubField2(http, HTTP_FIELD_WWW_AUTHENTICATE, "authkey", auth_key, sizeof(auth_key)) && # endif /* HAVE_AUTHORIZATION_H */ http->hostaddr->addr.sa_family == AF_LOCAL && !getenv("GATEWAY_INTERFACE")) /* Not via CGI programs... */ { /* * Verify that the current cupsUser() matches the current UID... */ struct passwd *pwd; /* Password information */ const char *username; /* Current username */ username = cupsUser(); if ((pwd = getpwnam(username)) != NULL && pwd->pw_uid == getuid()) { httpSetAuthString(http, "PeerCred", username); DEBUG_printf(("8cups_local_auth: Returning authstring=\"%s\"", http->authstring)); return (0); } } # endif /* SO_PEERCRED && AF_LOCAL */ /* * Try opening a certificate file for this PID. If that fails, * try the root certificate... */ pid = getpid(); snprintf(filename, sizeof(filename), "%s/certs/%d", cg->cups_statedir, pid); if ((fp = fopen(filename, "r")) == NULL && pid > 0) { /* * No certificate for this PID; see if we can get the root certificate... */ DEBUG_printf(("9cups_local_auth: Unable to open file %s: %s", filename, strerror(errno))); # ifdef HAVE_GSSAPI if (!_cups_strncasecmp(http->fields[HTTP_FIELD_WWW_AUTHENTICATE], "Negotiate", 9)) { /* * Kerberos required, don't try the root certificate... */ return (1); } # endif /* HAVE_GSSAPI */ # ifdef HAVE_AUTHORIZATION_H if (httpGetSubField2(http, HTTP_FIELD_WWW_AUTHENTICATE, "authkey", auth_key, sizeof(auth_key))) { /* * Don't use the root certificate as a replacement for an authkey... */ return (1); } # endif /* HAVE_AUTHORIZATION_H */ if (!httpGetSubField2(http, HTTP_FIELD_WWW_AUTHENTICATE, "trc", trc, sizeof(trc))) { /* * Scheduler doesn't want us to use the root certificate... */ return (1); } snprintf(filename, sizeof(filename), "%s/certs/0", cg->cups_statedir); fp = fopen(filename, "r"); } if (fp) { /* * Read the certificate from the file... */ char certificate[33], /* Certificate string */ *certptr; /* Pointer to certificate string */ certptr = fgets(certificate, sizeof(certificate), fp); fclose(fp); if (certptr) { /* * Set the authorization string and return... */ httpSetAuthString(http, "Local", certificate); DEBUG_printf(("8cups_local_auth: Returning authstring=\"%s\"", http->authstring)); return (0); } } return (1); #endif /* WIN32 || __EMX__ */ }
/* ==================== NET_InitNetworking ==================== */ void Sys_InitNetworking(void) { // haven't been able to clearly pinpoint which standards or RFCs define SIOCGIFCONF, SIOCGIFADDR, SIOCGIFNETMASK ioctls // it seems fairly widespread, in Linux kernel ioctl, and in BSD .. so let's assume it's always available on our targets #if MACOS_X unsigned int ip, mask; struct ifaddrs *ifap, *ifp; num_interfaces = 0; if( getifaddrs( &ifap ) < 0 ) { common->FatalError( "InitNetworking: SIOCGIFCONF error - %s\n", strerror( errno ) ); return; } for( ifp = ifap; ifp; ifp = ifp->ifa_next ) { if ( !ifp->ifa_addr ) continue; if ( ifp->ifa_addr->sa_family != AF_INET ) continue; if ( !( ifp->ifa_flags & IFF_UP ) ) continue; if ( !ifp->ifa_netmask ) continue; ip = ntohl( *( unsigned long *)&ifp->ifa_addr->sa_data[2] ); mask = ntohl( *( unsigned long *)&ifp->ifa_netmask->sa_data[2] ); if ( ip == INADDR_LOOPBACK ) { common->Printf( "loopback\n" ); } else { common->Printf( "IP: %d.%d.%d.%d\n", (unsigned char)ifp->ifa_addr->sa_data[2], (unsigned char)ifp->ifa_addr->sa_data[3], (unsigned char)ifp->ifa_addr->sa_data[4], (unsigned char)ifp->ifa_addr->sa_data[5] ); common->Printf( "NetMask: %d.%d.%d.%d\n", (unsigned char)ifp->ifa_netmask->sa_data[2], (unsigned char)ifp->ifa_netmask->sa_data[3], (unsigned char)ifp->ifa_netmask->sa_data[4], (unsigned char)ifp->ifa_netmask->sa_data[5] ); } netint[ num_interfaces ].ip = ip; netint[ num_interfaces ].mask = mask; num_interfaces++; } #else int s; char buf[ MAX_INTERFACES*sizeof( ifreq ) ]; ifconf ifc; ifreq *ifr; int ifindex; unsigned int ip, mask; num_interfaces = 0; s = socket( AF_INET, SOCK_DGRAM, 0 ); ifc.ifc_len = MAX_INTERFACES*sizeof( ifreq ); ifc.ifc_buf = buf; if ( ioctl( s, SIOCGIFCONF, &ifc ) < 0 ) { common->FatalError( "InitNetworking: SIOCGIFCONF error - %s\n", strerror( errno ) ); return; } ifindex = 0; while ( ifindex < ifc.ifc_len ) { common->Printf( "found interface %s - ", ifc.ifc_buf + ifindex ); // find the type - ignore interfaces for which we can find we can't get IP and mask ( not configured ) ifr = (ifreq*)( ifc.ifc_buf + ifindex ); if ( ioctl( s, SIOCGIFADDR, ifr ) < 0 ) { common->Printf( "SIOCGIFADDR failed: %s\n", strerror( errno ) ); } else { if ( ifr->ifr_addr.sa_family != AF_INET ) { common->Printf( "not AF_INET\n" ); } else { ip = ntohl( *( unsigned long *)&ifr->ifr_addr.sa_data[2] ); if ( ip == INADDR_LOOPBACK ) { common->Printf( "loopback\n" ); } else { common->Printf( "%d.%d.%d.%d", (unsigned char)ifr->ifr_addr.sa_data[2], (unsigned char)ifr->ifr_addr.sa_data[3], (unsigned char)ifr->ifr_addr.sa_data[4], (unsigned char)ifr->ifr_addr.sa_data[5] ); } if ( ioctl( s, SIOCGIFNETMASK, ifr ) < 0 ) { common->Printf( " SIOCGIFNETMASK failed: %s\n", strerror( errno ) ); } else { mask = ntohl( *( unsigned long *)&ifr->ifr_addr.sa_data[2] ); if ( ip != INADDR_LOOPBACK ) { common->Printf( "/%d.%d.%d.%d\n", (unsigned char)ifr->ifr_addr.sa_data[2], (unsigned char)ifr->ifr_addr.sa_data[3], (unsigned char)ifr->ifr_addr.sa_data[4], (unsigned char)ifr->ifr_addr.sa_data[5] ); } netint[ num_interfaces ].ip = ip; netint[ num_interfaces ].mask = mask; num_interfaces++; } } } ifindex += sizeof( ifreq ); } #endif }
/* ================== idPort::SendPacket ================== */ void idPort::SendPacket( const netadr_t to, const void *data, int size ) { int ret; struct sockaddr_in addr; if ( to.type == NA_BAD ) { common->Warning( "idPort::SendPacket: bad address type NA_BAD - ignored" ); return; } if ( !netSocket ) { return; } NetadrToSockadr( &to, &addr ); ret = sendto( netSocket, data, size, 0, (struct sockaddr *) &addr, sizeof(addr) ); if ( ret == -1 ) { common->Printf( "idPort::SendPacket ERROR: to %s: %s\n", Sys_NetAdrToString( to ), strerror( errno ) ); } }
int main(int ac, char **av) { int lc; /* loop counter */ char *msg; /* message returned from parse_opts */ /*************************************************************** * parse standard options ***************************************************************/ if ((msg = parse_opts(ac, av, (option_t *) NULL, NULL)) != (char *)NULL) tst_brkm(TBROK, cleanup, "OPTION PARSING ERROR - %s", msg); /*************************************************************** * perform global setup for test ***************************************************************/ setup(); /* set the expected errnos... */ TEST_EXP_ENOS(exp_enos); /*************************************************************** * check looping state if -c option given ***************************************************************/ for (lc = 0; TEST_LOOPING(lc); lc++) { /* reset Tst_count in case we are looping. */ Tst_count = 0; if (mkdir(fname, 0777) == -1) { tst_brkm(TBROK, cleanup, "mkdir(%s) Failure. errno=%d : %s", fname, errno, strerror(errno)); } /* * Call rmdir(2) */ TEST(rmdir(fname)); /* check return code */ if (TEST_RETURN == -1) { TEST_ERROR_LOG(TEST_ERRNO); tst_resm(TFAIL, "rmdir(%s) Failed, errno=%d : %s", fname, TEST_ERRNO, strerror(TEST_ERRNO)); } else { /*************************************************************** * only perform functional verification if flag set (-f not given) ***************************************************************/ if (STD_FUNCTIONAL_TEST) { /* No Verification test, yet... */ tst_resm(TPASS, "rmdir(%s) returned %ld", fname, TEST_RETURN); } } } /* End for TEST_LOOPING */ /*************************************************************** * cleanup and exit ***************************************************************/ cleanup(); return 0; } /* End main */
static int eventer_ports_impl_loop() { struct timeval __dyna_sleep = { 0, 0 }; struct ports_spec *spec; spec = eventer_get_spec_for_event(NULL); while(1) { struct timeval __now, __sleeptime; struct timespec __ports_sleeptime; unsigned int fd_cnt = 0; int ret; port_event_t pevents[MAX_PORT_EVENTS]; mtev_gettimeofday(&__now, NULL); if(compare_timeval(eventer_max_sleeptime, __dyna_sleep) < 0) __dyna_sleep = eventer_max_sleeptime; __sleeptime = __dyna_sleep; eventer_dispatch_timed(&__now, &__sleeptime); if(compare_timeval(__sleeptime, __dyna_sleep) > 0) __sleeptime = __dyna_sleep; /* Handle cross_thread dispatches */ eventer_cross_thread_process(); /* Handle recurrent events */ eventer_dispatch_recurrent(&__now); /* Now we move on to our fd-based events */ __ports_sleeptime.tv_sec = __sleeptime.tv_sec; __ports_sleeptime.tv_nsec = __sleeptime.tv_usec * 1000; fd_cnt = 1; pevents[0].portev_source = 65535; /* This is impossible */ ret = port_getn(spec->port_fd, pevents, MAX_PORT_EVENTS, &fd_cnt, &__ports_sleeptime); spec->wakeup_notify = 0; /* force unlock */ /* The timeout case is a tad complex with ports. -1/ETIME is clearly * a timeout. However, it i spossible that we got that and fd_cnt isn't * 0, which means we both timed out and got events... WTF? */ if(fd_cnt == 0 || (ret == -1 && errno == ETIME && pevents[0].portev_source == 65535)) add_timeval(__dyna_sleep, __dyna_increment, &__dyna_sleep); if(ret == -1 && (errno != ETIME && errno != EINTR)) mtevLT(eventer_err, &__now, "port_getn: %s\n", strerror(errno)); if(ret < 0) mtevLT(eventer_deb, &__now, "port_getn: %s\n", strerror(errno)); mtevLT(eventer_deb, &__now, "debug: port_getn(%d, [], %d) => %d\n", spec->port_fd, fd_cnt, ret); if(pevents[0].portev_source == 65535) { /* the impossible still remains, which means our fd_cnt _must_ be 0 */ fd_cnt = 0; } if(fd_cnt > 0) { int idx; /* Loop a last time to process */ __dyna_sleep.tv_sec = __dyna_sleep.tv_usec = 0; /* reset */ for(idx = 0; idx < fd_cnt; idx++) { port_event_t *pe; eventer_t e; int fd, mask; pe = &pevents[idx]; if(pe->portev_source != PORT_SOURCE_FD) continue; fd = (int)pe->portev_object; mtevAssert((vpsized_int)pe->portev_user == fd); e = master_fds[fd].e; /* It's possible that someone removed the event and freed it * before we got here.... bail out if we're null. */ if (!e) continue; mask = 0; if(pe->portev_events & (POLLIN | POLLHUP)) mask |= EVENTER_READ; if(pe->portev_events & (POLLOUT)) mask |= EVENTER_WRITE; if(pe->portev_events & (POLLERR | POLLHUP | POLLNVAL)) mask |= EVENTER_EXCEPTION; eventer_ports_impl_trigger(e, mask); } } } /* NOTREACHED */ return 0; }
void SocketTransport::waitForConnection( std::vector<int>& socketFds, int abortFd ) { // Wait for a connection on any of the fds we are listening to. We allow only // one debugger client to connect a a time, so once any bound fd accepts a // connection, we stop listening on all the others. int count = socketFds.size() + 1; size_t size = sizeof(struct pollfd) * count; struct pollfd* fds = (struct pollfd*)malloc(size); if (fds == nullptr) { VSDebugLogger::Log( VSDebugLogger::LogLevelError, "SocketTransport out of memory while trying to create pollfd." ); return; } memset(fds, 0, size); SCOPE_EXIT { if (fds != nullptr) { free(fds); } }; // fds[0] will contain the read end of our "abort" pipe. Another thread will // write data to tihs pipe to signal it's time for this worker to stop // blocking in poll() and terminate. int eventMask = POLLIN | POLLERR | POLLHUP; fds[0].fd = abortFd; fds[0].events = eventMask; for (unsigned int i = 1; i < count; i++) { fds[i].fd = socketFds[i - 1]; fds[i].events = eventMask; } // Poll socket fds until a connection is established or we're terminated. while (true) { VSDebugLogger::Log( VSDebugLogger::LogLevelInfo, "SocketTransport polling for connections..." ); int ret = poll(fds, count, -1); if (ret < 0) { if (ret == -EINTR) { continue; } VSDebugLogger::Log( VSDebugLogger::LogLevelError, "Polling inputs failed: %d. (%s)", errno, strerror(errno) ); return; } if (fds[0].revents != 0) { VSDebugLogger::Log( VSDebugLogger::LogLevelInfo, "Socket polling thread terminating due to shutdown request." ); return; } struct sockaddr sa; socklen_t len = sizeof(sa); for (unsigned int i = 1; i < count; i++) { if (fds[i].revents & POLLIN) { int newFd = ::accept(fds[i].fd, &sa, &len); if (newFd < 0) { VSDebugLogger::Log( VSDebugLogger::LogLevelWarning, "Accept returned an error: %d. (%s)", errno, strerror(errno) ); } else { Lock lock(m_lock); if (m_clientConnected) { // A client is already connected! m_lock.unlock(); rejectClientWithMsg(newFd, abortFd); m_lock.lock(); } else { VSDebugLogger::Log( VSDebugLogger::LogLevelInfo, "SocketTransport: new client connection accepted." ); // We have established a connection with a client. m_clientConnected = true; setTransportFd(newFd); m_debugger->setClientConnected(true); } } } // Reset the event flags. fds[i].revents = 0; } } }
void copylink(char *source, char *dest, int mode, int owner, int group) { struct stat sst, dst; int sfd, dfd, n; int r, same= 0, change= 0, docopy= 1; char buf[4096]; # define hdr ((struct exec *) buf) pid_t pid; int status; /* Source must exist as a plain file, dest may exist as a plain file. */ if (stat(source, &sst) < 0) { report(source); return; } if (mode == -1) { mode= sst.st_mode & 07777; if (!lflag || cflag) { mode|= 0444; if (mode & 0111) mode|= 0111; } } if (owner == -1) owner= sst.st_uid; if (group == -1) group= sst.st_gid; if (!S_ISREG(sst.st_mode)) { fprintf(stderr, "install: %s is not a regular file\n", source); excode= 1; return; } r= stat(dest, &dst); if (r < 0) { if (errno != ENOENT) { report(dest); return; } } else { if (!S_ISREG(dst.st_mode)) { fprintf(stderr, "install: %s is not a regular file\n", dest); excode= 1; return; } /* Are the files the same? */ if (sst.st_dev == dst.st_dev && sst.st_ino == dst.st_ino) { if (!lflag && cflag) { fprintf(stderr, "install: %s and %s are the same, can't copy\n", source, dest); excode= 1; return; } same= 1; } } if (lflag && !same) { /* Try to link the files. */ if (r >= 0 && unlink(dest) < 0) { report(dest); return; } if (link(source, dest) >= 0) { docopy= 0; } else { if (!cflag || errno != EXDEV) { fprintf(stderr, "install: can't link %s to %s: %s\n", source, dest, strerror(errno)); excode= 1; return; } } } if (docopy && !same) { /* Copy the files, stripping if necessary. */ long count= LONG_MAX; int first= 1; if ((sfd= open(source, O_RDONLY)) < 0) { report(source); return; } /* Open for write is less simple, its mode may be 444. */ dfd= open(dest, O_WRONLY|O_CREAT|O_TRUNC, mode | 0600); if (dfd < 0 && errno == EACCES) { (void) chmod(dest, mode | 0600); dfd= open(dest, O_WRONLY|O_TRUNC); } if (dfd < 0) { report(dest); close(sfd); return; } pid= 0; while (count > 0 && (n= read(sfd, buf, sizeof(buf))) > 0) { if (first && n >= A_MINHDR && !BADMAG(*hdr)) { if (strip) { count= hdr->a_hdrlen + hdr->a_text + hdr->a_data; #ifdef A_NSYM hdr->a_flags &= ~A_NSYM; #endif hdr->a_syms= 0; } if (stack != -1 && setstack(hdr)) change= 1; if (compress != nil) { /* Write first #! line. */ (void) write(dfd, zcat, strlen(zcat)); /* Put a compressor in between. */ if ((pid= filter(dfd, compress)) < 0) { close(sfd); close(dfd); return; } change= 1; } } if (count < n) n= count; if (write(dfd, buf, n) < 0) { report(dest); close(sfd); close(dfd); if (pid != 0) (void) waitpid(pid, nil, 0); return; } count-= n; first= 0; } if (n < 0) report(source); close(sfd); close(dfd); if (pid != 0 && waitpid(pid, &status, 0) < 0 || status != 0) { excode= 1; return; } if (n < 0) return; } else { if (stack != -1) { /* The file has been linked into place. Set the * stack size. */ if ((dfd= open(dest, O_RDWR)) < 0) { report(dest); return; } if ((n= read(dfd, buf, sizeof(*hdr))) < 0) { report(dest); return; } if (n >= A_MINHDR && !BADMAG(*hdr) && setstack(hdr)) { if (lseek(dfd, (off_t) 0, SEEK_SET) == -1 || write(dfd, buf, n) < 0 ) { report(dest); close(dfd); return; } change= 1; } close(dfd); } } if (stat(dest, &dst) < 0) { report(dest); return; } if ((dst.st_mode & 07777) != mode) { if (chmod(dest, mode) < 0) { report(dest); return; } } if (dst.st_uid != owner || dst.st_gid != group) { if (chown(dest, owner, group) < 0 && errno != EPERM) { report(dest); return; } /* Set the mode again, chown may have wrecked it. */ (void) chmod(dest, mode); } if (!change) { struct utimbuf ubuf; ubuf.actime= dst.st_atime; ubuf.modtime= sst.st_mtime; if (utime(dest, &ubuf) < 0 && errno != EPERM) { report(dest); return; } } }
int main(int argc, char *argv[]) { if (getpid() == 1) { if (open("/dev/tty0", O_RDWR) != 0) return 1; if (dup(0) != 1) return 1; if (dup(1) != 2) return 1; setenv("PATH", "/usr/local/bin:/usr/bin:/bin", 1); setenv("HOME", "/root", 1); setenv("LD_LIBRARY_PATH", "/usr/local/lib:/usr/lib:/lib", 1); struct sigaction sa; memset(&sa, 0, sizeof(struct sigaction)); sa.sa_sigaction = on_signal; sigemptyset(&sa.sa_mask); sa.sa_flags = SA_SIGINFO; if (sigaction(SIGINT, &sa, NULL) != 0) { perror("sigaction SIGINT"); return 1; }; if (sigaction(SIGCHLD, &sa, NULL) != 0) { perror("sigaction SIGCHLD"); return 1; }; if (sigaction(SIGTERM, &sa, NULL) != 0) { perror("sigaction SIGTERM"); return 1; }; if (sigaction(SIGHUP, &sa, NULL) != 0) // SIGHUP is sent when the power button is pressed { perror("sigaction SIGHUP"); return 1; }; if (mkdir("/sem", 01777) != 0) { perror("mkdir /run/sem"); return 1; }; loadmods(); printf("init: initializing partitions...\n"); init_parts(); printf("init: looking for root filesystem...\n"); if (try_mount_root() != 0) { printf("init: failed to find the root filesystem!\n"); return 1; }; printf("init: setting up second-level filesystem...\n"); if (mount("bind", "/dev", "/rootfs/dev", 0, NULL, 0) != 0) { perror("init: bind /dev"); return 1; }; if (mount("bind", "/proc", "/rootfs/proc", 0, NULL, 0) != 0) { perror("init: bind /proc"); return 1; }; if (mount("bind", "/initrd", "/rootfs/initrd", 0, NULL, 0) != 0) { perror("init: bind /initrd"); return 1; }; if (mount("bind", "/run", "/rootfs/run", 0, NULL, 0) != 0) { perror("init: bind /run"); return 1; }; if (mount("bind", "/run", "/rootfs/var/run", 0, NULL, 0) != 0) { perror("init: bind /var/run"); return 1; }; printf("init: setting up fsinfo...\n"); int fd = open("/run/fsinfo", O_WRONLY | O_CREAT | O_EXCL, 0644); if (fd == -1) { perror("init: open /run/fsinfo"); return 1; }; struct __fsinfo_record record; memset(&record, 0, sizeof(struct __fsinfo_record)); strcpy(record.__image, rootImage); strcpy(record.__mntpoint, "/"); write(fd, &record, sizeof(struct __fsinfo_record)); strcpy(record.__image, "none"); strcpy(record.__mntpoint, "/dev"); write(fd, &record, sizeof(struct __fsinfo_record)); strcpy(record.__mntpoint, "/proc"); write(fd, &record, sizeof(struct __fsinfo_record)); strcpy(record.__mntpoint, "/initrd"); write(fd, &record, sizeof(struct __fsinfo_record)); strcpy(record.__mntpoint, "/run"); write(fd, &record, sizeof(struct __fsinfo_record)); strcpy(record.__mntpoint, "/var/run"); write(fd, &record, sizeof(struct __fsinfo_record)); close(fd); printf("init: executing startup script...\n"); if (fork() == 0) { if (chdir("/rootfs") != 0) { fprintf(stderr, "init: cannot switch to /rootfs: %s\n", strerror(errno)); _exit(1); }; if (chroot("/rootfs") != 0) { fprintf(stderr, "init: failed to set root directory to /rootfs: %s\n", strerror(errno)); _exit(1); }; execl("/bin/sh", "/bin/sh", "/etc/init/startup.sh", NULL); perror("init: exec"); _exit(1); }; while (1) { pause(); if (shouldHalt) { tcsetpgrp(0, getpgrp()); printf("init: received shutdown request\n"); int fd = open("/run/down-action", O_RDONLY); char downAction[256]; memset(downAction, 0, 256); downAction[read(fd, downAction, 16)] = 0; close(fd); int action = _GLIDIX_DOWN_HALT; if (strcmp(downAction, "poweroff") == 0) { action = _GLIDIX_DOWN_POWEROFF; } else if (strcmp(downAction, "reboot") == 0) { action = _GLIDIX_DOWN_REBOOT; }; shutdownSystem(action); } else if ((shouldRunPoweroff) && (!ranPoweroff)) { ranPoweroff = 1; if (fork() == 0) { if (execl("/usr/bin/halt", "poweroff", NULL) == -1) { perror("exec poweroff"); fprintf(stderr, "forcing shutdown\n"); kill(1, SIGTERM); exit(1); }; }; }; }; } else { fprintf(stderr, "%s: not allowed to execute with pid other than 1!\n", argv[0]); return 1; }; return 0; };
int main(int argc, char** argv, char** envp) { int i, j, loglevel; const char *toolname = NULL; const char *clientname = NULL; int clientname_arg = 0; const char *archname = NULL; const char *arch; const char *default_arch; cpu_type_t default_cputype; char *toolfile; char launcher_name[PATH_MAX+1]; char* new_line; char* set_cwd; char* cwd; char** new_env; char **new_argv; int new_argc; /* Start the debugging-log system ASAP. First find out how many "-d"s were specified. This is a pre-scan of the command line. At the same time, look for the tool name. */ loglevel = 0; for (i = 1; i < argc; i++) { if (argv[i][0] != '-') { clientname = argv[i]; clientname_arg = i; break; } if (0 == strcmp(argv[i], "--")) { if (i+1 < argc) { clientname = argv[i+1]; clientname_arg = i; } break; } if (0 == strcmp(argv[i], "-d")) loglevel++; if (0 == strncmp(argv[i], "--tool=", 7)) toolname = argv[i] + 7; if (0 == strncmp(argv[i], "--arch=", 7)) archname = argv[i] + 7; } /* ... and start the debug logger. Now we can safely emit logging messages all through startup. */ VG_(debugLog_startup)(loglevel, "Stage 1"); /* Make sure we know which tool we're using */ if (toolname) { VG_(debugLog)(1, "launcher", "tool '%s' requested\n", toolname); } else { VG_(debugLog)(1, "launcher", "no tool requested, defaulting to 'memcheck'\n"); toolname = "memcheck"; } /* Find the real executable if clientname is an app bundle. */ if (clientname) { struct stat st; if (0 == stat(clientname, &st) && (st.st_mode & S_IFDIR)) { char *copy = strdup(clientname); char *appname = basename(copy); char *dot = strrchr(appname, '.'); if (dot) { char *newclient; *dot = '\0'; asprintf(&newclient, "%s/Contents/MacOS/%s", clientname, appname); VG_(debugLog)(1, "launcher", "Using executable in app bundle: %s\n", newclient); clientname = newclient; argv[clientname_arg] = newclient; } free(copy); } } /* Establish the correct VALGRIND_LIB. */ { const char *cp; cp = getenv(VALGRIND_LIB); valgrind_lib = ( cp == NULL ? VG_LIBDIR : cp ); VG_(debugLog)(1, "launcher", "valgrind_lib = %s\n", valgrind_lib); } /* Find installed architectures. Use vgpreload_core-<platform>.so as the * indicator of whether the platform is installed. */ for (i = 0; i < valid_archs_count; i++) { char *vgpreload_core; asprintf(&vgpreload_core, "%s/vgpreload_core-%s-darwin.so", valgrind_lib, valid_archs[i].valgrind_name); if (access(vgpreload_core, R_OK|X_OK) != 0) { VG_(debugLog)(1, "launcher", "arch '%s' IS NOT installed\n", valid_archs[i].valgrind_name); bzero(&valid_archs[i], sizeof(valid_archs[i])); } else { VG_(debugLog)(1, "launcher", "arch '%s' IS installed\n", valid_archs[i].valgrind_name); } free(vgpreload_core); } /* Find the "default" arch (VGCONF_ARCH_PRI from configure). This is the preferred arch from fat files and the fallback. */ default_arch = NULL; default_cputype = 0; for (i = 0; i < valid_archs_count; i++) { if (!valid_archs[i].cputype) continue; if (0 == strncmp(VG_PLATFORM, valid_archs[i].valgrind_name, strlen(valid_archs[i].valgrind_name))) { default_arch = valid_archs[i].valgrind_name; default_cputype = valid_archs[i].cputype; break; } } if (i == valid_archs_count) barf("Unknown/uninstalled VG_PLATFORM '%s'", VG_PLATFORM); assert(NULL != default_arch); assert(0 != default_cputype); /* Work out what arch to use, or use the default arch if not possible. */ if (archname != NULL) { // --arch from command line arch = NULL; for (i = 0; i < valid_archs_count; i++) { if (0 == strcmp(archname, valid_archs[i].apple_name) || 0 == strcmp(archname, valid_archs[i].valgrind_name)) { arch = valid_archs[i].valgrind_name; break; } } if (i == valid_archs_count) barf("Unknown --arch '%s'", archname); assert(NULL != arch); VG_(debugLog)(1, "launcher", "using arch '%s' from --arch=%s\n", arch, archname); } else if (clientname == NULL) { // no client executable; use default as fallback VG_(debugLog)(1, "launcher", "no client specified, defaulting arch to '%s'\n", default_arch); arch = default_arch; } else if ((arch = select_arch(clientname, default_cputype,default_arch))) { // arch from client executable VG_(debugLog)(1, "launcher", "selected arch '%s'\n", arch); } else { // nothing found in client executable; use default as fallback VG_(debugLog)(1, "launcher", "no arch detected, defaulting arch to '%s'\n", default_arch); arch = default_arch; } cwd = getcwd(NULL, 0); if (!cwd) barf("Current directory no longer exists."); /* Figure out the name of this executable (viz, the launcher), so we can tell stage2. stage2 will use the name for recursive invokations of valgrind on child processes. */ memset(launcher_name, 0, PATH_MAX+1); for (i = 0; envp[i]; i++) ; /* executable path is after last envp item */ /* envp[i] == NULL ; envp[i+1] == executable_path */ if (envp[i+1][0] != '/') { strcpy(launcher_name, cwd); strcat(launcher_name, "/"); } if (strlen(launcher_name) + strlen(envp[i+1]) > PATH_MAX) barf("launcher path is too long"); strcat(launcher_name, envp[i+1]); VG_(debugLog)(1, "launcher", "launcher_name = %s\n", launcher_name); /* tediously augment the env: VALGRIND_LAUNCHER=launcher_name */ asprintf(&new_line, VALGRIND_LAUNCHER "=%s", launcher_name); /* tediously augment the env: VALGRIND_STARTUP_PWD_%PID_XYZZY=current_working_dir */ asprintf(&set_cwd, "VALGRIND_STARTUP_PWD_%u_XYZZY=%s", getppid(), cwd); // Note that Apple binaries get a secret fourth arg, "char* apple", which // contains the executable path. Don't forget about it. for (j = 0; envp[j]; j++) ; new_env = malloc((j+4) * sizeof(char*)); if (new_env == NULL) barf("malloc of new_env failed."); for (i = 0; i < j; i++) new_env[i] = envp[i]; new_env[i++] = new_line; new_env[i++] = set_cwd; new_env[i++] = NULL; new_env[i ] = envp[i-2]; // the 'apple' arg == the executable_path assert(i == j+3); /* tediously edit env: hide dyld options from valgrind's captive dyld */ for (i = 0; envp[i]; i++) { if (0 == strncmp(envp[i], "DYLD_", 5)) { envp[i][0] = 'V'; /* VYLD_; changed back by initimg-darwin */ } } /* tediously edit argv: remove --arch= */ new_argv = malloc((1+argc) * sizeof(char *)); for (i = 0, new_argc = 0; i < argc; i++) { if (0 == strncmp(argv[i], "--arch=", 7)) { // skip } else { new_argv[new_argc++] = argv[i]; } } new_argv[new_argc++] = NULL; /* Build the stage2 invokation, and execve it. Bye! */ asprintf(&toolfile, "%s/%s-%s-darwin", valgrind_lib, toolname, arch); if (access(toolfile, R_OK|X_OK) != 0) { barf("tool '%s' not installed (%s) (%s)", toolname, toolfile, strerror(errno)); } VG_(debugLog)(1, "launcher", "launching %s\n", toolfile); execve(toolfile, new_argv, new_env); fprintf(stderr, "valgrind: failed to start tool '%s' for platform '%s-darwin': %s\n", toolname, arch, strerror(errno)); exit(1); }
void shutdownSystem(int action) { struct sigaction sa; memset(&sa, 0, sizeof(struct sigaction)); sa.sa_handler = SIG_IGN; sigaction(SIGCHLD, &sa, NULL); sigaction(SIGINT, &sa, NULL); sigaction(SIGTERM, &sa, NULL); sigaction(SIGHUP, &sa, NULL); sa.sa_flags = SA_SIGINFO; sa.sa_sigaction = onShutdownAlarm; sigaction(SIGALRM, &sa, NULL); printf("init: asking remaining processes to terminate...\n"); while (killNextProcess() == 0); printf("init: closing my remaining files...\n"); int fd; for (fd=3; fd<sysconf(_SC_OPEN_MAX); fd++) { close(fd); }; printf("init: unmounting filesystems...\n"); struct fsinfo currentFSList[256]; chdir("/"); chroot("rootfs"); size_t count = _glidix_fsinfo(currentFSList, 256); chroot("."); int i; for (i=count-1; i>=0; i--) { char actual_mntpoint[512]; sprintf(actual_mntpoint, "/rootfs/%s", currentFSList[i].fs_mntpoint); printf("init: unmount %s\n", actual_mntpoint); if (unmount(actual_mntpoint, 0) != 0) { printf("init: failed to unmount %s: %s\n", currentFSList[i].fs_mntpoint, strerror(errno)); printf("init: waiting 5 seconds and skipping this filesystem\n"); sleep(5); }; }; printf("init: removing all kernel modules...\n"); struct modstat ms; for (i=0; i<512; i++) { if (modstat(i, &ms) == 0) { if (rmmod(ms.mod_name, 0) != 0) { printf("init: failed to rmmod %s: %s\n", ms.mod_name, strerror(errno)); printf("Report this problem to the module developer.\n"); printf("I will now hang, you may turn off power manually.\n"); printf("If the problem persists, remove the module for your safety.\n"); while (1) pause(); }; }; }; printf("init: bringing the system down...\n"); _glidix_down(action); };
int try_mount_root() { // create the /rootfs directory if (mkdir("/rootfs", 0755) != 0) { fprintf(stderr, "init: failed to create /rootfs: %s\n", strerror(errno)); return -1; }; // get the list of devices size_t numDevs = 0; DIR *dirp = opendir("/dev"); if (dirp == NULL) { fprintf(stderr, "init: failed to scan /dev: %s\n", strerror(errno)); return -1; }; struct dirent *ent; while ((ent = readdir(dirp)) != NULL) { if (memcmp(ent->d_name, "sd", 2) == 0) { char *devname = (char*) malloc(strlen(ent->d_name) + strlen("/dev/") + 1); sprintf(devname, "/dev/%s", ent->d_name); devList = (char**) realloc(devList, sizeof(char*) * (numDevs+1)); devList[numDevs++] = devname; printf("init: detected candidate storage device: %s\n", devname); }; }; devList = (char**) realloc(devList, sizeof(char*) * (numDevs+1)); devList[numDevs] = NULL; closedir(dirp); char names[256*16]; int drvcount = (int) __syscall(__SYS_fsdrv, names, 256); if (drvcount == -1) { fprintf(stderr, "init: cannot get filesystem driver list: %s\n", strerror(errno)); return 1; }; struct system_state sst; if (__syscall(__SYS_systat, &sst, sizeof(struct system_state)) != 0) { fprintf(stderr, "init: failed to get system state: %s\n", strerror(errno)); }; char idbuf[33]; id_to_string(idbuf, sst.sst_bootid); printf("init: kernel boot ID is %s\n", idbuf); const char *scan = names; while (drvcount--) { const char *fstype = scan; scan += 16; if (try_mount_root_with_type(fstype, sst.sst_bootid) == 0) return 0; }; return -1; };
/** * Find a process to kill (during shutdown), kill it and return 0. If no more processes need to be killed, * returns -1. */ int killNextProcess() { DIR *dirp = opendir("/proc"); if (dirp == NULL) { printf("init: critical error: failed to open /proc: %s\n", strerror(errno)); printf("WARNING: waiting 5 seconds and skipping process termination!\n"); sleep(5); return -1; }; struct stat st; struct dirent *ent; while ((ent = readdir(dirp)) != NULL) { if (ent->d_name[0] == '.') { continue; } else if (strcmp(ent->d_name, "self") == 0) { continue; } else if (strcmp(ent->d_name, "1") == 0) { continue; } else { // kill it only if it's our child right now char parentPath[256]; char exePath[256]; char procName[256]; char parentLink[256]; sprintf(parentPath, "/proc/%s/parent", ent->d_name); sprintf(exePath, "/proc/%s/exe", ent->d_name); procName[readlink(exePath, procName, 256)] = 0; int iAmParent = 0; if (stat(parentPath, &st) != 0) { // if the 'parent' link is broken, it means 'init' is indeed the parent iAmParent = 1; } else { parentLink[readlink(parentPath, parentLink, 256)] = 0; if (strcmp(parentLink, "../1") == 0) { iAmParent = 1; }; }; if (iAmParent) { int pid; sscanf(ent->d_name, "%d", &pid); kill(pid, SIGTERM); alarm(10); int status = waitpid(pid, NULL, 0); int errnum = errno; alarm(0); if (status == -1) { if (errnum == EINTR) { printf("init: process %d ('%s') failed to terminate in 10 seconds; killing\n", pid, procName); kill(pid, SIGKILL); if (waitpid(pid, NULL, 0) == -1) { printf("init: waitpid unexpectedly failed on %d: %s\n", pid, strerror(errno)); printf("init: assuming process terminated\n"); continue; }; } else { printf("init: waitpid unexpectedly failed on %d: %s\n", pid, strerror(errnum)); printf("init: assuming process terminated\n"); continue; }; }; // we terminated a process successfully closedir(dirp); return 0; }; }; }; closedir(dirp); return -1; };
static void socket_destructor(struct object *obj) { struct socketinfo *si = &obj->sockinfo; struct linger ling = { .l_onoff = FALSE, .l_linger = 0 }; int fd; //FIXME: This is a workaround for a weird bug where we hang forevre // waiting for bluetooth sockets when we setsockopt. // Hopefully at some point we can remove this when someone figures out what's going on. if (si->triplet.family == PF_BLUETOOTH) return; /* Grab an fd, and nuke it before someone else uses it. */ fd = si->fd; si->fd = 0; /* disable linger */ (void) setsockopt(fd, SOL_SOCKET, SO_LINGER, &ling, sizeof(struct linger)); (void) shutdown(fd, SHUT_RDWR); if (close(fd) != 0) output(1, "failed to close socket [%d:%d:%d].(%s)\n", si->triplet.family, si->triplet.type, si->triplet.protocol, strerror(errno)); } static void socket_dump(struct object *obj, bool global) { struct socketinfo *si = &obj->sockinfo; struct msg_objcreatedsocket objmsg; output(2, "socket fd:%d domain:%u (%s) type:0x%u protocol:%u\n", si->fd, si->triplet.family, get_domain_name(si->triplet.family), si->triplet.type, si->triplet.protocol); init_msgobjhdr(&objmsg.hdr, OBJ_CREATED_SOCKET, global, obj); objmsg.si.fd = si->fd; objmsg.si.triplet.family = si->triplet.family; objmsg.si.triplet.type = si->triplet.type; objmsg.si.triplet.protocol = si->triplet.protocol; sendudp((char *) &objmsg, sizeof(objmsg)); } static int open_sockets(void) { struct objhead *head; int bytesread = -1; int ret; head = get_objhead(OBJ_GLOBAL, OBJ_FD_SOCKET); head->destroy = &socket_destructor; head->dump = &socket_dump; cachefile = open(cachefilename, O_RDONLY); if (cachefile < 0) { output(1, "Couldn't find socket cachefile. Regenerating.\n"); ret = generate_sockets(); output(1, "created %d sockets\n", nr_sockets); return ret; } lock_cachefile(F_RDLCK); while (bytesread != 0) { unsigned int domain, type, protocol; unsigned int buffer[3]; int fd; bytesread = read(cachefile, buffer, sizeof(int) * 3); if (bytesread == 0) { if (nr_sockets == 0) goto regenerate; break; } domain = buffer[0]; type = buffer[1]; protocol = buffer[2]; if (domain >= TRINITY_PF_MAX) { output(1, "cachefile contained invalid domain %u\n", domain); goto regenerate; } if ((do_specific_domain == TRUE && domain != specific_domain) || (no_domains[domain] == TRUE)) { output(1, "ignoring socket cachefile due to specific " "protocol request (or protocol disabled), " "and stale data in cachefile.\n"); regenerate: unlock_cachefile(); /* drop the reader lock. */ close(cachefile); unlink(cachefilename); ret = generate_sockets(); return ret; } fd = open_socket(domain, type, protocol); if (fd < 0) { output(1, "Cachefile is stale. Need to regenerate.\n"); goto regenerate; } /* check for ctrl-c */ if (shm->exit_reason != STILL_RUNNING) { close(cachefile); return FALSE; } } output(1, "%d sockets created based on info from socket cachefile.\n", nr_sockets); unlock_cachefile(); close(cachefile); return TRUE; } struct socketinfo * get_rand_socketinfo(void) { struct object *obj; /* When using victim files, sockets can be 0. */ if (objects_empty(OBJ_FD_SOCKET) == TRUE) return NULL; obj = get_random_object(OBJ_FD_SOCKET, OBJ_GLOBAL); return &obj->sockinfo; } static int get_rand_socket_fd(void) { struct socketinfo *sockinfo; sockinfo = get_rand_socketinfo(); if (sockinfo == NULL) return -1; return sockinfo->fd; } int fd_from_socketinfo(struct socketinfo *si) { if (si != NULL) { if (!(ONE_IN(1000))) return si->fd; } return get_random_fd(); } static const struct fd_provider socket_fd_provider = { .name = "sockets", .enabled = TRUE, .open = &open_sockets, .get = &get_rand_socket_fd, }; REG_FD_PROV(socket_fd_provider);
static void lock_cachefile(int type) { struct flock fl = { .l_len = 0, .l_start = 0, .l_whence = SEEK_SET, }; fl.l_pid = getpid(); fl.l_type = type; if (verbose) output(2, "waiting on lock for cachefile\n"); if (fcntl(cachefile, F_SETLKW, &fl) == -1) { perror("fcntl F_SETLKW"); return; } if (verbose) output(2, "took lock for cachefile\n"); } static void unlock_cachefile(void) { struct flock fl = { .l_len = 0, .l_start = 0, .l_whence = SEEK_SET, }; fl.l_pid = getpid(); fl.l_type = F_UNLCK; if (fcntl(cachefile, F_SETLK, &fl) == -1) { perror("fcntl F_UNLCK F_SETLK "); return; } if (verbose) output(2, "dropped lock for cachefile\n"); } static unsigned int valid_proto(unsigned int family) { const char *famstr; famstr = get_domain_name(family); /* Not used for creating sockets. */ if (strncmp(famstr, "UNSPEC", 9) == 0) return FALSE; if (strncmp(famstr, "BRIDGE", 9) == 0) return FALSE; if (strncmp(famstr, "SECURITY", 11) == 0) return FALSE; /* Not actually implemented (or now removed). */ if (strncmp(famstr, "NETBEUI", 10) == 0) return FALSE; if (strncmp(famstr, "ASH", 6) == 0) return FALSE; if (strncmp(famstr, "ECONET", 9) == 0) return FALSE; if (strncmp(famstr, "SNA", 6) == 0) return FALSE; if (strncmp(famstr, "WANPIPE", 10) == 0) return FALSE; /* Needs root. */ if (orig_uid != 0) { if (strncmp(famstr, "KEY", 6) == 0) return FALSE; if (strncmp(famstr, "PACKET", 9) == 0) return FALSE; if (strncmp(famstr, "LLC", 6) == 0) return FALSE; } return TRUE; } static bool write_socket_to_cache(struct socket_triplet *st) { unsigned int buffer[3]; int n; if (cachefile == -1) return FALSE; buffer[0] = st->family; buffer[1] = st->type; buffer[2] = st->protocol; n = write(cachefile, &buffer, sizeof(int) * 3); if (n == -1) { outputerr("something went wrong writing the cachefile! : %s\n", strerror(errno)); return FALSE; } return TRUE; } static bool generate_socket(unsigned int family, unsigned int protocol, unsigned int type) { struct socket_triplet st; int fd; st.family = family; st.type = type; st.protocol = protocol; fd = open_socket(st.family, st.type, st.protocol); if (fd > -1) { write_socket_to_cache(&st); return TRUE; } output(2, "Couldn't open socket %d:%d:%d. %s\n", family, type, protocol, strerror(errno)); return FALSE; } static bool generate_specific_socket(int family) { struct socket_triplet st; int fd; st.family = family; BUG_ON(st.family >= ARRAY_SIZE(no_domains)); if (no_domains[st.family]) return FALSE; if (get_domain_name(st.family) == NULL) return FALSE; if (valid_proto(st.family) == FALSE) { outputerr("Can't do protocol %s\n", get_domain_name(st.family)); return FALSE; } st.protocol = rnd() % 256; if (sanitise_socket_triplet(&st) == -1) rand_proto_type(&st); fd = open_socket(st.family, st.type, st.protocol); if (fd == -1) { output(0, "Couldn't open socket (%d:%d:%d). %s\n", st.family, st.type, st.protocol, strerror(errno)); return FALSE; } return write_socket_to_cache(&st); } #define NR_SOCKET_FDS 50 static bool generate_sockets(void) { int i, r, ret = FALSE; bool domains_disabled = FALSE; cachefile = creat(cachefilename, S_IWUSR|S_IRUSR); if (cachefile == -1) { outputerr("Couldn't open cachefile for writing! (%s)\n", strerror(errno)); return FALSE; } lock_cachefile(F_WRLCK); if (do_specific_domain == TRUE) { while (nr_sockets < NR_SOCKET_FDS) { ret = generate_specific_socket(specific_domain); if (ret == FALSE) return FALSE; } goto out_unlock; } /* * check if all domains are disabled. */ for (i = 0; i < (int)ARRAY_SIZE(no_domains); i++) { if (no_domains[i] == FALSE) { domains_disabled = FALSE; break; } else { domains_disabled = TRUE; } } if (domains_disabled == TRUE) { output(0, "All domains disabled!\n"); goto out_unlock; } for (i = 0; i < TRINITY_PF_MAX; i++) { const struct netproto *proto = net_protocols[i].proto; struct socket_triplet *triplets; unsigned int j; if (no_domains[i] == TRUE) continue; /* check for ctrl-c again. */ if (shm->exit_reason != STILL_RUNNING) goto out_unlock; if (proto == NULL) continue; if (proto->nr_triplets == 0) continue; triplets = proto->valid_triplets; for (j = 0; j < proto->nr_triplets; j++) ret |= generate_socket(triplets[j].family, triplets[j].protocol, triplets[j].type); if (proto->nr_privileged_triplets == 0) continue; if (orig_uid != 0) continue; triplets = proto->valid_privileged_triplets; for (j = 0; j < proto->nr_privileged_triplets; j++) ret |= generate_socket(triplets[j].family, triplets[j].protocol, triplets[j].type); } /* This is here temporarily until we have sufficient ->valid_proto's */ while (nr_sockets < NR_SOCKET_FDS) { r = rnd() % TRINITY_PF_MAX; for (i = 0; i < 10; i++) generate_specific_socket(r); } out_unlock: if (cachefile != -1) { unlock_cachefile(); close(cachefile); } return ret; }
static void handle_child(pid_t childpid, int childstatus) { unsigned int i; int slot; switch (childpid) { case 0: //debugf("[%d] Nothing changed. children:%d\n", getpid(), shm->running_childs); break; case -1: if (shm->exit_reason != STILL_RUNNING) return; if (errno == ECHILD) { debugf("[%d] All children exited!\n", getpid()); for_each_pidslot(i) { if (shm->pids[i] != EMPTY_PIDSLOT) { if (pid_alive(shm->pids[i]) == -1) { debugf("[%d] Removing %d from pidmap\n", getpid(), shm->pids[i]); shm->pids[i] = EMPTY_PIDSLOT; shm->running_childs--; } else { debugf("[%d] %d looks still alive! ignoring.\n", getpid(), shm->pids[i]); } } } break; } output(0, "error! (%s)\n", strerror(errno)); break; default: debugf("[%d] Something happened to pid %d\n", getpid(), childpid); if (WIFEXITED(childstatus)) { slot = find_pid_slot(childpid); if (slot == PIDSLOT_NOT_FOUND) { printf("[%d] ## Couldn't find pid slot for %d\n", getpid(), childpid); shm->exit_reason = EXIT_LOST_PID_SLOT; dump_pid_slots(); } else { debugf("[%d] Child %d exited after %ld syscalls.\n", getpid(), childpid, shm->child_syscall_count[slot]); reap_child(childpid); } break; } else if (WIFSIGNALED(childstatus)) { switch (WTERMSIG(childstatus)) { case SIGALRM: debugf("[%d] got a alarm signal from pid %d\n", getpid(), childpid); break; case SIGFPE: case SIGSEGV: case SIGKILL: case SIGPIPE: case SIGABRT: debugf("[%d] got a signal from pid %d (%s)\n", getpid(), childpid, strsignal(WTERMSIG(childstatus))); reap_child(childpid); break; default: debugf("[%d] ** Child got an unhandled signal (%d)\n", getpid(), WTERMSIG(childstatus)); break; } break; } else if (WIFSTOPPED(childstatus)) { switch (WSTOPSIG(childstatus)) { case SIGALRM: debugf("[%d] got an alarm signal from pid %d\n", getpid(), childpid); break; case SIGSTOP: debugf("[%d] Sending PTRACE_DETACH (and then KILL)\n", getpid()); ptrace(PTRACE_DETACH, childpid, NULL, NULL); kill(childpid, SIGKILL); reap_child(childpid); break; case SIGFPE: case SIGSEGV: case SIGKILL: case SIGPIPE: case SIGABRT: debugf("[%d] Child %d was stopped by %s\n", getpid(), childpid, strsignal(WTERMSIG(childstatus))); reap_child(childpid); break; default: debugf("[%d] Child %d was stopped by unhandled signal (%s).\n", getpid(), childpid, strsignal(WSTOPSIG(childstatus))); break; } break; } else if (WIFCONTINUED(childstatus)) { break; } else { output(0, "erk, wtf\n"); } }
bool iprint_cache_reload(void) { http_t *http = NULL; /* HTTP connection to server */ ipp_t *request = NULL, /* IPP Request */ *response = NULL; /* IPP Response */ ipp_attribute_t *attr; /* Current attribute */ cups_lang_t *language = NULL; /* Default language */ int i; bool ret = False; DEBUG(5, ("reloading iprint printcap cache\n")); /* * Make sure we don't ask for passwords... */ cupsSetPasswordCB(iprint_passwd_cb); /* * Try to connect to the server... */ if ((http = httpConnect(iprint_server(), ippPort())) == NULL) { DEBUG(0,("Unable to connect to iPrint server %s - %s\n", iprint_server(), strerror(errno))); goto out; } /* * Build a OPERATION_NOVELL_LIST_PRINTERS request, which requires the following attributes: * * attributes-charset * attributes-natural-language */ request = ippNew(); request->request.op.operation_id = (ipp_op_t)OPERATION_NOVELL_LIST_PRINTERS; request->request.op.request_id = 1; language = cupsLangDefault(); ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_CHARSET, "attributes-charset", NULL, "utf-8"); ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_LANGUAGE, "attributes-natural-language", NULL, language->language); ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_KEYWORD, "ipp-server", NULL, "ippSrvr"); /* * Do the request and get back a response... */ if ((response = cupsDoRequest(http, request, "/ipp")) == NULL) { DEBUG(0,("Unable to get printer list - %s\n", ippErrorString(cupsLastError()))); goto out; } for (attr = response->attrs; attr != NULL;) { /* * Skip leading attributes until we hit a printer... */ while (attr != NULL && attr->group_tag != IPP_TAG_PRINTER) attr = attr->next; if (attr == NULL) break; /* * Pull the needed attributes from this printer... */ while (attr != NULL && attr->group_tag == IPP_TAG_PRINTER) { if (strcmp(attr->name, "printer-name") == 0 && (attr->value_tag == IPP_TAG_URI || attr->value_tag == IPP_TAG_NAME || attr->value_tag == IPP_TAG_TEXT || attr->value_tag == IPP_TAG_NAMELANG || attr->value_tag == IPP_TAG_TEXTLANG)) { for (i = 0; i<attr->num_values; i++) { char *url = attr->values[i].string.text; if (!url || !strlen(url)) continue; iprint_cache_add_printer(http, i+2, url); } } attr = attr->next; } } ret = True; out: if (response) ippDelete(response); if (language) cupsLangFree(language); if (http) httpClose(http); return ret; }
void load_volume_table() { int alloc = 2; device_volumes = malloc(alloc * sizeof(Volume)); // Insert an entry for /tmp, which is the ramdisk and is always mounted. device_volumes[0].mount_point = "/tmp"; device_volumes[0].fs_type = "ramdisk"; device_volumes[0].device = NULL; device_volumes[0].device2 = NULL; device_volumes[0].fs_type2 = NULL; device_volumes[0].fs_options = NULL; device_volumes[0].fs_options2 = NULL; device_volumes[0].length = 0; num_volumes = 1; FILE* fstab = fopen("/etc/recovery.fstab", "r"); if (fstab == NULL) { LOGE("failed to open /etc/recovery.fstab (%s)\n", strerror(errno)); return; } char buffer[1024]; int i; while (fgets(buffer, sizeof(buffer)-1, fstab)) { for (i = 0; buffer[i] && isspace(buffer[i]); ++i); if (buffer[i] == '\0' || buffer[i] == '#') continue; char* original = strdup(buffer); char* mount_point = strtok(buffer+i, " \t\n"); char* fs_type = strtok(NULL, " \t\n"); char* device = strtok(NULL, " \t\n"); // lines may optionally have a second device, to use if // mounting the first one fails. char* options = NULL; char* device2 = strtok(NULL, " \t\n"); if (device2) { if (device2[0] == '/') { options = strtok(NULL, " \t\n"); } else { options = device2; device2 = NULL; } } if (mount_point && fs_type && device) { while (num_volumes >= alloc) { alloc *= 2; device_volumes = realloc(device_volumes, alloc*sizeof(Volume)); } device_volumes[num_volumes].mount_point = strdup(mount_point); device_volumes[num_volumes].fs_type = strdup(fs_type); device_volumes[num_volumes].device = strdup(device); device_volumes[num_volumes].device2 = device2 ? strdup(device2) : NULL; device_volumes[num_volumes].length = 0; device_volumes[num_volumes].fs_type2 = NULL; device_volumes[num_volumes].fs_options = NULL; device_volumes[num_volumes].fs_options2 = NULL; if (parse_options(options, device_volumes + num_volumes) != 0) { LOGE("skipping malformed recovery.fstab line: %s\n", original); } else { ++num_volumes; } } else { LOGE("skipping malformed recovery.fstab line: %s\n", original); } free(original); } fclose(fstab); printf("recovery filesystem table\n"); printf("=========================\n"); for (i = 0; i < num_volumes; ++i) { Volume* v = &device_volumes[i]; printf(" %d %s %s %s %s %lld\n", i, v->mount_point, v->fs_type, v->device, v->device2, v->length); } printf("\n"); }
static int iprint_job_resume(int snum, struct printjob *pjob) { int ret = 1; /* Return value */ http_t *http = NULL; /* HTTP connection to server */ ipp_t *request = NULL, /* IPP Request */ *response = NULL; /* IPP Response */ cups_lang_t *language = NULL; /* Default language */ char uri[HTTP_MAX_URI]; /* printer-uri attribute */ char httpPath[HTTP_MAX_URI]; /* path portion of the printer-uri */ DEBUG(5,("iprint_job_resume(%d, %p (%d))\n", snum, pjob, pjob->sysjob)); /* * Make sure we don't ask for passwords... */ cupsSetPasswordCB(iprint_passwd_cb); /* * Try to connect to the server... */ if ((http = httpConnect(iprint_server(), ippPort())) == NULL) { DEBUG(0,("Unable to connect to iPrint server %s - %s\n", iprint_server(), strerror(errno))); goto out; } /* * Build an IPP_RELEASE_JOB request, which requires the following * attributes: * * attributes-charset * attributes-natural-language * printer-uri * job-id * requesting-user-name */ request = ippNew(); request->request.op.operation_id = IPP_RELEASE_JOB; request->request.op.request_id = 1; language = cupsLangDefault(); ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_CHARSET, "attributes-charset", NULL, "utf-8"); ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_LANGUAGE, "attributes-natural-language", NULL, language->language); slprintf(uri, sizeof(uri) - 1, "ipp://%s/ipp/%s", iprint_server(), lp_printername(snum)); ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "printer-uri", NULL, uri); ippAddInteger(request, IPP_TAG_OPERATION, IPP_TAG_INTEGER, "job-id", pjob->sysjob); ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME, "requesting-user-name", NULL, pjob->user); /* * Do the request and get back a response... */ slprintf(httpPath, sizeof(httpPath) - 1, "/ipp/%s", lp_printername(snum)); if ((response = cupsDoRequest(http, request, httpPath)) != NULL) { if (response->request.status.status_code >= IPP_OK_CONFLICT) { DEBUG(0,("Unable to release job %d - %s\n", pjob->sysjob, ippErrorString(cupsLastError()))); } else { ret = 0; } } else { DEBUG(0,("Unable to release job %d - %s\n", pjob->sysjob, ippErrorString(cupsLastError()))); } out: if (response) ippDelete(response); if (language) cupsLangFree(language); if (http) httpClose(http); return ret; }
int main (int argc, char* argv[]){ if (argc!=2){ fprintf(stderr, "Error: Expected 1 parameter.\n" "Usage: %s <pathname>\n", argv[0]); return(EXIT_FAILURE); } DIR* FD1; struct dirent* in_file; list lista = NULL; list scan,head; unsigned char c[MD5_DIGEST_LENGTH]; struct stat statbuf; FILE *f; int i; chdir(argv[1]); if (NULL == (FD1 = opendir ("."))){ fprintf(stderr, "Error : Failed to open directory - %s\n", strerror(errno)); return -1; } while ((in_file = readdir(FD1))){ if(!strncmp(in_file->d_name,".",1)) continue; //ignoro file nascosti stat(in_file->d_name, &statbuf); if(S_ISDIR(statbuf.st_mode)) continue; //ignoro le directory f = fopen (in_file->d_name, "rb"); insert(&lista, in_file->d_name, f); for(i = 0; i < MD5_DIGEST_LENGTH; i++) printf("%02x", lista->hash[i]); printf(" %s\n",lista->name); } head=lista; while(lista!=NULL){ scan=lista; while(scan!=NULL){ if(!strcmp(lista->hash,scan->next->hash)){ printf("Same hash!\n"); if(equal(lista->name,scan->next->name)){ printf("And they are also the same file!!\n"); link(lista->name,scan->next->name); printf("Removing %s from the list\n",scan->next->name); removelem(&scan->next); } } else scan=scan->next; } lista=lista->next; } while(head!=NULL){ printf("%s\n", head->name); } return 0; }
static int iprint_job_submit(int snum, struct printjob *pjob) { int ret = 1; /* Return value */ http_t *http = NULL; /* HTTP connection to server */ ipp_t *request = NULL, /* IPP Request */ *response = NULL; /* IPP Response */ ipp_attribute_t *attr; /* Current attribute */ cups_lang_t *language = NULL; /* Default language */ char uri[HTTP_MAX_URI]; /* printer-uri attribute */ DEBUG(5,("iprint_job_submit(%d, %p (%d))\n", snum, pjob, pjob->sysjob)); /* * Make sure we don't ask for passwords... */ cupsSetPasswordCB(iprint_passwd_cb); /* * Try to connect to the server... */ if ((http = httpConnect(iprint_server(), ippPort())) == NULL) { DEBUG(0,("Unable to connect to iPrint server %s - %s\n", iprint_server(), strerror(errno))); goto out; } /* * Build an IPP_PRINT_JOB request, which requires the following * attributes: * * attributes-charset * attributes-natural-language * printer-uri * requesting-user-name * [document-data] */ request = ippNew(); request->request.op.operation_id = IPP_PRINT_JOB; request->request.op.request_id = 1; language = cupsLangDefault(); ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_CHARSET, "attributes-charset", NULL, "utf-8"); ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_LANGUAGE, "attributes-natural-language", NULL, language->language); slprintf(uri, sizeof(uri) - 1, "ipp://%s/ipp/%s", iprint_server(), lp_printername(snum)); ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "printer-uri", NULL, uri); ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME, "requesting-user-name", NULL, pjob->user); ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME, "job-originating-host-name", NULL, pjob->clientmachine); ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME, "job-name", NULL, pjob->jobname); /* * Do the request and get back a response... */ slprintf(uri, sizeof(uri) - 1, "/ipp/%s", lp_printername(snum)); if ((response = cupsDoFileRequest(http, request, uri, pjob->filename)) != NULL) { if (response->request.status.status_code >= IPP_OK_CONFLICT) { DEBUG(0,("Unable to print file to %s - %s\n", lp_printername(snum), ippErrorString(cupsLastError()))); } else { ret = 0; } } else { DEBUG(0,("Unable to print file to `%s' - %s\n", lp_printername(snum), ippErrorString(cupsLastError()))); } if ( ret == 0 ) unlink(pjob->filename); /* else print_job_end will do it for us */ if ( ret == 0 ) { attr = ippFindAttribute(response, "job-id", IPP_TAG_INTEGER); if (attr != NULL && attr->group_tag == IPP_TAG_JOB) { pjob->sysjob = attr->values[0].integer; } } out: if (response) ippDelete(response); if (language) cupsLangFree(language); if (http) httpClose(http); return ret; }
int main(int ac, char **av) { int lc; char *msg; int i; /* Disable test if the version of the kernel is less than 2.6.16 */ if ((tst_kvercmp(2, 6, 16)) < 0) { tst_resm(TWARN, "This test can only run on kernels that are "); tst_resm(TWARN, "2.6.16 and higher"); exit(0); } /*************************************************************** * parse standard options ***************************************************************/ if ((msg = parse_opts(ac, av, NULL, NULL)) != NULL) tst_brkm(TBROK, NULL, "OPTION PARSING ERROR - %s", msg); /*************************************************************** * perform global setup for test ***************************************************************/ setup(); /*************************************************************** * check looping state if -c option given ***************************************************************/ for (lc = 0; TEST_LOOPING(lc); lc++) { setup_every_copy(); Tst_count = 0; /* * Call readlinkat */ for (i = 0; i < TST_TOTAL; i++) { buffer[0] = '\0'; TEST(myreadlinkat (fds[i], filenames[i], buffer, BUFF_SIZE)); if (TEST_RETURN >= 0) { buffer[TEST_RETURN] = '\0'; } /* check return code */ if (TEST_ERRNO == expected_errno[i] && (strcmp(expected_buff[i], buffer) == 0)) { /*************************************************************** * only perform functional verification if flag set (-f not given) ***************************************************************/ if (STD_FUNCTIONAL_TEST) { /* No Verification test, yet... */ tst_resm(TPASS, "readlinkat() returned the expected errno %d: %s", TEST_ERRNO, strerror(TEST_ERRNO)); } } else { if (TEST_RETURN >= 0) { tst_resm(TINFO, "The link readlinkat got isn't as same as the expected"); } TEST_ERROR_LOG(TEST_ERRNO); tst_resm(TFAIL, "readlinkat() Failed, errno=%d : %s", TEST_ERRNO, strerror(TEST_ERRNO)); } } } /*************************************************************** * cleanup and exit ***************************************************************/ cleanup(); return (0); }
static int iprint_queue_get(const char *sharename, enum printing_types printing_type, char *lpq_command, print_queue_struct **q, print_status_struct *status) { fstring printername; http_t *http = NULL; /* HTTP connection to server */ ipp_t *request = NULL, /* IPP Request */ *response = NULL; /* IPP Response */ ipp_attribute_t *attr = NULL; /* Current attribute */ cups_lang_t *language = NULL; /* Default language */ char uri[HTTP_MAX_URI]; /* printer-uri attribute */ char serviceUri[HTTP_MAX_URI]; /* service-uri attribute */ char httpPath[HTTP_MAX_URI]; /* path portion of the uri */ int jobUseUnixTime = 0; /* Whether job times should * be assumed to be Unix time */ int qcount = 0, /* Number of active queue entries */ qalloc = 0; /* Number of queue entries allocated */ print_queue_struct *queue = NULL, /* Queue entries */ *temp; /* Temporary pointer for queue */ const char *user_name, /* job-originating-user-name attribute */ *job_name; /* job-name attribute */ int job_id; /* job-id attribute */ int job_k_octets; /* job-k-octets attribute */ time_t job_time; /* time-at-creation attribute */ time_t printer_up_time = 0; /* printer's uptime */ ipp_jstate_t job_status; /* job-status attribute */ int job_priority; /* job-priority attribute */ static const char *jattrs[] = /* Requested job attributes */ { "job-id", "job-k-octets", "job-name", "job-originating-user-name", "job-priority", "job-state", "time-at-creation", }; static const char *pattrs[] = /* Requested printer attributes */ { "printer-state", "printer-state-message", "printer-current-time", "printer-up-time" }; *q = NULL; /* HACK ALERT!!! The porblem with support the 'printer name' option is that we key the tdb off the sharename. So we will overload the lpq_command string to pass in the printername (which is basically what we do for non-cups printers ... using the lpq_command to get the queue listing). */ fstrcpy( printername, lpq_command ); DEBUG(5,("iprint_queue_get(%s, %p, %p)\n", printername, q, status)); /* * Make sure we don't ask for passwords... */ cupsSetPasswordCB(iprint_passwd_cb); /* * Try to connect to the server... */ if ((http = httpConnect(iprint_server(), ippPort())) == NULL) { DEBUG(0,("Unable to connect to iPrint server %s - %s\n", iprint_server(), strerror(errno))); goto out; } /* * Generate the printer URI and the service URI that goes with it... */ slprintf(uri, sizeof(uri) - 1, "ipp://%s/ipp/%s", iprint_server(), printername); slprintf(serviceUri, sizeof(serviceUri) - 1, "ipp://%s/ipp/", iprint_server()); /* * For Linux iPrint servers from OES SP1 on, the iPrint server * uses Unix time for job start times unless it detects the iPrint * client in an http User-Agent header. (This was done to accomodate * CUPS broken behavior. According to RFC 2911, section 4.3.14, job * start times are supposed to be relative to how long the printer has * been up.) Since libcups doesn't allow us to set that header before * the request is sent, this ugly hack allows us to detect the server * version and decide how to interpret the job time. */ if (iprint_get_server_version(http, serviceUri) >= NOVELL_SERVER_VERSION_OES_SP1) jobUseUnixTime = 1; request = ippNew(); request->request.op.operation_id = IPP_GET_PRINTER_ATTRIBUTES; request->request.op.request_id = 2; language = cupsLangDefault(); ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_CHARSET, "attributes-charset", NULL, "utf-8"); ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_LANGUAGE, "attributes-natural-language", NULL, language->language); ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "printer-uri", NULL, uri); ippAddStrings(request, IPP_TAG_OPERATION, IPP_TAG_KEYWORD, "requested-attributes", (sizeof(pattrs) / sizeof(pattrs[0])), NULL, pattrs); /* * Do the request and get back a response... */ slprintf(httpPath, sizeof(httpPath) - 1, "/ipp/%s", printername); if ((response = cupsDoRequest(http, request, httpPath)) == NULL) { DEBUG(0,("Unable to get printer status for %s - %s\n", printername, ippErrorString(cupsLastError()))); *q = queue; goto out; } if (response->request.status.status_code >= IPP_OK_CONFLICT) { DEBUG(0,("Unable to get printer status for %s - %s\n", printername, ippErrorString(response->request.status.status_code))); *q = queue; goto out; } /* * Get the current printer status and convert it to the SAMBA values. */ if ((attr = ippFindAttribute(response, "printer-state", IPP_TAG_ENUM)) != NULL) { if (attr->values[0].integer == IPP_PRINTER_STOPPED) status->status = LPSTAT_STOPPED; else status->status = LPSTAT_OK; } if ((attr = ippFindAttribute(response, "printer-state-message", IPP_TAG_TEXT)) != NULL) fstrcpy(status->message, attr->values[0].string.text); if ((attr = ippFindAttribute(response, "printer-up-time", IPP_TAG_INTEGER)) != NULL) printer_up_time = attr->values[0].integer; ippDelete(response); response = NULL; /* * Build an IPP_GET_JOBS request, which requires the following * attributes: * * attributes-charset * attributes-natural-language * requested-attributes * printer-uri */ request = ippNew(); request->request.op.operation_id = IPP_GET_JOBS; request->request.op.request_id = 3; ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_CHARSET, "attributes-charset", NULL, "utf-8"); ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_LANGUAGE, "attributes-natural-language", NULL, language->language); ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "printer-uri", NULL, uri); ippAddStrings(request, IPP_TAG_OPERATION, IPP_TAG_KEYWORD, "requested-attributes", (sizeof(jattrs) / sizeof(jattrs[0])), NULL, jattrs); /* * Do the request and get back a response... */ slprintf(httpPath, sizeof(httpPath) - 1, "/ipp/%s", printername); if ((response = cupsDoRequest(http, request, httpPath)) == NULL) { DEBUG(0,("Unable to get jobs for %s - %s\n", uri, ippErrorString(cupsLastError()))); goto out; } if (response->request.status.status_code >= IPP_OK_CONFLICT) { DEBUG(0,("Unable to get jobs for %s - %s\n", uri, ippErrorString(response->request.status.status_code))); goto out; } /* * Process the jobs... */ qcount = 0; qalloc = 0; queue = NULL; for (attr = response->attrs; attr != NULL; attr = attr->next) { /* * Skip leading attributes until we hit a job... */ while (attr != NULL && attr->group_tag != IPP_TAG_JOB) attr = attr->next; if (attr == NULL) break; /* * Allocate memory as needed... */ if (qcount >= qalloc) { qalloc += 16; queue = SMB_REALLOC_ARRAY(queue, print_queue_struct, qalloc); if (queue == NULL) { DEBUG(0,("iprint_queue_get: Not enough memory!")); qcount = 0; goto out; } } temp = queue + qcount; memset(temp, 0, sizeof(print_queue_struct)); /* * Pull the needed attributes from this job... */ job_id = 0; job_priority = 50; job_status = IPP_JOB_PENDING; job_time = 0; job_k_octets = 0; user_name = NULL; job_name = NULL; while (attr != NULL && attr->group_tag == IPP_TAG_JOB) { if (attr->name == NULL) { attr = attr->next; break; } if (strcmp(attr->name, "job-id") == 0 && attr->value_tag == IPP_TAG_INTEGER) job_id = attr->values[0].integer; if (strcmp(attr->name, "job-k-octets") == 0 && attr->value_tag == IPP_TAG_INTEGER) job_k_octets = attr->values[0].integer; if (strcmp(attr->name, "job-priority") == 0 && attr->value_tag == IPP_TAG_INTEGER) job_priority = attr->values[0].integer; if (strcmp(attr->name, "job-state") == 0 && attr->value_tag == IPP_TAG_ENUM) job_status = (ipp_jstate_t)(attr->values[0].integer); if (strcmp(attr->name, "time-at-creation") == 0 && attr->value_tag == IPP_TAG_INTEGER) { /* * If jobs times are in Unix time, the accuracy of the job * start time depends upon the iPrint server's time being * set correctly. Otherwise, the accuracy depends upon * the Samba server's time being set correctly */ if (jobUseUnixTime) job_time = attr->values[0].integer; else job_time = time(NULL) - printer_up_time + attr->values[0].integer; } if (strcmp(attr->name, "job-name") == 0 && (attr->value_tag == IPP_TAG_NAMELANG || attr->value_tag == IPP_TAG_NAME)) job_name = attr->values[0].string.text; if (strcmp(attr->name, "job-originating-user-name") == 0 && (attr->value_tag == IPP_TAG_NAMELANG || attr->value_tag == IPP_TAG_NAME)) user_name = attr->values[0].string.text; attr = attr->next; } /* * See if we have everything needed... */ if (user_name == NULL || job_name == NULL || job_id == 0) { if (attr == NULL) break; else continue; } temp->job = job_id; temp->size = job_k_octets * 1024; temp->status = job_status == IPP_JOB_PENDING ? LPQ_QUEUED : job_status == IPP_JOB_STOPPED ? LPQ_PAUSED : job_status == IPP_JOB_HELD ? LPQ_PAUSED : LPQ_PRINTING; temp->priority = job_priority; temp->time = job_time; strncpy(temp->fs_user, user_name, sizeof(temp->fs_user) - 1); strncpy(temp->fs_file, job_name, sizeof(temp->fs_file) - 1); qcount ++; if (attr == NULL) break; } /* * Return the job queue... */ *q = queue; out: if (response) ippDelete(response); if (language) cupsLangFree(language); if (http) httpClose(http); return qcount; }
static void alter_fd_dissociate(eventer_t e, int mask, struct ports_spec *spec) { int s_errno = 0, ret; errno = 0; ret = port_dissociate(spec->port_fd, PORT_SOURCE_FD, e->fd); s_errno = errno; if (ret == -1) { if(s_errno == ENOENT) return; /* Fine */ if(s_errno == EBADFD) return; /* Fine */ mtevFatal(mtev_error, "eventer port_dissociate failed(%d-%d): %d/%s\n", e->fd, spec->port_fd, s_errno, strerror(s_errno)); } }
/* * Turn job control on and off. * * Note: This code assumes that the third arg to ioctl is a character * pointer, which is true on Berkeley systems but not System V. Since * System V doesn't have job control yet, this isn't a problem now. */ MKINIT int jobctl; #if JOBS /* Minix setjobctl is defined to empty, compilation error */ void setjobctl(int on) { #ifdef OLD_TTY_DRIVER int ldisc; #endif if (on == jobctl || rootshell == 0) return; if (on) { #if defined(FIOCLEX) || defined(FD_CLOEXEC) int err; int i; if (ttyfd != -1) close(ttyfd); if ((ttyfd = open("/dev/tty", O_RDWR)) == -1) { for (i = 0; i < 3; i++) { if (isatty(i) && (ttyfd = dup(i)) != -1) break; } if (i == 3) goto out; } /* Move to a high fd */ for (i = 10; i > 2; i--) { if ((err = fcntl(ttyfd, F_DUPFD, (1 << i) - 1)) != -1) break; } if (err != -1) { close(ttyfd); ttyfd = err; } #ifdef FIOCLEX err = ioctl(ttyfd, FIOCLEX, 0); #elif FD_CLOEXEC err = fcntl(ttyfd, F_SETFD, fcntl(ttyfd, F_GETFD, 0) | FD_CLOEXEC); #endif if (err == -1) { close(ttyfd); ttyfd = -1; goto out; } #else out2str("sh: Need FIOCLEX or FD_CLOEXEC to support job control"); goto out; #endif do { /* while we are in the background */ if ((initialpgrp = tcgetpgrp(ttyfd)) < 0) { out: out2str("sh: can't access tty; job control turned off\n"); mflag = 0; return; } if (initialpgrp == -1) initialpgrp = getpgrp(); else if (initialpgrp != getpgrp()) { killpg(0, SIGTTIN); continue; } } while (0); #ifdef OLD_TTY_DRIVER if (ioctl(ttyfd, TIOCGETD, (char *)&ldisc) < 0 || ldisc != NTTYDISC) { out2str("sh: need new tty driver to run job control; job control turned off\n"); mflag = 0; return; } #endif setsignal(SIGTSTP, 0); setsignal(SIGTTOU, 0); setsignal(SIGTTIN, 0); if (getpgrp() != rootpid && setpgid(0, rootpid) == -1) error("Cannot set process group (%s) at %d", strerror(errno), __LINE__); if (tcsetpgrp(ttyfd, rootpid) == -1) error("Cannot set tty process group (%s) at %d", strerror(errno), __LINE__); } else { /* turning job control off */ if (getpgrp() != initialpgrp && setpgid(0, initialpgrp) == -1) error("Cannot set process group (%s) at %d", strerror(errno), __LINE__); if (tcsetpgrp(ttyfd, initialpgrp) == -1) error("Cannot set tty process group (%s) at %d", strerror(errno), __LINE__); close(ttyfd); ttyfd = -1; setsignal(SIGTSTP, 0); setsignal(SIGTTOU, 0); setsignal(SIGTTIN, 0); } jobctl = on; }
static void alter_fd_associate(eventer_t e, int mask, struct ports_spec *spec) { int events = 0, s_errno = 0, ret; if(mask & EVENTER_READ) events |= POLLIN; if(mask & EVENTER_WRITE) events |= POLLOUT; if(mask & EVENTER_EXCEPTION) events |= POLLERR; errno = 0; ret = port_associate(spec->port_fd, PORT_SOURCE_FD, e->fd, events, (void *)(vpsized_int)e->fd); s_errno = errno; if (ret == -1) { mtevFatal(mtev_error, "eventer port_associate failed(%d-%d): %d/%s\n", e->fd, spec->port_fd, s_errno, strerror(s_errno)); } }
void forkchild(struct job *jp, union node *n, int mode, int vforked) { int wasroot; #if JOBS /* LSC: for proper compilation with JOBS == 0 */ int pgrp; #endif const char *devnull = _PATH_DEVNULL; const char *nullerr = "Can't open %s"; wasroot = rootshell; TRACE(("Child shell %d\n", getpid())); if (!vforked) rootshell = 0; closescript(vforked); clear_traps(vforked); #if JOBS if (!vforked) jobctl = 0; /* do job control only in root shell */ if (wasroot && mode != FORK_NOJOB && mflag) { if (jp == NULL || jp->nprocs == 0) pgrp = getpid(); else pgrp = jp->ps[0].pid; /* This can fail because we are doing it in the parent also */ (void)setpgid(0, pgrp); if (mode == FORK_FG) { if (tcsetpgrp(ttyfd, pgrp) == -1) error("Cannot set tty process group (%s) at %d", strerror(errno), __LINE__); } setsignal(SIGTSTP, vforked); setsignal(SIGTTOU, vforked); } else if (mode == FORK_BG) { ignoresig(SIGINT, vforked); ignoresig(SIGQUIT, vforked); if ((jp == NULL || jp->nprocs == 0) && ! fd0_redirected_p ()) { close(0); if (open(devnull, O_RDONLY) != 0) error(nullerr, devnull); } } #else if (mode == FORK_BG) { ignoresig(SIGINT, vforked); ignoresig(SIGQUIT, vforked); if ((jp == NULL || jp->nprocs == 0) && ! fd0_redirected_p ()) { close(0); if (open(devnull, O_RDONLY) != 0) error(nullerr, devnull); } } #endif if (wasroot && iflag) { setsignal(SIGINT, vforked); setsignal(SIGQUIT, vforked); setsignal(SIGTERM, vforked); } if (!vforked) jobs_invalid = 1; }
/* ==================== IPSocket ==================== */ static int IPSocket( const char *net_interface, int port, netadr_t *bound_to = NULL ) { int newsocket; struct sockaddr_in address; int i = 1; if ( net_interface ) { common->Printf( "Opening IP socket: %s:%i\n", net_interface, port ); } else { common->Printf( "Opening IP socket: localhost:%i\n", port ); } if ( ( newsocket = socket( PF_INET, SOCK_DGRAM, IPPROTO_UDP ) ) == -1 ) { common->Printf( "ERROR: IPSocket: socket: %s", strerror( errno ) ); return 0; } // make it non-blocking int on = 1; if ( ioctl( newsocket, FIONBIO, &on ) == -1 ) { common->Printf( "ERROR: IPSocket: ioctl FIONBIO:%s\n", strerror( errno ) ); return 0; } // make it broadcast capable if ( setsockopt( newsocket, SOL_SOCKET, SO_BROADCAST, (char *) &i, sizeof(i) ) == -1 ) { common->Printf( "ERROR: IPSocket: setsockopt SO_BROADCAST:%s\n", strerror( errno ) ); return 0; } if ( !net_interface || !net_interface[ 0 ] || !idStr::Icmp( net_interface, "localhost" ) ) { address.sin_addr.s_addr = INADDR_ANY; } else { StringToSockaddr( net_interface, &address, true ); } if ( port == PORT_ANY ) { address.sin_port = 0; } else { address.sin_port = htons((short) port); } address.sin_family = AF_INET; if ( bind( newsocket, (const struct sockaddr *)&address, sizeof( address ) ) == -1 ) { common->Printf( "ERROR: IPSocket: bind: %s\n", strerror( errno ) ); close( newsocket ); return 0; } if ( bound_to ) { unsigned int len = sizeof( address ); if ( (unsigned int)(getsockname( newsocket, (struct sockaddr *)&address, (socklen_t*)&len )) == -1 ) { common->Printf( "ERROR: IPSocket: getsockname: %s\n", strerror( errno ) ); close( newsocket ); return 0; } SockadrToNetadr( &address, bound_to ); } return newsocket; }
int main(int argc, char *argv[]) { const char *cmdline[9]; int i = 0, r = EXIT_FAILURE, q; pid_t pid; siginfo_t status; _cleanup_udev_unref_ struct udev *udev = NULL; _cleanup_udev_device_unref_ struct udev_device *udev_device = NULL; const char *device, *type; bool root_directory; int progress_pipe[2] = { -1, -1 }; char dash_c[2+10+1]; struct stat st; if (argc > 2) { log_error("This program expects one or no arguments."); return EXIT_FAILURE; } log_set_target(LOG_TARGET_AUTO); log_parse_environment(); log_open(); umask(0022); parse_proc_cmdline(parse_proc_cmdline_item); test_files(); if (!arg_force && arg_skip) return 0; udev = udev_new(); if (!udev) { log_oom(); return EXIT_FAILURE; } if (argc > 1) { device = argv[1]; root_directory = false; if (stat(device, &st) < 0) { log_error("Failed to stat '%s': %m", device); return EXIT_FAILURE; } udev_device = udev_device_new_from_devnum(udev, 'b', st.st_rdev); if (!udev_device) { log_error("Failed to detect device %s", device); return EXIT_FAILURE; } } else { struct timespec times[2]; /* Find root device */ if (stat("/", &st) < 0) { log_error("Failed to stat() the root directory: %m"); return EXIT_FAILURE; } /* Virtual root devices don't need an fsck */ if (major(st.st_dev) == 0) return EXIT_SUCCESS; /* check if we are already writable */ times[0] = st.st_atim; times[1] = st.st_mtim; if (utimensat(AT_FDCWD, "/", times, 0) == 0) { log_info("Root directory is writable, skipping check."); return EXIT_SUCCESS; } udev_device = udev_device_new_from_devnum(udev, 'b', st.st_dev); if (!udev_device) { log_error("Failed to detect root device."); return EXIT_FAILURE; } device = udev_device_get_devnode(udev_device); if (!device) { log_error("Failed to detect device node of root directory."); return EXIT_FAILURE; } root_directory = true; } type = udev_device_get_property_value(udev_device, "ID_FS_TYPE"); if (type) { r = fsck_exists(type); if (r == -ENOENT) { log_info("fsck.%s doesn't exist, not checking file system on %s", type, device); return EXIT_SUCCESS; } else if (r < 0) log_warning("fsck.%s cannot be used for %s: %s", type, device, strerror(-r)); } if (arg_show_progress) if (pipe(progress_pipe) < 0) { log_error("pipe(): %m"); return EXIT_FAILURE; } cmdline[i++] = "/sbin/fsck"; cmdline[i++] = arg_repair; cmdline[i++] = "-T"; cmdline[i++] = "-l"; if (!root_directory) cmdline[i++] = "-M"; if (arg_force) cmdline[i++] = "-f"; if (progress_pipe[1] >= 0) { snprintf(dash_c, sizeof(dash_c), "-C%i", progress_pipe[1]); char_array_0(dash_c); cmdline[i++] = dash_c; } cmdline[i++] = device; cmdline[i++] = NULL; pid = fork(); if (pid < 0) { log_error("fork(): %m"); goto finish; } else if (pid == 0) { /* Child */ if (progress_pipe[0] >= 0) safe_close(progress_pipe[0]); execv(cmdline[0], (char**) cmdline); _exit(8); /* Operational error */ } progress_pipe[1] = safe_close(progress_pipe[1]); if (progress_pipe[0] >= 0) { process_progress(progress_pipe[0]); progress_pipe[0] = -1; } q = wait_for_terminate(pid, &status); if (q < 0) { log_error("waitid(): %s", strerror(-q)); goto finish; } if (status.si_code != CLD_EXITED || (status.si_status & ~1)) { if (status.si_code == CLD_KILLED || status.si_code == CLD_DUMPED) log_error("fsck terminated by signal %s.", signal_to_string(status.si_status)); else if (status.si_code == CLD_EXITED) log_error("fsck failed with error code %i.", status.si_status); else log_error("fsck failed due to unknown reason."); if (status.si_code == CLD_EXITED && (status.si_status & 2) && root_directory) /* System should be rebooted. */ start_target(SPECIAL_REBOOT_TARGET); else if (status.si_code == CLD_EXITED && (status.si_status & 6)) /* Some other problem */ start_target(SPECIAL_EMERGENCY_TARGET); else { r = EXIT_SUCCESS; log_warning("Ignoring error."); } } else r = EXIT_SUCCESS; if (status.si_code == CLD_EXITED && (status.si_status & 1)) touch("/run/systemd/quotacheck"); finish: safe_close_pair(progress_pipe); return r; }
int main(int argc, char *argv[], char *envp[]) { struct stat histstat; if (modfind(VINUMMOD) < 0) { /* need to load the vinum module */ if (kldload(VINUMMOD) < 0 || modfind(VINUMMOD) < 0) { perror(VINUMMOD ": Kernel module not available"); return 1; } } dateformat = getenv("VINUM_DATEFORMAT"); if (dateformat == NULL) dateformat = "%e %b %Y %H:%M:%S"; historyfile = getenv("VINUM_HISTORY"); if (historyfile == NULL) historyfile = DEFAULT_HISTORYFILE; if (stat(historyfile, &histstat) == 0) { /* history file exists */ if ((histstat.st_mode & S_IFMT) != S_IFREG) { fprintf(stderr, "Vinum history file %s must be a regular file\n", historyfile); exit(1); } } else if ((errno != ENOENT) /* not "not there", */ &&(errno != EROFS)) { /* and not read-only file system */ fprintf(stderr, "Can't open %s: %s (%d)\n", historyfile, strerror(errno), errno); exit(1); } hist = fopen(historyfile, "a+"); if (hist != NULL) { timestamp(); fprintf(hist, "*** " VINUMMOD " started ***\n"); fflush(hist); /* before we start the daemon */ } superdev = open(VINUM_SUPERDEV_NAME, O_RDWR); /* open vinum superdevice */ if (superdev < 0) { /* no go */ if (errno == ENODEV) { /* not configured, */ superdev = open(VINUM_WRONGSUPERDEV_NAME, O_RDWR); /* do we have a debug mismatch? */ if (superdev >= 0) { /* yup! */ #if VINUMDEBUG fprintf(stderr, "This program is compiled with debug support, but the kernel module does\n" "not have debug support. This program must be matched with the kernel\n" "module. Please alter /usr/src/sbin/" VINUMMOD "/Makefile and remove\n" "the option -DVINUMDEBUG from the CFLAGS definition, or alternatively\n" "edit /usr/src/sys/modules/" VINUMMOD "/Makefile and add the option\n" "-DVINUMDEBUG to the CFLAGS definition. Then rebuild the component\n" "of your choice with 'make clean all install'. If you rebuild the kernel\n" "module, you must stop " VINUMMOD " and restart it\n"); #else fprintf(stderr, "This program is compiled without debug support, but the kernel module\n" "includes debug support. This program must be matched with the kernel\n" "module. Please alter /usr/src/sbin/" VINUMMOD "/Makefile and add\n" "the option -DVINUMDEBUG to the CFLAGS definition, or alternatively\n" "edit /usr/src/sys/modules/" VINUMMOD "/Makefile and remove the option\n" "-DVINUMDEBUG from the CFLAGS definition. Then rebuild the component\n" "of your choice with 'make clean all install'. If you rebuild the kernel\n" "module, you must stop " VINUMMOD " and restart it\n"); #endif return 1; } } else if (errno == ENOENT) /* we don't have our node, */ make_devices(); /* create them first */ if (superdev < 0) { perror("Can't open " VINUM_SUPERDEV_NAME); return 1; } } /* Check if the dæmon is running. If not, start it in the * background */ start_daemon(); if (argc > 1) { /* we have a command on the line */ if (setjmp(command_fail) != 0) /* long jumped out */ return -1; parseline(argc - 1, &argv[1]); /* do it */ } else { /* * Catch a possible race condition which could cause us to * longjmp() into nowhere if we receive a SIGINT in the next few * lines. */ if (setjmp(command_fail)) /* come back here on catastrophic failure */ return 1; setsigs(); /* set signal handler */ for (;;) { /* ugh */ char *c; int childstatus; /* from wait4 */ if (setjmp(command_fail) == 2) /* come back here on catastrophic failure */ fprintf(stderr, "*** interrupted ***\n"); /* interrupted */ while (wait4(-1, &childstatus, WNOHANG, NULL) > 0); /* wait for all dead children */ c = readline(VINUMMOD " -> "); /* get an input */ if (c == NULL) { /* EOF or error */ if (ferror(stdin)) { fprintf(stderr, "Can't read input: %s (%d)\n", strerror(errno), errno); return 1; } else { /* EOF */ printf("\n"); return 0; } } else if (*c) { /* got something there */ add_history(c); /* save it in the history */ strcpy(buffer, c); /* put it where we can munge it */ free(c); line++; /* count the lines */ tokens = tokenize(buffer, token); /* got something potentially worth parsing */ if (tokens) parseline(tokens, token); /* and do what he says */ } if (hist) fflush(hist); } } return 0; /* normal completion */ }
static gss_name_t /* O - Server name */ cups_gss_getname( http_t *http, /* I - Connection to server */ const char *service_name) /* I - Service name */ { gss_buffer_desc token = GSS_C_EMPTY_BUFFER; /* Service token */ OM_uint32 major_status, /* Major status code */ minor_status; /* Minor status code */ gss_name_t server_name; /* Server name */ char buf[1024]; /* Name buffer */ DEBUG_printf(("7cups_gss_getname(http=%p, service_name=\"%s\")", http, service_name)); /* * Get the hostname... */ if (!http->gsshost[0]) { httpGetHostname(http, http->gsshost, sizeof(http->gsshost)); if (!strcmp(http->gsshost, "localhost")) { if (gethostname(http->gsshost, sizeof(http->gsshost)) < 0) { DEBUG_printf(("1cups_gss_getname: gethostname() failed: %s", strerror(errno))); http->gsshost[0] = '\0'; return (NULL); } if (!strchr(http->gsshost, '.')) { /* * The hostname is not a FQDN, so look it up... */ struct hostent *host; /* Host entry to get FQDN */ if ((host = gethostbyname(http->gsshost)) != NULL && host->h_name) { /* * Use the resolved hostname... */ strlcpy(http->gsshost, host->h_name, sizeof(http->gsshost)); } else { DEBUG_printf(("1cups_gss_getname: gethostbyname(\"%s\") failed.", http->gsshost)); http->gsshost[0] = '\0'; return (NULL); } } } } /* * Get a service name we can use for authentication purposes... */ snprintf(buf, sizeof(buf), "%s@%s", service_name, http->gsshost); DEBUG_printf(("8cups_gss_getname: Looking up \"%s\".", buf)); token.value = buf; token.length = strlen(buf); server_name = GSS_C_NO_NAME; major_status = gss_import_name(&minor_status, &token, GSS_C_NT_HOSTBASED_SERVICE, &server_name); if (GSS_ERROR(major_status)) { cups_gss_printf(major_status, minor_status, "cups_gss_getname: gss_import_name() failed"); return (NULL); } return (server_name); }