Example #1
0
File: auth.c Project: apple/cups
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__ */
}
Example #2
0
/*
====================
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
}
Example #3
0
/*
==================
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 ) );
    }
}
Example #4
0
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 */
Example #5
0
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;
}
Example #6
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;
    }
  }
}
Example #7
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;
		}
	}
}
Example #8
0
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;
};
Example #9
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);
}
Example #10
0
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);
};
Example #11
0
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;
};
Example #12
0
/**
 * 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;
};
Example #13
0
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);
Example #14
0
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;
}
Example #15
0
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");
		}
	}
Example #16
0
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;
}
Example #17
0
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");
}
Example #18
0
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;
}
Example #19
0
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;
}
Example #20
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;
}
Example #21
0
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);
}
Example #22
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;
}
Example #23
0
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));
    }
}
Example #24
0
/*
 * 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;
}
Example #25
0
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));
    }
}
Example #26
0
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;
}
Example #27
0
/*
====================
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;
}
Example #28
0
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;
}
Example #29
0
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 */
}
Example #30
0
File: auth.c Project: apple/cups
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), "%[email protected]%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);
}