Esempio n. 1
0
static int config_check()
{
    if (!str_empty(robot.conf_file))
    {
        if (!parse_conf_file(robot.conf_file)) return 0;
    }
    else
    {
        fprintf(stderr, "Please input configure file!!!!\n");
        return 0;
    }
    if (conf_lookup(&robot.conf, str_from("QQ")).type != CONF_VALUE_TYPE_STRING || conf_lookup(&robot.conf, str_from("PASSWORD")).type != CONF_VALUE_TYPE_STRING)
    {
        fprintf(stderr, "Invalid QQ or PASSWORD type!!!!\n");
        return 0;
    }
    if (str_empty(conf_lookup(&robot.conf, str_from("DB_HOST")).string))
    {
        fprintf(stdout, "Warning: Unset DB_HOST variable, the default value is 127.0.0.1!!!!\n");
        fflush(stdout);
        conf_append_strs(&robot.conf, "DB_HOST", "127.0.0.1");
    }
    if (str_empty(conf_lookup(&robot.conf, str_from("DB_NAME")).string))
    {
        fprintf(stdout, "Warning: Unset DB_NAME variable, the default value is qqrobot!!!!\n");
        fflush(stdout);
        conf_append_strs(&robot.conf, "DB_NAME", "qqrobot");
    }
    return 1;
}
Esempio n. 2
0
static void
handle_user_command(struct vsf_session* p_sess)
{
  /* SECURITY: If we're in anonymous only-mode, immediately reject
   * non-anonymous usernames in the hope we save passwords going plaintext
   * over the network
   */
  int is_anon = 1;
  str_copy(&p_sess->user_str, &p_sess->ftp_arg_str);
  str_upper(&p_sess->ftp_arg_str);
  if (!str_equal_text(&p_sess->ftp_arg_str, "FTP") &&
      !str_equal_text(&p_sess->ftp_arg_str, "ANONYMOUS"))
  {
    is_anon = 0;
  }
  if (!tunable_local_enable && !is_anon)
  {
    vsf_cmdio_write(
      p_sess, FTP_LOGINERR, "This FTP server is anonymous only.");
    str_empty(&p_sess->user_str);
    return;
  }
  if (is_anon && p_sess->control_use_ssl && !tunable_allow_anon_ssl)
  {
    vsf_cmdio_write(
      p_sess, FTP_LOGINERR, "Anonymous sessions may not use encryption.");
    str_empty(&p_sess->user_str);
    return;
  }
  if (tunable_ssl_enable && !is_anon && !p_sess->control_use_ssl &&
      tunable_force_local_logins_ssl)
  {
    vsf_cmdio_write(
      p_sess, FTP_LOGINERR, "Non-anonymous sessions must use encryption.");
    str_empty(&p_sess->user_str);
    return;
  }
  if (!str_isempty(&p_sess->userlist_str))
  {
    int located = str_contains_line(&p_sess->userlist_str, &p_sess->user_str);
    if ((located && tunable_userlist_deny) ||
        (!located && !tunable_userlist_deny))
    {
      vsf_cmdio_write(p_sess, FTP_LOGINERR, "Permission denied.");
      str_empty(&p_sess->user_str);
      return;
    }
  }
  if (is_anon && tunable_no_anon_password)
  {
    /* Fake a password */
    str_alloc_text(&p_sess->ftp_arg_str, "<no password>");
    handle_pass_command(p_sess);
  }
  else
  {
    vsf_cmdio_write(p_sess, FTP_GIVEPWORD, "Please specify the password.");
  }
}
Esempio n. 3
0
void
strs_empty( str *s, ... )
{
	str *s2;
	va_list ap;
	str_empty( s );
	va_start( ap, s );
	do {
		s2 = va_arg( ap, str * );
		if ( s2 ) str_empty( s2 );
	} while ( s2 );
	va_end( ap );
}
Esempio n. 4
0
void
QtSqlConnectionBackend::open(SqlDialect *dialect, const SqlSource &source)
{
    close();
    ScopedLock lock(drv_->conn_mux_);
    own_handle_ = true;
    conn_name_ = dialect->get_name() + _T("_") + source.db()
        + _T("_") + to_string(drv_->seq_);
    ++drv_->seq_;
    String driver = source.driver();
    bool eat_slash = false;
    if (driver == _T("QTSQL"))
    {
        if (dialect->get_name() == _T("MYSQL"))
            driver = _T("QMYSQL");
        else if (dialect->get_name() == _T("POSTGRES"))
            driver = _T("QPSQL");
        else if (dialect->get_name() == _T("ORACLE"))
            driver = _T("QOCI");
        else if (dialect->get_name() == _T("INTERBASE"))
            driver = _T("QIBASE");
        else if (dialect->get_name() == _T("SQLITE"))
            driver = _T("QSQLITE");
        if (dialect->native_driver_eats_slash()
                && !str_empty(source.db())
                && char_code(source.db()[0]) == '/')
            eat_slash = true;
    }
    conn_ = new QSqlDatabase(QSqlDatabase::addDatabase(driver, conn_name_));
    if (eat_slash)
        conn_->setDatabaseName(str_substr(source.db(), 1));
    else
        conn_->setDatabaseName(source.db());
    conn_->setUserName(source.user());
    conn_->setPassword(source.passwd());
    if (source.port() > 0)
        conn_->setPort(source.port());
    if (!str_empty(source.host()))
        conn_->setHostName(source.host());
    String options;
    Strings keys = source.options();
    for (size_t i = 0; i < keys.size(); ++i) {
        if (!str_empty(options))
            options += _T(";");
        options += keys[i] + _T("=") + source[keys[i]];
    }
    if (!str_empty(options))
        conn_->setConnectOptions(options);
    if (!conn_->open())
        throw DBError(conn_->lastError().text());
}
Esempio n. 5
0
static int
medin_authorlist( xml *node, fields *info )
{
	int fstatus, status;
	str name;
	char *tag;
	str_init( &name );
	node = node->down;
	while ( node ) {
		if ( xml_tag_matches( node, "Author" ) && node->down ) {
			status = medin_author( node->down, &name );
			tag = "AUTHOR";
			if ( str_is_empty( &name ) ) {
				status = medin_corpauthor( node->down, &name );
				tag = "AUTHOR:CORP";
			}
			if ( str_memerr( &name ) || status!=BIBL_OK ) return BIBL_ERR_MEMERR;
			if ( str_has_value( &name ) ) {
				fstatus = fields_add(info,tag,name.data,0);
				if ( fstatus!=FIELDS_OK ) return BIBL_ERR_MEMERR;
			}
			str_empty( &name );
		}
		node = node->next;
	}
	str_free( &name );
	return BIBL_OK;
}
Esempio n. 6
0
int
str_getline(const struct mystr* p_str, struct mystr* p_line_str,
            unsigned int* p_pos)
{
  unsigned int start_pos = *p_pos;
  unsigned int curr_pos = start_pos;
  unsigned int buf_len = str_getlen(p_str);
  const char* p_buf = str_getbuf(p_str);
  unsigned int out_len;
  if (start_pos > buf_len)
  {
    bug("p_pos out of range in str_getline");
  }
  str_empty(p_line_str);
  if (start_pos == buf_len)
  {
    return 0;
  }
  while (curr_pos < buf_len && p_buf[curr_pos] != '\n')
  {
    curr_pos++;
  }
  out_len = curr_pos - start_pos;
  /* If we ended on a \n - skip it */
  if (curr_pos < buf_len && p_buf[curr_pos] == '\n')
  {
    curr_pos++;
  }
  private_str_alloc_memchunk(p_line_str, p_buf + start_pos, out_len);
  *p_pos = curr_pos;
  return 1;
}
Esempio n. 7
0
static void
handle_pass_command(struct vsf_session* p_sess)
{
  if (str_isempty(&p_sess->user_str))
  {
    vsf_cmdio_write(p_sess, FTP_NEEDUSER, "Login with USER first.");
    return;
  }
  /* These login calls never return if successful */
  if (tunable_one_process_model)
  {
    vsf_one_process_login(p_sess, &p_sess->ftp_arg_str);
  }
  else
  {
    vsf_two_process_login(p_sess, &p_sess->ftp_arg_str);
  }
  vsf_cmdio_write(p_sess, FTP_LOGINERR, "Login incorrect.");
  if (++p_sess->login_fails >= tunable_max_login_fails)
  {
    vsf_sysutil_exit(0);
  }
  str_empty(&p_sess->user_str);
  /* FALLTHRU if login fails */
}
Esempio n. 8
0
void
str_trimbegin( str *s, unsigned long n )
{
	char *p, *q;

	assert( s );

	if ( n==0 ) return;
	if ( s->len==0 ) return;
	if ( n >= s->len ) {
		str_empty( s );
		return;
	}

	p = s->data;
	while ( n-- > 0 ) p++;

	n = 0;
	q = s->data;
	while ( *p ) {
		*q++ = *p++;
		n++;
	}
	*q = '\0';

	s->len = n;
}
Esempio n. 9
0
char *get_config_directory (void) {
  char *config_directory;
  config_directory = getenv("TELEGRAM_CONFIG_DIR");
  if (!str_empty (config_directory)) { return tstrdup (config_directory); }
  // XDG: http://standards.freedesktop.org/basedir-spec/basedir-spec-latest.html
  config_directory = getenv("XDG_CONFIG_HOME");
  if (!str_empty (config_directory)) {
    tasprintf (&config_directory, "%s/" PROG_NAME, config_directory);
    // :TODO: someone check whether it could be required to pass tasprintf
    //        a tstrdup()ed config_directory instead; works for me without.
    //        should work b/c this scope's lifespan encompasses tasprintf()
    return config_directory;
  }
  tasprintf (&config_directory, "%s/" CONFIG_DIRECTORY, get_home_directory ());
  return config_directory;
}
Esempio n. 10
0
YBORM_DECL const String env_cfg(const String &entry, const String &def_val)
{
    String value = xgetenv(_T("YBORM_") + entry);
    if (str_empty(value))
        return def_val;
    return value;
}
Esempio n. 11
0
int
str_fgetline( str *s, FILE *fp )
{
	int ch, eol = 0;
	assert( s );
	assert( fp );
	str_empty( s );
	if ( feof( fp ) ) return 0;
	while ( !feof( fp ) && !eol ) {
		ch = fgetc( fp );
		if ( ch == EOF ) {
			if ( s->len ) return 1;
			else return 0;
		}
		else if ( ch == '\n' ) eol = 1;
		else if ( ch == '\r' ) {
			ch = fgetc( fp );
			if ( ch != '\n' ) ungetc( ch, fp );
			eol = 1;
		} else {
			str_addchar( s, (char) ch );
		}
	}
	return 1;
}
Esempio n. 12
0
/* str_segcpy( s, start, end );
 *
 * copies [start,end) into s
 */
