コード例 #1
0
ファイル: module-monitor.c プロジェクト: kamyk11/oscam
static int32_t secmon_auth_client(uchar *ucrc)
{
	uint32_t crc;
	struct s_auth *account;
	struct s_client *cur_cl = cur_client();
	unsigned char md5tmp[MD5_DIGEST_LENGTH];

	if (cur_cl->auth)
	{
		int32_t s=memcmp(cur_cl->ucrc, ucrc, 4);
		if (s)
			cs_log("wrong user-crc or garbage !?");
		return !s;
	}
	cur_cl->crypted=1;
	crc=(ucrc[0]<<24) | (ucrc[1]<<16) | (ucrc[2]<<8) | ucrc[3];
	for (account=cfg.account; (account) && (!cur_cl->auth); account=account->next)
		if ((account->monlvl) &&
				(crc==crc32(0L, MD5((unsigned char *)account->usr, strlen(account->usr), md5tmp), MD5_DIGEST_LENGTH)))
		{
			memcpy(cur_cl->ucrc, ucrc, 4);
			aes_set_key(cur_cl, (char *)MD5((unsigned char *)ESTR(account->pwd), strlen(ESTR(account->pwd)), md5tmp));
			if (cs_auth_client(cur_cl, account, NULL))
				return -1;
			cur_cl->auth=1;
		}
	if (!cur_cl->auth)
	{
		cs_auth_client(cur_cl, (struct s_auth *)0, "invalid user");
		return -1;
	}
	return cur_cl->auth;
}
コード例 #2
0
ファイル: jsontofiles.c プロジェクト: kurt-vd/cgiformhelper
int main(int argc, char *argv[])
{
	int opt, ret;
	char *tempdir;
	struct stat st;

	/* argument parsing */
	while ((opt = getopt_long(argc, argv, optstring, long_opts, NULL)) != -1)
	switch (opt) {
	case 'V':
		fprintf(stderr, "%s %s\n", NAME, VERSION);
		return 0;

	default:
		fprintf(stderr, "unknown option '%c'", opt);
	case '?':
		fputs(help_msg, stderr);
		exit(1);
		break;
	}

	openlog(NAME, LOG_PERROR, LOG_DAEMON);

	tempdir = argv[optind];
	if (!tempdir)
		asprintf(&tempdir, "/tmp/%s-%i", NAME, getppid());

	/* setup input */
	if (fstat(STDIN_FILENO, &st))
		mylog(LOG_ERR, "fstat(0): %s", ESTR(errno));

	char *dat;
	dat = mmap(NULL, st.st_size, PROT_READ, MAP_PRIVATE | MAP_POPULATE, STDIN_FILENO, 0);
	if (dat == MAP_FAILED)
		mylog(LOG_ERR, "mmap(0): %s", ESTR(errno));

	/* start parsing */
	jsmn_parser prs;
	jsmntok_t *tok;
	size_t tokcnt;

	jsmn_init(&prs);
	ret = jsmn_parse(&prs, dat, st.st_size, NULL, 0);
	if (ret < 0)
		mylog(LOG_ERR, "jsmn_parse returned %i", ret);

	jsmn_init(&prs);
	tokcnt = ret;
	tok = malloc(sizeof(*tok)*tokcnt);
	ret = jsmn_parse(&prs, dat, st.st_size, tok, tokcnt);
	if (ret < 0)
		mylog(LOG_ERR, "jsmn_parse returned %i", ret);

	tokdump(dat, tok, tempdir);
	return 0;
}
コード例 #3
0
ファイル: jsontofiles.c プロジェクト: kurt-vd/cgiformhelper
static int tokdump(char *str, jsmntok_t *t, const char *fs)
{
	int fd, ntok, j, ret;
	char *newfs;
	size_t len;

	switch (t->type) {
	case JSMN_PRIMITIVE:
	case JSMN_STRING:
		fd = open(fs, O_RDWR | O_CREAT | O_TRUNC, 0666);
		if (fd < 0)
			mylog(LOG_ERR, "create %s: %s", fs, ESTR(errno));
		ret = write(fd, str+t->start, t->end - t->start);
		if (ret < 0)
			mylog(LOG_ERR, "write %s: %s", fs, ESTR(errno));
		close(fd);
		return 1;
	case JSMN_OBJECT:
		newfs = NULL;
		len = 0;
		ntok = 1;
		if (mkdir(fs, 0777) < 0)
			mylog(LOG_ERR, "mkdir %s: %s", fs, ESTR(errno));
		for (j = 0; j < t->size; ++j) {
			if (t[ntok].type != JSMN_STRING)
				mylog(LOG_ERR, "property with non-string name");
			if (strlen(fs) + t[ntok].end - t[ntok].start + 1 > len) {
				len = (strlen(fs) + t[ntok].end - t[ntok].start + 1 + 128) & ~127;
				newfs = realloc(newfs, len);
				if (!newfs)
					mylog(LOG_ERR, "realloc %li: %s", (long)len, ESTR(errno));
			}
			sprintf(newfs, "%s/%.*s", fs, t[ntok].end - t[ntok].start, str + t[ntok].start);
			++ntok;
			ntok += tokdump(str, t+ntok, newfs);
		}
		if (newfs)
			free(newfs);
		return ntok;
	case JSMN_ARRAY:
		newfs = malloc(strlen(fs) + 16);
		ntok = 1;
		if (mkdir(fs, 0777) < 0)
			mylog(LOG_ERR, "mkdir %s: %s", fs, ESTR(errno));
		for (j = 0; j < t->size; ++j) {
			sprintf(newfs, "%s/%i", fs, j);
			ntok += tokdump(str, t+ntok, newfs);
		}
		free(newfs);
		return ntok;
	default:
		return 0;
	}
}
コード例 #4
0
ファイル: oscam-client.c プロジェクト: kamyk11/oscam
void cs_reinit_clients(struct s_auth *new_accounts)
{
    struct s_auth *account;
    unsigned char md5tmp[MD5_DIGEST_LENGTH];

    struct s_client *cl;
    for (cl = first_client->next; cl; cl = cl->next) {
        if ((cl->typ == 'c' || cl->typ == 'm') && cl->account) {
            for (account = new_accounts; (account) ; account = account->next) {
                if (!strcmp(cl->account->usr, account->usr))
                    break;
            }
            if (account && !account->disabled && cl->pcrc == crc32(0L, MD5((uchar *)ESTR(account->pwd), strlen(ESTR(account->pwd)), md5tmp), MD5_DIGEST_LENGTH)) {
                cl->account = account;
                if (cl->typ == 'c') {
                    cl->grp	= account->grp;
                    cl->aureader_list	= account->aureader_list;
                    cl->autoau = account->autoau;
                    cl->expirationdate = account->expirationdate;
                    cl->allowedtimeframe[0] = account->allowedtimeframe[0];
                    cl->allowedtimeframe[1] = account->allowedtimeframe[1];
                    cl->ncd_keepalive = account->ncd_keepalive;
                    cl->c35_suppresscmd08 = account->c35_suppresscmd08;
                    cl->tosleep	= (60*account->tosleep);
                    cl->c35_sleepsend = account->c35_sleepsend;
                    cl->monlvl = account->monlvl;
                    cl->disabled	= account->disabled;
                    cl->fchid	= account->fchid;  // CHID filters
                    cl->cltab	= account->cltab;  // Class
                    // newcamd module doesn't like ident reloading
                    if (!cl->ncd_server)
                        cl->ftab = account->ftab;   // Ident

                    cl->sidtabs.ok = account->sidtabs.ok;   // services
                    cl->sidtabs.no = account->sidtabs.no;   // services
                    cl->failban = account->failban;

                    memcpy(&cl->ctab, &account->ctab, sizeof(cl->ctab));
                    memcpy(&cl->ttab, &account->ttab, sizeof(cl->ttab));

                    webif_client_reset_lastresponsetime(cl);
                    if (account->uniq)
                        cs_fake_client(cl, account->usr, (account->uniq == 1 || account->uniq == 2) ? account->uniq + 2 : account->uniq, cl->ip);
                    ac_init_client(cl, account);
                }
            } else {
                if (get_module(cl)->type & MOD_CONN_NET) {
                    cs_debug_mask(D_TRACE, "client '%s', thread=%8lX not found in db (or password changed)", cl->account->usr, (unsigned long)cl->thread);
                    kill_thread(cl);
                } else {
                    cl->account = first_client->account;
                }
            }
        } else {
            cl->account = NULL;
        }
    }
}
コード例 #5
0
void system_dump(void){
	char *buffer = NULL;

	//get wan gw
	buffer =  NSTR(primary_wan_ip_set[0].gw_ip);
	D(SYSTEM, "get apcli0 gw [%s]\n", buffer);

	//get wan ip
	buffer =  NSTR(primary_wan_ip_set[0].ip);
	D(SYSTEM, "get apcli0 ip [%s]\n", buffer);

	//get wan mac
	buffer = ESTR(SYS_wan_mac);
	D(SYSTEM, "get apcli0 mac [%s]\n", buffer);

	update_mat_table();

	system_show_assoclist();

}
コード例 #6
0
ファイル: oscam-client.c プロジェクト: kamyk11/oscam
int32_t cs_auth_client(struct s_client * client, struct s_auth *account, const char *e_txt)
{
    int32_t rc = 0;
    unsigned char md5tmp[MD5_DIGEST_LENGTH];
    char buf[32];
    char *t_crypt = "encrypted";
    char *t_plain = "plain";
    char *t_grant = " granted";
    char *t_reject = " rejected";
    char *t_msg[] = { buf, "invalid access", "invalid ip", "unknown reason", "protocol not allowed" };
    struct s_module *module = get_module(client);

    memset(&client->grp, 0xff, sizeof(uint64_t));
    //client->grp=0xffffffffffffff;
    if ((intptr_t)account != 0 && (intptr_t)account != -1 && account->disabled) {
        cs_add_violation(client, account->usr);
        cs_log("%s %s-client %s%s (%s%sdisabled account)",
               client->crypted ? t_crypt : t_plain,
               module->desc,
               IP_ISSET(client->ip) ? cs_inet_ntoa(client->ip) : "",
               IP_ISSET(client->ip) ? t_reject : t_reject+1,
               e_txt ? e_txt : "",
               e_txt ? " " : "");
        return 1;
    }

    // check whether client comes in over allowed protocol
    if ((intptr_t)account != 0 && (intptr_t)account != -1 && (intptr_t)account->allowedprotocols &&
            (((intptr_t)account->allowedprotocols & module->listenertype) != module->listenertype))
    {
        cs_add_violation(client, account->usr);
        cs_log("%s %s-client %s%s (%s%sprotocol not allowed)",
               client->crypted ? t_crypt : t_plain,
               module->desc,
               IP_ISSET(client->ip) ? cs_inet_ntoa(client->ip) : "",
               IP_ISSET(client->ip) ? t_reject : t_reject+1,
               e_txt ? e_txt : "",
               e_txt ? " " : "");
        return 1;
    }

    client->account = first_client->account;
    switch((intptr_t)account) {

    case 0: { // reject access
        rc = 1;
        cs_add_violation(client, NULL);
        cs_log("%s %s-client %s%s (%s)",
               client->crypted ? t_crypt : t_plain,
               module->desc,
               IP_ISSET(client->ip) ? cs_inet_ntoa(client->ip) : "",
               IP_ISSET(client->ip) ? t_reject : t_reject+1,
               e_txt ? e_txt : t_msg[rc]);
        break;
    }

    default: { // grant/check access
        if (IP_ISSET(client->ip) && account->dyndns) {
            if (!IP_EQUAL(client->ip, account->dynip))
                cs_user_resolve(account);
            if (!IP_EQUAL(client->ip, account->dynip)) {
                cs_add_violation(client, account->usr);
                rc=2;
            }
        }
        client->monlvl = account->monlvl;
        client->account = account;
        if (!rc)
        {
            client->dup=0;
            if (client->typ=='c' || client->typ=='m')
                client->pcrc = crc32(0L, MD5((uchar *)(ESTR(account->pwd)), strlen(ESTR(account->pwd)), md5tmp), MD5_DIGEST_LENGTH);
            if (client->typ=='c')
            {
                client->last_caid = NO_CAID_VALUE;
                client->last_srvid = NO_SRVID_VALUE;
                client->expirationdate = account->expirationdate;
                client->disabled = account->disabled;
                client->allowedtimeframe[0] = account->allowedtimeframe[0];
                client->allowedtimeframe[1] = account->allowedtimeframe[1];
                if (account->firstlogin == 0) account->firstlogin = time((time_t*)0);
                client->failban = account->failban;
                client->c35_suppresscmd08 = account->c35_suppresscmd08;
                client->ncd_keepalive = account->ncd_keepalive;
                client->grp = account->grp;
                client->aureader_list = account->aureader_list;
                client->autoau = account->autoau;
                client->tosleep = (60*account->tosleep);
                client->c35_sleepsend = account->c35_sleepsend;
                memcpy(&client->ctab, &account->ctab, sizeof(client->ctab));
                if (account->uniq)
                    cs_fake_client(client, account->usr, account->uniq, client->ip);
                client->ftab  = account->ftab;   // IDENT filter
                client->cltab = account->cltab;  // CLASS filter
                client->fchid = account->fchid;  // CHID filter
                client->sidtabs.ok= account->sidtabs.ok;   // services
                client->sidtabs.no= account->sidtabs.no;   // services
                memcpy(&client->ttab, &account->ttab, sizeof(client->ttab));
                ac_init_client(client, account);
            }
        }
    }

    case -1: { // anonymous grant access
        if (rc) {
            t_grant = t_reject;
        } else {
            if (client->typ == 'm') {
                snprintf(t_msg[0], sizeof(buf), "lvl=%d", client->monlvl);
            } else {
                int32_t rcount = ll_count(client->aureader_list);
                snprintf(buf, sizeof(buf), "au=");
                if (!rcount)
                    snprintf(buf+3, sizeof(buf)-3, "off");
                else {
                    if (client->autoau)
                        snprintf(buf+3, sizeof(buf)-3, "auto (%d reader)", rcount);
                    else
                        snprintf(buf+3, sizeof(buf)-3, "on (%d reader)", rcount);
                }
            }
        }
        cs_log("%s %s-client %s%s (%s, %s)",
               client->crypted ? t_crypt : t_plain,
               e_txt ? e_txt : module->desc,
               IP_ISSET(client->ip) ? cs_inet_ntoa(client->ip) : "",
               IP_ISSET(client->ip) ? t_grant : t_grant + 1,
               username(client), t_msg[rc]);
        break;
    }
    }
    return rc;
}
コード例 #7
0
ファイル: Keeper.cpp プロジェクト: kleopatra999/finx
int Keeper::collect(const char *path)
{
  #ifdef TEST
  *logofs << "Keeper: Looking for files in directory '"
          << path << "'.\n" << logofs_flush;
  #endif

  DIR *cacheDir = opendir(path);

  if (cacheDir != NULL)
  {
    File *file;

    dirent *dirEntry;

    struct stat fileStat;

    int baseSize = strlen(path);
    int fileSize = baseSize + 3 + MD5_LENGTH * 2 + 1;

    int n = 0;
    int s = 0;

    while (((dirEntry = readdir(cacheDir)) != NULL))
    {
      if (s++ % ONCE == 0) usleep(sleep_ * 1000);

      if (signal_ != 0) break;

      if (strcmp(dirEntry -> d_name, ".") == 0 ||
              strcmp(dirEntry -> d_name, "..") == 0)
      {
        continue;
      }      

      n++;

      if (strlen(dirEntry -> d_name) == (MD5_LENGTH * 2 + 2) &&
              (strncmp(dirEntry -> d_name, "I-", 2) == 0 ||
                  strncmp(dirEntry -> d_name, "S-", 2) == 0 ||
                      strncmp(dirEntry -> d_name, "C-", 2) == 0))
      {
        file = new File();

        char *fileName = new char[fileSize];

        if (file == NULL || fileName == NULL)
        {
          #ifdef WARNING
          *logofs << "Keeper: WARNING! Can't add file '"
                  << dirEntry -> d_name << "' to repository.\n"
                  << logofs_flush;
          #endif

          delete [] fileName;

          delete file;

          continue;
        }

        strcpy(fileName, path);
        strcpy(fileName + baseSize, "/");
        strcpy(fileName + baseSize + 1, dirEntry -> d_name);

        file -> name_ = fileName;

        #ifdef DEBUG
        *logofs << "Keeper: Adding file '" << file -> name_
                << "'.\n" << logofs_flush;
        #endif

        if (stat(file -> name_, &fileStat) == -1)
        {
          #ifdef WARNING
          *logofs << "Keeper: WARNING! Can't stat NX file '"
                  << file -> name_ << ". Error is " << EGET()
                  << " '" << ESTR() << "'.\n"
                  << logofs_flush;
          #endif

          delete file;

          continue;
        }

        file -> size_ = fileStat.st_size;
        file -> time_ = fileStat.st_mtime;

        files_ -> insert(T_files::value_type(file));

        total_ += file -> size_;
      }
    }

    closedir(cacheDir);

    if (n == 0)
    {
      time_t now = time(NULL);

      if (now > 0 && stat(path, &fileStat) == 0)
      {
        #ifdef TEST
        *logofs << "Keeper: Empty NX subdirectory '" << path
                << "' unused since " << now - fileStat.st_mtime
                << " S.\n" << logofs_flush;
        #endif

        if (now - fileStat.st_mtime > EMPTY_DIR_TIME)
        {
          #ifdef TEST
          *logofs << "Keeper: Removing empty NX subdirectory '"
                  << path << "'.\n" << logofs_flush;
          #endif

          rmdir(path);
        }
      }
    }
  }
  else
  {
    #ifdef WARNING
    *logofs << "Keeper: WARNING! Can't open NX subdirectory '"
            << path << ". Error is " << EGET() << " '" << ESTR()
            << "'.\n" << logofs_flush;
     #endif

     cerr << "Warning" << ": Can't open NX subdirectory '"
          << path << ". Error is " << EGET() << " '" << ESTR()
          << "'.\n";
  }

  return 1;
}
コード例 #8
0
ファイル: Keeper.cpp プロジェクト: kleopatra999/finx
int Keeper::cleanupImages()
{
  #ifdef TEST
  *logofs << "Keeper: Looking for image directory in '"
          << root_ << "'.\n" << logofs_flush;
  #endif

  char *imagesPath = new char[strlen(root_) + strlen("/images") + 1];

  if (imagesPath == NULL)
  {
    return -1;
  }

  strcpy(imagesPath, root_);
  strcat(imagesPath, "/images");

  //
  // Check if the cache directory does exist.
  //

  struct stat dirStat;

  if (stat(imagesPath, &dirStat) == -1)
  {
    #ifdef WARNING
    *logofs << "Keeper: WARNING! Can't stat NX images cache directory '"
            << imagesPath << ". Error is " << EGET() << " '"
            << ESTR() << "'.\n" << logofs_flush;
    #endif

    cerr << "Warning" << ": Can't stat NX images cache directory '"
         << imagesPath << ". Error is " << EGET() << " '"
         << ESTR() << "'.\n";

    delete [] imagesPath;

    return -1;
  }

  //
  // Check any of the 16 directories in the
  // images root path.
  //

  char *digitPath = new char[strlen(imagesPath) + 5];

  strcpy(digitPath, imagesPath);

  for (char digit = 0; digit < 16; digit++)
  {
    //
    // Give up if we received a signal or
    // our parent is gone.
    //

    if (signal_ != 0)
    {
      #ifdef TEST
      *logofs << "Keeper: Signal detected. Aborting.\n"
              << logofs_flush;
      #endif

      goto KeeperCleanupImagesAbort;
    }
    else if (parent_ != getppid() || parent_ == 1)
    {
      #ifdef WARNING
      *logofs << "Keeper: WARNING! Parent process appears "
              << "to be dead. Returning.\n"
              << logofs_flush;
      #endif

      goto KeeperCleanupImagesAbort;

      return 0;
    }

    sprintf(digitPath + strlen(imagesPath), "/I-%01X", digit);

    //
    // Add to the repository all the files
    // in the given directory.
    //

    collect(digitPath);
  }

  delete [] imagesPath;
  delete [] digitPath;

  //
  // Remove the oldest files.
  //

  cleanup(images_);

  //
  // Empty the repository.
  //

  empty();

  return 1;

KeeperCleanupImagesAbort:

  delete [] imagesPath;
  delete [] digitPath;

  empty();

  return 0;
}
コード例 #9
0
ファイル: Keeper.cpp プロジェクト: kleopatra999/finx
int Keeper::cleanupCaches()
{
  #ifdef TEST
  *logofs << "Keeper: Looking for cache directories in '"
          << root_ << "'.\n" << logofs_flush;
  #endif

  DIR *rootDir = opendir(root_);

  if (rootDir != NULL)
  {
    dirent *dirEntry;

    struct stat fileStat;

    int baseSize = strlen(root_);

    int s = 0;

    while (((dirEntry = readdir(rootDir)) != NULL))
    {
      if (s++ % ONCE == 0) usleep(sleep_ * 1000);

      if (signal_ != 0) break;

      if (strcmp(dirEntry -> d_name, "cache") == 0 ||
              strncmp(dirEntry -> d_name, "cache-", 6) == 0)
      {
        char *dirName = new char[baseSize + strlen(dirEntry -> d_name) + 2];

        if (dirName == NULL)
        {
          #ifdef WARNING
          *logofs << "Keeper: WARNING! Can't check directory entry '"
                  << dirEntry -> d_name << "'.\n" << logofs_flush;
          #endif

          delete [] dirName;

          continue;
        }

        strcpy(dirName, root_);
        strcpy(dirName + baseSize, "/");
        strcpy(dirName + baseSize + 1, dirEntry -> d_name);

        #ifdef TEST
        *logofs << "Keeper: Checking directory '" << dirName
                << "'.\n" << logofs_flush;
        #endif

        if (stat(dirName, &fileStat) == 0 &&
                S_ISDIR(fileStat.st_mode) != 0)
        {
          //
          // Add to repository all the "C-" and
          // "S-" files in the given directory.
          //

          collect(dirName);
        }

        delete [] dirName;
      }
    }

    closedir(rootDir);
  }
  else
  {
    #ifdef WARNING
    *logofs << "Keeper: WARNING! Can't open NX root directory '"
            << root_ << "'. Error is " << EGET() << " '"
            << ESTR() << "'.\n" << logofs_flush;
     #endif

     cerr << "Warning" << ": Can't open NX root directory '"
          << root_ << "'. Error is " << EGET() << " '"
          << ESTR() << "'.\n";
  }

  //
  // Remove older files.
  //

  cleanup(caches_);

  //
  // Empty the repository.
  //

  empty();

  return 1;
}
コード例 #10
0
ファイル: Service.cpp プロジェクト: kleopatra999/finx
int Service::logCheck(const char *file, const char *search)
{
  FILE *fp;
  char line[DEFAULT_STRING_LENGTH];
  int found;

  if (file == NULL)
  {
    #ifdef WARNING
    logUser("Service::logCheck: WARNING! No file specified.");
    #endif

    return 0;
  }

  fp = fopen(file, "r");

  if (fp == NULL)
  {
    #ifdef WARNING
    logUser("Service::logCheck: WARNING! Cannot open the file: (error %d) %s", EGET(), ESTR());
    #endif

    return 0;
  }

  //
  // TODO: This function could be optimized using
  // the search stream direction.
  //

  found = 0;

  while (!feof(fp))
  {
    fgets(line, DEFAULT_STRING_LENGTH-1, fp);

    #ifdef TEST
    logUser("Service::logCheck: Going to examine line [%s].", line);
    #endif

    if (strstr(line, search) != NULL)
    {
      found = 1;
      break;
    }
  }

  fclose(fp);

  return (found);
}
コード例 #11
0
ファイル: runc.c プロジェクト: kurt-vd/rund
/* convenience wrapper for send with SCM_CREDENTIALS */
static int sendcred(int sock, const void *dat, unsigned int len, int flags)
{
	struct ucred *pcred;
	union {
		struct cmsghdr hdr;
		char dat[CMSG_SPACE(sizeof(struct ucred))];
	} cmsg = {
		.hdr.cmsg_len = CMSG_LEN(sizeof(struct ucred)),
		.hdr.cmsg_level = SOL_SOCKET,
		.hdr.cmsg_type = SCM_CREDENTIALS,
	};
	struct iovec iov = {
		.iov_base = (void *)dat,
		.iov_len = len,
	};
	struct msghdr msg = {
		.msg_iov = &iov,
		.msg_iovlen = 1,
		.msg_control = &cmsg,
		.msg_controllen = cmsg.hdr.cmsg_len,
	};
	pcred = (void *)CMSG_DATA(&cmsg.hdr);
	pcred->pid = getpid();
	pcred->uid = getuid();
	pcred->gid = getgid();
	return sendmsg(sock, &msg, flags);
}

