Exemple #1
0
PARROT_WARN_UNUSED_RESULT
PARROT_CAN_RETURN_NULL
PIOHANDLE
Parrot_io_internal_accept(PARROT_INTERP, PIOHANDLE os_handle, ARGOUT(PMC * remote_addr))
{
    Parrot_Socklen_t addr_len = sizeof (struct sockaddr_storage);
    struct sockaddr_storage *addr =
        (struct sockaddr_storage *)Parrot_gc_allocate_memory_chunk(interp,
                                        addr_len);
    Parrot_Sockaddr_attributes *sa_attrs = PARROT_SOCKADDR(remote_addr);
    PIOSOCKET newsock;

    newsock = accept((PIOSOCKET)os_handle, (struct sockaddr *)addr, &addr_len);

    if (newsock == PIO_INVALID_SOCKET)
        Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_PIO_ERROR,
                "accept failed: %Ss",
                Parrot_platform_strerror(interp, PIO_SOCK_ERRNO));

    sa_attrs->len     = addr_len;
    sa_attrs->pointer = addr;

    /* XXX FIXME: Need to do a getsockname and getpeername here to
     * fill in the sockaddr_in structs for local and peer */

    /* Optionally do a gethostbyaddr() to resolve remote IP address.
     * This should be based on an option set in the master socket */

    return (PIOHANDLE)newsock;
}
Exemple #2
0
int
main(int argc, const char **argv)
{
    PackFile   *pf;
    Interp     *interp;

    const char *file            = NULL;
    int         terse           = 0;
    int         disas           = 0;
    int         convert         = 0;
    int         nums_only       = 0;
    int         options         = PFOPT_UTILS;

    struct longopt_opt_info opt = LONGOPT_OPT_INFO_INIT;

    int         status;

    if (argc < 2)
        help();

    interp = Parrot_new(NULL);

    /* init and set top of stack */
    Parrot_init_stacktop(interp, &status);

    while ((status = longopt_get(interp, argc, argv, opt_options, &opt)) > 0) {
        switch (opt.opt_id) {
#if TRACE_PACKFILE
          case 'D':
            options += atoi(opt.opt_arg) << 2;
            break;
#endif
          case 'h':
            options += PFOPT_HEADERONLY;
            break;
          case 't':
            terse = 1;
            break;
          case 'd':
            disas = 1;
            break;
          case 'o':
            file    = opt.opt_arg;
            convert = 1;
            break;
          case 'n':
            nums_only = 1;
            break;
          case '?':
          default:
            help();
            break;
        }
    }

    if (status == -1)
        help();

    argc -= opt.opt_index;
    argv += opt.opt_index;

    pf = Parrot_pbc_read(interp, *argv, options);

    if (!pf) {
        printf("Can't read PBC\n");
        return 1;
    }

    Parrot_pbc_load(interp, pf);

    if (convert) {
        size_t   size  = PackFile_pack_size(interp,
                            interp->code->base.pf) * sizeof (opcode_t);
        opcode_t *pack = (opcode_t *)Parrot_gc_allocate_memory_chunk(interp,
                                        size);
        FILE *fp;

        if (!pack) {
            printf("out of mem\n");
            exit(EXIT_FAILURE);
        }

        PackFile_pack(interp, interp->code->base.pf, pack);

        if (STREQ(file, "-"))
            fp = stdout;
        else if ((fp = fopen(file, "wb")) == 0) {
            printf("Couldn't open %s\n", file);
            exit(EXIT_FAILURE);
        }

        if ((1 != fwrite(pack, size, 1, fp))) {
            printf("Couldn't write %s\n", file);
            exit(EXIT_FAILURE);
        }

        fclose(fp);
        Parrot_gc_free_memory_chunk(interp, pack);
        Parrot_exit(interp, 0);
    }

    if (!nums_only)
        PackFile_header_dump(interp, pf);

    if (options & PFOPT_HEADERONLY)
        Parrot_exit(interp, 0);

    /* install a dumper function */
    if (!terse) {
        pf->PackFuncs[PF_CONST_SEG].dump = const_dump;
    }

    if (disas)
        pf->PackFuncs[PF_BYTEC_SEG].dump = disas_dump;

    if (nums_only) {
        int i;

        for (i = PF_DIR_SEG + 1; i < PF_MAX_SEG; ++i)
            pf->PackFuncs[i].dump = null_dump;

        pf->PackFuncs[PF_DIR_SEG].dump   = null_dir_dump;
        pf->PackFuncs[PF_BYTEC_SEG].dump = nums_dump;
    }

    /* do a directory dump, which dumps segs then */
    PackFile_Segment_dump(interp, &pf->directory.base);

    Parrot_exit(interp, 0);
}
Exemple #3
0
PARROT_WARN_UNUSED_RESULT
PARROT_CANNOT_RETURN_NULL
PMC *
Parrot_io_internal_getaddrinfo(PARROT_INTERP, ARGIN(STRING *addr), INTVAL port,
        INTVAL protocol, INTVAL fam, INTVAL passive)
{
#ifdef PARROT_HAS_IPV6
    PMC *array;

    struct addrinfo hints;
    struct addrinfo *ai, *walk;
    /* We need to pass the port as a string (because you could also use a
     * service specification from /etc/services). The highest port is 65535,
     * so we need 5 characters + trailing null-byte. */
    char portstr[6];
    int  ret;

    /* convert Parrot's family to system family */
    if (fam < 0
    ||  fam >= PIO_PF_MAX
    || (fam = pio_pf[fam]) < 0)
        Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_PIO_ERROR,
                "unsupported protocol family: %ld", fam);

    memset(&hints, 0, sizeof (struct addrinfo));
    if (passive)
        hints.ai_flags = AI_PASSIVE;

    hints.ai_family   = fam;
    hints.ai_protocol = protocol;

    snprintf(portstr, sizeof (portstr), "%ld", port);

    {
        /* Limited scope for the C string to prevent mistakes */
        char *s = STRING_IS_NULL(addr)
                ? (char *) NULL
                : Parrot_str_to_cstring(interp, addr);
        ret = getaddrinfo(s, portstr, &hints, &ai);

        Parrot_str_free_cstring(s);
    }

    if (ret != 0)
        Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_PIO_ERROR,
                "getaddrinfo failed: %Ss: %Ss", addr,
                Parrot_platform_strerror(interp, PIO_SOCK_ERRNO));

    array = Parrot_pmc_new(interp, enum_class_ResizablePMCArray);

    for (walk = ai; walk; walk = walk->ai_next) {
        PMC *sockaddr = Parrot_pmc_new(interp, enum_class_Sockaddr);
        Parrot_Sockaddr_attributes *sa_attrs = PARROT_SOCKADDR(sockaddr);

        sa_attrs->family   = walk->ai_family;
        sa_attrs->type     = walk->ai_socktype;
        sa_attrs->protocol = walk->ai_protocol;
        sa_attrs->len      = walk->ai_addrlen;
        sa_attrs->pointer  = Parrot_gc_allocate_memory_chunk(interp,
                                    walk->ai_addrlen);

        memcpy(sa_attrs->pointer, walk->ai_addr, walk->ai_addrlen);

        VTABLE_push_pmc(interp, array, sockaddr);
    }

    freeaddrinfo(ai);

    return array;