void
str_segcpy( str *s, char *startat, char *endat )
{
	unsigned long n;
	char *p;

	assert( s && startat && endat );
	assert( ((size_t) startat) <= ((size_t) endat) );

	return_if_memerr( s );

	if ( startat==endat ) {
		str_empty( s );
		return;
	}

	n = 0;
	p = startat;
	while ( p!=endat ) {
		p++;
		n++;
	}

	str_strcpy_internal( s, startat, n );
}
Esempio n. 13
0
int
ctl_create(const char *dir, const char *file)
{
    if (str_empty(dir)) {
        errno = EINVAL;
        return -1;
    }

    if (mkdir(dir, 0700) == -1 && errno != EEXIST)
        return -1;

    int fd = socket(AF_UNIX, SOCK_DGRAM, 0);

    if (fd == -1)
        return -1;

    if (ctl_bind(fd, dir, file)) {
        int err = errno;
        close(fd);
        errno = err;
        return -1;
    }

    return fd;
}
Esempio n. 14
0
/* XXX - really, this should be refactored into a "buffered writer" object */
static int
write_dir_list(struct vsf_session* p_sess, struct mystr_list* p_dir_list,
               enum EVSFRWTarget target)
{
  /* This function writes out a list of strings to the client, over the
   * data socket. We now coalesce the strings into fewer write() syscalls,
   * which saved 33% CPU time writing a large directory.
   */
  int retval = 0;
  unsigned int dir_index_max = str_list_get_length(p_dir_list);
  unsigned int dir_index;
  struct mystr buf_str = INIT_MYSTR;
  str_reserve(&buf_str, VSFTP_DIR_BUFSIZE);
  for (dir_index = 0; dir_index < dir_index_max; dir_index++)
  {
    str_append_str(&buf_str, str_list_get_pstr(p_dir_list, dir_index));
    if (dir_index == dir_index_max - 1 ||
        str_getlen(&buf_str) +
          str_getlen(str_list_get_pstr(p_dir_list, dir_index + 1)) >
            VSFTP_DIR_BUFSIZE)
    {
      /* Writeout needed - we're either at the end, or we filled the buffer */
      int writeret = ftp_write_str(p_sess, &buf_str, target);
      if (writeret != 0)
      {
        retval = 1;
        break;
      }
      str_empty(&buf_str);
    }
  }
  str_free(&buf_str);
  return retval;
}
Esempio n. 15
0
static int
ctl_bind(int fd, const char *dir, const char *file)
{
    char tmp[32];
    struct sockaddr_un sun;

    if (str_empty(file)) {
        for (int i = 0; i < CTL_BIND_MAX; i++) {
            if (snprintf(tmp, sizeof(tmp), ".%i", i) >= sizeof(tmp))
                return -1;

            if (ctl_setsun(&sun, dir, tmp))
                return -1;

            if (!bind(fd, (struct sockaddr *)&sun, sizeof(sun)))
                return 0;
        }
    } else {
        if (ctl_setsun(&sun, dir, file))
            return -1;

        unlink(sun.sun_path);

        if (!bind(fd, (struct sockaddr *)&sun, sizeof(sun)))
            return 0;
    }

    return -1;
}
Esempio n. 16
0
/* str_fget()
 *   returns 0 if we're done, 1 if we're not done
 *   extracts line by line (regardless of end characters)
 *   and feeds from buf....
 */