static int ttytest(void)
{
	int fd;

	fd = open("/dev/tty", O_RDWR);
	close(fd);
	/* /dev/tty can only open when a controlling terminal is opened,
	 * /dev/console is not one of them
	 */
	return fd >= 0;
}

/* main process */
int main(int argc, char *argv[])
{
	int ret, opt, sock, j, pos;
	struct sockaddr_un name = {
		.sun_family = AF_UNIX,
		.sun_path = "\0rund",
	};
	double repeat = NAN;
	int maxdelay = 0;
	time_t t0;
	int quiet;

	/* prepare cmd */
	static char sbuf[16*1024], rbuf[16*1024];
	char *bufp, *str;

	/* assume quiet operation on non-terminal invocation */
	quiet = !ttytest();
	/* parse program options */
	while ((opt = getopt(argc, argv, optstring)) != -1)
	switch (opt) {
	case 'V':
		fprintf(stderr, "%s: %s\n", NAME, VERSION);
		return 0;
	case 'q':
		quiet = 1;
		break;
	case 'r':
		repeat = optarg ? strtod(optarg, NULL) : 1;
		if (!(repeat > 0))
			mylog(LOG_ERR, "bad rate '%s'", optarg);
		break;
	case 's':
		if (*optarg != '@')
			mylog(LOG_ERR, "bad socket name '%s'", optarg);
		strcpy(name.sun_path+1, optarg+1);
		break;
	case 'm':
		maxdelay = ceil(strtod(optarg, NULL));
		break;
	default:
		fprintf(stderr, "%s: option '%c' unrecognised\n", NAME, opt);
	case '?':
		fputs(help_msg, stderr);
		exit(1);
	}

	for (j = optind, bufp = sbuf; j < argc; ++j) {
		if (!strncmp("USER="******"user '%s' unknown", argv[j]+5);
			/* add the argument manually
			 * don't forget to add null terminator
			 */
			bufp += sprintf(bufp, "USER=#%u", pw->pw_uid)+1;
			continue;
		}
		strcpy(bufp, argv[j]);
		bufp += strlen(bufp)+1;
	}
	if (bufp <= sbuf)
		mylog(LOG_ERR, "no command specified");

	/* install timeout handler using sigalrm */
	signal(SIGALRM, sigalrm);

	/* open client socket */
	ret = sock = socket(PF_UNIX, SOCK_DGRAM, 0);
	if (ret < 0)
		mylog(LOG_ERR, "socket(unix, ...) failed: %s", ESTR(errno));
	/* connect to server */
	ret = connect(sock, (void *)&name, sizeof(name));
	if (ret < 0)
		mylog(LOG_ERR, "connect(@%s) failed: %s", name.sun_path+1, ESTR(errno));

	str = name.sun_path+1;
	str += strlen(str);
	sprintf(str, "-%i", getpid());
	ret = bind(sock, (void *)&name, sizeof(name));
	if (ret < 0)
		mylog(LOG_ERR, "bind(@%s) failed: %s", name.sun_path+1, ESTR(errno));

	t0 = time(NULL);
	do {
		/* schedule timeout */
		alarm(1);
		/* send command */
		ret = sendcred(sock, sbuf, bufp - sbuf, 0);
		if (ret < 0)
			mylog(LOG_ERR, "send ...: %s", ESTR(errno));

		do {
			ret = recv(sock, rbuf, sizeof(rbuf)-1, 0);
			if (ret < 0)
				mylog(LOG_ERR, "recv ...: %s", ESTR(errno));
			if (!ret)
				mylog(LOG_ERR, "empty response");
			rbuf[ret] = 0;
			if (*rbuf != '>')
				break;
			for (pos = 1; pos < ret; ) {
				if (pos > 1)
					fputc(' ', stdout);
				fputs(rbuf+pos, stdout);
				pos += strlen(rbuf+pos)+1;
			}
			printf("\n");
			alarm(1);
		} while (1);
		ret = strtol(rbuf, NULL, 0);
		if (ret < 0)
			mylog(LOG_ERR, "command failed: %s", ESTR(-ret));
		if (isnan(repeat)) {
			if (!quiet)
				printf("%i\n", ret);
			break;
		}
		if (maxdelay && (!ret || (time(NULL) > (t0+maxdelay)))) {
			if (!quiet)
				mylog(LOG_INFO, "%s %s after %lu seconds", sbuf,
					ret ? "aborted" : "finished",
					time(NULL)-t0);
			return !!ret;
		}
		/* remove timeout */
		alarm(0);
		if (ret)
			poll(NULL, 0, repeat*1000);
	} while (ret);
	return EXIT_SUCCESS;
}
コード例 #12
0
ファイル: StaticCompressor.cpp プロジェクト: narenas/nx-libs
int StaticCompressor::compressBuffer(const unsigned char *plainBuffer,
                                         const unsigned int plainSize,
                                             unsigned char *&compressedBuffer,
                                                 unsigned int &compressedSize)
{
  #ifdef DEBUG
  *logofs << "StaticCompressor: Called for buffer at "
          << (void *) plainBuffer << ".\n"
          << logofs_flush;
  #endif

  compressedSize = plainSize;

  if (plainSize < (unsigned int) threshold_)
  {
    #ifdef TEST
    *logofs << "StaticCompressor: Leaving buffer unchanged. "
            << "Plain size is " << plainSize << " with threshold "
            << (unsigned int) threshold_ << ".\n" << logofs_flush;
    #endif

    return 0;
  }

  //
  // Determine the size of the temporary
  // buffer. 
  //

  unsigned int newSize = plainSize + (plainSize / 1000) + 12;

  //
  // Allocate a new buffer if it grows
  // beyond 64K.
  //

  if (buffer_ == NULL || (bufferSize_ > 65536 &&
          newSize < bufferSize_ / 2) || newSize > bufferSize_)
  {
    delete [] buffer_;

    buffer_ = new unsigned char[newSize];

    if (buffer_ == NULL)
    {
      #ifdef PANIC
      *logofs << "StaticCompressor: PANIC! Can't allocate compression "
              << "buffer of " << newSize << " bytes. Error is " << EGET()
              << " ' " << ESTR() << "'.\n" << logofs_flush;
      #endif

      cerr << "Warning" << ": Can't allocate compression buffer of "
           << newSize << " bytes. Error is " << EGET()
           << " '" << ESTR() << "'.\n";

      bufferSize_ = 0;

      return 0;
    }

    bufferSize_ = newSize;
  }

  unsigned int resultingSize = newSize; 

  int result = ZCompress(&compressionStream_, buffer_, &resultingSize,
                             plainBuffer, plainSize);

  if (result == Z_OK)
  {
    if (resultingSize > newSize)
    {
      #ifdef PANIC
      *logofs << "StaticCompressor: PANIC! Overflow in compression "
              << "buffer size. " << "Expected size was " << newSize
              << " while it is " << resultingSize << ".\n"
              << logofs_flush;
      #endif

      cerr << "Error" << ": Overflow in compress buffer size. "
           << "Expected size was " << newSize << " while it is "
           << resultingSize << ".\n";

      return -1;
    }
    else if (resultingSize >= plainSize)
    {
      #ifdef TEST
      *logofs << "StaticCompressor: Leaving buffer unchanged. "
              << "Plain size is " << plainSize << " compressed "
              << "size is " << resultingSize << ".\n"
              << logofs_flush;
      #endif

      return 0;
    }

    compressedBuffer = buffer_;
    compressedSize   = resultingSize;

    #ifdef TEST
    *logofs << "StaticCompressor: Compressed buffer from "
            << plainSize << " to " << resultingSize
            << " bytes.\n" << logofs_flush;
    #endif

    return 1;
  }

  #ifdef PANIC
  *logofs << "StaticCompressor: PANIC! Failed compression of buffer. "
          << "Error is '" << zError(result) << "'.\n"
          << logofs_flush;
  #endif

  cerr << "Error" << ": Failed compression of buffer. "
       << "Error is '" << zError(result) << "'.\n";

  return -1;
}
コード例 #13
0
ファイル: ServerProxy.cpp プロジェクト: narenas/nx-libs
int ServerProxy::handleNewXConnectionFromProxy(int channelId)
{
  //
  // Connect to the real X server.
  //

  int retryConnect = control -> OptionServerRetryConnect;

  int xServerFd;

  for (;;)
  {
    xServerFd = socket(xServerAddrFamily_, SOCK_STREAM, PF_UNSPEC);

    if (xServerFd < 0)
    {
      #ifdef PANIC
      *logofs << "ServerProxy: PANIC! Call to socket failed. "
              << "Error is " << EGET() << " '" << ESTR()
              << "'.\n" << logofs_flush;
      #endif

      cerr << "Error" << ": Call to socket failed. "
           << "Error is " << EGET() << " '" << ESTR()
           << "'.\n";

      return -1;
    }

    #ifdef TEST
    *logofs << "ServerProxy: Trying to connect to X server '"
            << xServerDisplay_ << "'.\n" << logofs_flush;
    #endif

    int result = connect(xServerFd, xServerAddr_, xServerAddrLength_);

    getNewTimestamp();

    if (result < 0)
    {
      #ifdef WARNING
      *logofs << "ServerProxy: WARNING! Connection to '"
              << xServerDisplay_ << "' failed with error '"
              << ESTR() << "'. Retrying.\n" << logofs_flush;
      #endif

      close(xServerFd);

      if (--retryConnect == 0)
      {
        #ifdef PANIC
        *logofs << "ServerProxy: PANIC! Connection to '"
                << xServerDisplay_ << "' for channel ID#"
                << channelId << " failed. Error is "
                << EGET() << " '" << ESTR() << "'.\n"
                << logofs_flush;
        #endif

        cerr << "Error" << ": Connection to '"
             << xServerDisplay_ << "' failed. Error is "
             << EGET() << " '" << ESTR() << "'.\n";

        close(xServerFd);

        return -1;
      }

      if (activeChannels_.getSize() == 0)
      {
        sleep(2);
      }
      else
      {
        sleep(1);
      }
    }
    else
    {
      break;
    }
  }

  assignChannelMap(channelId, xServerFd);

  #ifdef TEST
  *logofs << "ServerProxy: X server descriptor FD#" << xServerFd 
          << " mapped to channel ID#" << channelId << ".\n"
          << logofs_flush;
  #endif

  //
  // Turn queuing off for path proxy-to-X-server.
  //

  if (control -> OptionServerNoDelay == 1)
  {
    SetNoDelay(xServerFd, control -> OptionServerNoDelay);
  }

  //
  // If requested, set the size of the TCP send
  // and receive buffers.
  //

  if (control -> OptionServerSendBuffer != -1)
  {
    SetSendBuffer(xServerFd, control -> OptionServerSendBuffer);
  }

  if (control -> OptionServerReceiveBuffer != -1)
  {
    SetReceiveBuffer(xServerFd, control -> OptionServerReceiveBuffer);
  }

  if (allocateTransport(xServerFd, channelId) < 0)
  {
    return -1;
  }

  //
  // Starting from protocol level 3 client and server
  // caches are created in proxy and shared between all
  // channels. If remote proxy has older protocol level
  // pointers are NULL and channels must create their
  // own instances.
  //

  channels_[channelId] = new ServerChannel(transports_[channelId], compressor_);

  if (channels_[channelId] == NULL)
  {
    deallocateTransport(channelId);

    return -1;
  }

  increaseChannels(channelId);

  //
  // Propagate channel stores and caches to the new
  // channel.
  //

  channels_[channelId] -> setOpcodes(opcodeStore_);

  channels_[channelId] -> setStores(clientStore_, serverStore_);

  channels_[channelId] -> setCaches(clientCache_, serverCache_);

  int port = atoi(fontServerPort_);

  if (port > 0)
  {
    channels_[channelId] -> setPorts(port);
  }

  //
  // Let channel configure itself according
  // to control parameters.
  //

  channels_[channelId] -> handleConfiguration();

  //
  // Check if we have successfully loaded the
  // selected cache and, if not, remove it
  // from disk.
  //

  handleCheckLoad();

  return 1;
}
コード例 #14
0
ファイル: Pipe.cpp プロジェクト: narenas/nx-libs
FILE *Popen(char * const parameters[], const char *type)
{
  FILE *iop;

  struct pid *cur;
  int pdes[2], pid;

  if (parameters == NULL || type == NULL)
  {
    return NULL;
  }

  if ((*type != 'r' && *type != 'w') || type[1])
  {
    return NULL;
  }

  if ((cur = (struct pid *) malloc(sizeof(struct pid))) == NULL)
  {
    return NULL;
  }

  if (pipe(pdes) < 0)
  {
    free(cur);

    return NULL;
  }

  //
  // Block all signals until command is exited.
  // We need to gather information about the
  // child in Pclose().
  //

  DisableSignals();

  switch (pid = Fork())
  {
    case -1:
    {
      //
      // Error.
      //

      #ifdef PANIC
      *logofs << "Popen: PANIC! Function fork failed. "
              << "Error is " << EGET() << " '" << ESTR()
              << "'.\n" << logofs_flush;
      #endif

      cerr << "Error" << ": Function fork failed. "
           << "Error is " << EGET() << " '" << ESTR()
           << "'.\n";

      close(pdes[0]);
      close(pdes[1]);

      free(cur);

      return NULL;
    }
    case 0:
    {
      //
      // Child.
      //

      setgid(getgid());
      setuid(getuid());

      if (*type == 'r')
      {
        if (pdes[1] != 1)
        {
          //
          // Set up stdout.
          //

          dup2(pdes[1], 1);
          close(pdes[1]);
        }

        close(pdes[0]);
      }
      else
      {
        if (pdes[0] != 0)
        {
          //
          // Set up stdin.
          //

          dup2(pdes[0], 0);
          close(pdes[0]);
        }

        close(pdes[1]);
      }

      execvp(parameters[0], parameters + 1);

      exit(127);
    }
  }

  //
  // Parent. Save data about the child.
  //

  RegisterChild(pid);

  if (*type == 'r')
  {
    iop = fdopen(pdes[0], type);

    close(pdes[1]);
  }
  else
  {
    iop = fdopen(pdes[1], type);

    close(pdes[0]);
  }

  cur -> fp = iop;
  cur -> self = pid;
  cur -> next = pidlist;

  pidlist = cur;

  #ifdef TEST
  *logofs << "Popen: Executing ";

  for (int i = 0; i < 256 && parameters[i] != NULL; i++)
  {
    *logofs << "[" << parameters[i] << "]";
  }

  *logofs << " with descriptor " << fileno(iop)
          << ".\n" << logofs_flush;
  #endif

  return iop;
}