#else /* PARROT_HAS_IPV6 */

    const char *host;
    char *cstring;
    int   success;
    PMC  *sockaddr;
    PMC  *array;

    const size_t addr_len = sizeof (struct sockaddr_in);
    struct sockaddr_in *sa;

    Parrot_Sockaddr_attributes *sa_attrs;

    sa       = (struct sockaddr_in *)Parrot_gc_allocate_memory_chunk(interp,
                                            addr_len);
    sockaddr = Parrot_pmc_new(interp, enum_class_Sockaddr);
    sa_attrs = PARROT_SOCKADDR(sockaddr);

    sa_attrs->family   = PF_INET;
    sa_attrs->type     = 0;
    sa_attrs->protocol = 0;
    sa_attrs->len      = addr_len;
    sa_attrs->pointer  = sa;

    if (STRING_IS_NULL(addr)) {
        cstring = NULL;
        host    = "127.0.0.1";
    }
    else {
        cstring = Parrot_str_to_cstring(interp, addr);
        host    = cstring;
    }

#  ifdef _WIN32
    sa->sin_addr.S_un.S_addr = inet_addr(host);
    success = sa->sin_addr.S_un.S_addr != -1;
#  else
#    ifdef PARROT_DEF_INET_ATON
    success = inet_aton(host, &sa->sin_addr) != 0;
#    else
    /* positive retval is success */
    success = inet_pton(PF_INET, host, &sa->sin_addr) > 0;
#    endif
#  endif

    if (!success) {
        /* Maybe it is a hostname, try to lookup */
        /* XXX Check PIO option before doing a name lookup,
         * it may have been toggled off.
         */
        const struct hostent * const he = gethostbyname(host);

        if (!he) {
            if (cstring)
                Parrot_str_free_cstring(cstring);
            Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_PIO_ERROR,
                    "getaddrinfo failed: %s", host);
        }

        memcpy((char*)&sa->sin_addr, he->h_addr, sizeof (sa->sin_addr));
    }

    if (cstring)
        Parrot_str_free_cstring(cstring);

    sa->sin_family = PF_INET;
    sa->sin_port = htons(port);

    array = Parrot_pmc_new(interp, enum_class_ResizablePMCArray);
    VTABLE_push_pmc(interp, array, sockaddr);

    return array;
#endif /* PARROT_HAS_IPV6 */
}