int
str_fget( FILE *fp, char *buf, int bufsize, int *pbufpos, str *outs )
{
	int  bufpos = *pbufpos, done = 0;
	char *ok;
	assert( fp && outs );
	str_empty( outs );
	while ( !done ) {
		while ( buf[bufpos] && buf[bufpos]!='\r' && buf[bufpos]!='\n' )
			str_addchar( outs, buf[bufpos++] );
		if ( buf[bufpos]=='\0' ) {
			ok = fgets( buf, bufsize, fp );
			bufpos=*pbufpos=0;
			if ( !ok && feof(fp) ) { /* end-of-file */
				buf[bufpos] = 0;
				if ( outs->len==0 ) return 0; /*nothing in out*/
				else return 1; /*one last out */
			}
		} else if ( buf[bufpos]=='\r' || buf[bufpos]=='\n' ) done=1;
	}
	if ( ( buf[bufpos]=='\n' && buf[bufpos+1]=='\r') ||
	     ( buf[bufpos]=='\r' && buf[bufpos+1]=='\n') ) bufpos+=2;
	else if ( buf[bufpos]=='\n' || buf[bufpos]=='\r' ) bufpos+=1; 
	*pbufpos = bufpos;
	return 1;
}
Esempio n. 17
0
static int
ssl_cert_digest(SSL* p_ssl, struct vsf_session* p_sess, struct mystr* p_str)
{
  X509* p_cert = SSL_get_peer_certificate(p_ssl);
  unsigned int num_bytes = 0;
  if (p_cert == NULL)
  {
    return 0;
  }
  str_reserve(p_str, EVP_MAX_MD_SIZE);
  str_empty(p_str);
  str_rpad(p_str, EVP_MAX_MD_SIZE);
  if (!X509_digest(p_cert, EVP_sha256(), (unsigned char*) str_getbuf(p_str),
                   &num_bytes))
  {
    die("X509_digest failed");
  }
  X509_free(p_cert);
  if (tunable_debug_ssl)
  {
    unsigned int i;
    str_alloc_text(&debug_str, "Cert digest:");
    for (i = 0; i < num_bytes; ++i)
    { 
      str_append_char(&debug_str, ' ');
      str_append_ulong(
        &debug_str, (unsigned long) (unsigned char) str_get_char_at(p_str, i));
    }
    vsf_log_line(p_sess, kVSFLogEntryDebug, &debug_str);
  }
  str_trunc(p_str, num_bytes);
  return 1;
}
Esempio n. 18
0
File: str.c Progetto: Einheri/wl500g
static void
str_split_text_common(struct mystr* p_src, struct mystr* p_rhs,
                      const char* p_text, int is_reverse)
{
  struct str_locate_result locate_result;
  unsigned int indexx;
  unsigned int search_len = vsf_sysutil_strlen(p_text);
  if (is_reverse)
  {
    locate_result = str_locate_text_reverse(p_src, p_text);
  }
  else
  {
    locate_result = str_locate_text(p_src, p_text);
  }
  /* Not found? */
  if (!locate_result.found)
  {
    str_empty(p_rhs);
    return;
  }
  indexx = locate_result.index;
  if (indexx + search_len > p_src->len)
  {
    bug("indexx invalid in str_split_text");
  } 
  /* Build rhs */
  private_str_alloc_memchunk(p_rhs, p_src->p_buf + indexx + search_len,
                             p_src->len - indexx - search_len);
  /* Build lhs */
  str_trunc(p_src, indexx);
}
Esempio n. 19
0
/* str_cpytodelim()
 *     term      = string of characters to be used as terminators
 *     finalstep = set to non-zero to position return value past the
 *                 terminating character
 */
char *
str_cpytodelim( str *s, char *p, const char *delim, unsigned char finalstep )
{
	assert( s );

	str_empty( s );
	return str_cattodelim( s, p, delim, finalstep );
}
Esempio n. 20
0
SqlSource Engine::sql_source_from_env(const String &id)
{
    SqlSource src;
    String url = env_cfg(_T("URL"));
    if (!str_empty(url))
        src = SqlSource(url);
    else
        src = SqlSource(_T(""),
            env_cfg(_T("DRIVER"), _T("DEFAULT")),
            env_cfg(_T("DBTYPE")), env_cfg(_T("DB")),
            env_cfg(_T("USER")), env_cfg(_T("PASSWD")));
    if (str_empty(id))
        src[_T("&id")] = src.format();
    else
        src[_T("&id")] = id;
    return src;
}
Esempio n. 21
0
void
str_strcpy( str *s, str *from )
{
	assert( s );
	assert( from );
	if ( s==from ) return;
	else if ( !from || from->len==0 ) str_empty( s );
	else str_strcpy_internal( s, from->data, from->len );
}
Esempio n. 22
0
void
str_next_dirent(struct mystr* p_filename_str, struct vsf_sysutil_dir* p_dir)
{
  const char* p_filename = vsf_sysutil_next_dirent(p_dir);
  str_empty(p_filename_str);
  if (p_filename != 0)
  {
    str_alloc_text(p_filename_str, p_filename);
  }
}
Esempio n. 23
0
void running_for_first_time (void) {
  check_type_sizes ();
  if (!str_empty (config_filename)) {
    return; // Do not create custom config file
  }
  if (str_empty (config_directory)) {
    config_directory = get_config_directory ();
  }
  tasprintf (&config_filename, "%s/%s", config_directory, CONFIG_FILE);
  config_filename = make_full_path (config_filename);
  if (!disable_output) {
    printf ("I: config dir=[%s]\n", config_directory);
  }
  // printf ("I: config file=[%s]\n", config_filename);

  int config_file_fd;
  //char *config_directory = get_config_directory ();
  //char *downloads_directory = get_downloads_directory ();

  if (!mkdir (config_directory, CONFIG_DIRECTORY_MODE)) {
    if (!disable_output) {
      printf ("[%s] created\n", config_directory);
    }
  }

  tfree_str (config_directory);
  config_directory = NULL;
  // see if config file is there
  if (access (config_filename, R_OK) != 0) {
    // config file missing, so touch it
    config_file_fd = open (config_filename, O_CREAT | O_RDWR, 0600);
    if (config_file_fd == -1)  {
      perror ("open[config_file]");
      printf ("I: config_file=[%s]\n", config_filename);
      exit (EXIT_FAILURE);
    }
    if (write (config_file_fd, DEFAULT_CONFIG_CONTENTS, strlen (DEFAULT_CONFIG_CONTENTS)) <= 0) {
      perror ("write[config_file]");
      exit (EXIT_FAILURE);
    }
    close (config_file_fd);
  }
}
Esempio n. 24
0
char *get_home_directory (void) {
  if (home_directory) { return home_directory; }
  home_directory = getenv("TELEGRAM_HOME");
  if (!str_empty (home_directory)) { return home_directory = tstrdup (home_directory); }
  home_directory = getenv("HOME");
  if (!str_empty (home_directory)) { return home_directory = tstrdup (home_directory); }
  struct passwd *current_passwd;
  uid_t user_id;
  setpwent ();
  user_id = getuid ();
  while ((current_passwd = getpwent ())) {
    if (current_passwd->pw_uid == user_id) {
      home_directory = tstrdup (current_passwd->pw_dir);
      break;
    }
  }
  endpwent ();
  if (str_empty (home_directory)) { home_directory = tstrdup ("."); }
  return home_directory;
}
Esempio n. 25
0
YBORM_DECL ElementTree::ElementPtr
data_object_to_etree(DataObject::Ptr data, const String &alt_name)
{
    const Table &table = data->table();
    String name = str_empty(alt_name)? table.xml_name(): alt_name;
    ElementTree::ElementPtr node = ElementTree::new_element(name);
    Columns::const_iterator it = table.begin(), end = table.end();
    for (; it != end; ++it) {
        const String col_name = it->xml_name();
        if (!str_empty(col_name) && _T("!") != col_name) {
            Value value = data->get(it->name());
            ElementTree::ElementPtr sub_el = node->sub_element(col_name);
            if (value.is_null())
                sub_el->attrib_[_T("is_null")] = _T("1");
            else
                sub_el->set_text(value.as_string());
        }
    }
    return node;
}
Esempio n. 26
0
void
str_copyposlen( str *s, str *in, unsigned long pos, unsigned long len )
{
	unsigned long i, max;
	assert( s );
	str_empty( s );
	max = pos+len;
	if ( max > in->len ) max = in->len;
	for ( i=pos; i<max; ++i )
		str_addchar( s, in->data[i] );
}
Esempio n. 27
0
LFSCProof* LFSCProofGeneric::Make( string str_pre, LFSCProof* sub_pf1, LFSCProof* sub_pf2, string str_post, bool db_str )
{
  vector< RefPtr< LFSCProof > > d_pfs;
  d_pfs.push_back( sub_pf1 );
  d_pfs.push_back( sub_pf2 );
  vector< string > d_strs;
  string str_empty(" ");
  d_strs.push_back( str_pre );
  d_strs.push_back( str_empty );
  d_strs.push_back( str_post );
  return new LFSCProofGeneric( d_pfs, d_strs, db_str );
}
Esempio n. 28
0
void
str_makepath( str *path, const char *dirname, const char *filename, char sep )
{
	assert( path );
	if ( dirname ) str_strcpyc( path, dirname );
	else str_empty( path );

	if ( path->len && path->data[path->len-1]!=sep )
		str_addchar( path, sep );

	if ( filename ) str_strcatc( path, filename );
}
Esempio n. 29
0
int main(int argc, char **argv) {
    Qiniu_RS_StatRet statRet;
    Qiniu_Client client;

    char *accessKey = getenv("QINIU_ACCESS_KEY");
    char *secretKey = getenv("QINIU_SECRET_KEY");
    char *bucket = getenv("QINIU_TEST_BUCKET");

    if (str_empty(accessKey) || str_empty(accessKey) || str_empty(bucket)) {
        printf("please fill `test-env.sh` and then run `source test-env.sh` first\n");
        return -1;
    }

    char *key = "qiniu.png";

    Qiniu_Mac mac;
    mac.accessKey = accessKey;
    mac.secretKey = secretKey;

    Qiniu_Use_Zone_Huadong(Qiniu_True);
    //init
    Qiniu_Client_InitMacAuth(&client, 1024, &mac);
    Qiniu_Error error = Qiniu_RS_Stat(&client, &statRet, bucket, key);
    if (error.code != 200) {
        printf("stat file %s:%s error.\n", bucket, key);
        debug_log(&client, error);
    } else {
        /*200, 正确返回了, 你可以通过statRet变量查询一些关于这个文件的信息*/
        printf("stat file \t%s:%s success.\n\n", bucket, key);
        printf("file hash: \t%s\n", statRet.hash);
        printf("file size: \t%lld\n", statRet.fsize);
        printf("file put time: \t%lld\n", statRet.putTime);
        printf("file mime type: \t%s\n", statRet.mimeType);
        printf("file type: \t%lld\n", statRet.type);
    }

    Qiniu_Client_Cleanup(&client);
}
Esempio n. 30
0
const unsigned char*
vsf_sysutil_parse_ipv6(const struct mystr* p_str)
{
  static struct mystr s_ret;
  static struct mystr s_rhs_ret;
  static struct mystr s_lhs_str;
  static struct mystr s_rhs_str;
  unsigned int lhs_len;
  unsigned int rhs_len;
  str_empty(&s_ret);
  str_empty(&s_rhs_ret);
  str_copy(&s_lhs_str, p_str);
  str_split_text(&s_lhs_str, &s_rhs_str, "::");
  if (!ipv6_parse_main(&s_ret, &s_lhs_str))
  {
    return 0;
  }
  if (!ipv6_parse_main(&s_rhs_ret, &s_rhs_str))
  {
    return 0;
  }
  lhs_len = str_getlen(&s_ret);
  rhs_len = str_getlen(&s_rhs_ret);
  if (lhs_len + rhs_len > 16)
  {
    return 0;
  }
  if (rhs_len > 0)
  {
    unsigned int add_nulls = 16 - (lhs_len + rhs_len);
    while (add_nulls--)
    {
      str_append_char(&s_ret, '\0');
    }
    str_append_str(&s_ret, &s_rhs_ret);
  }
  return (const unsigned char*) str_getbuf(&s_ret);
}