Help - Search - Members - Calendar
Full Version: Somebody with C skills here?
[splatterladder] Board > --:: gEnErAl ::-- > Chat
schnoog
Hi,

I need somebody with C skills to change a programm-source to accept command-line parameters.

The default source is

q3ms.c
CODE
/*

Original by Luigi Auriemma

*/


#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>

#ifdef WIN32
    #include <winsock.h>
    #include "winerr.h"

    #define    close    closesocket
    #define sleep   Sleep
    #define ONESEC  1000
#else
    #include <unistd.h>
    #include <sys/socket.h>
    #include <sys/types.h>
    #include <arpa/inet.h>
    #include <netdb.h>

    #define ONESEC  1
#endif



#define VER     "0.1"
#define BUFFSZ  4096
#define MS      "master.quake3arena.com"
#define MSPORT  27950
#define REQ     "\xff\xff\xff\xff" \
                "getservers 68\n"
#define TIMEOUT 5



int timeout(int sock);
u_int resolv(char *host);
void std_err(void);



int main(int argc, char *argv[]) {
    struct    sockaddr_in     peer;
    int        sd,
            err,
            rlen,
            i,
            tot = 0;
    u_char  *buff,
            *ptr;
    u_int  ip;
    u_short port;

#ifdef WIN32
    WSADATA    wsadata;
    WSAStartup(MAKEWORD(2,0), &wsadata);
#endif


    setbuf(stdout, NULL);


    peer.sin_addr.s_addr = resolv(MS);
    peer.sin_port        = htons(MSPORT);
    peer.sin_family      = AF_INET;
    rlen                 = sizeof(peer);

    buff = malloc(BUFFSZ + 1);
    if(!buff) std_err();

    sd = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
    if(sd < 0) std_err();

    fputs("Contacting "MS"\n", stdout);
    err = sendto(sd, REQ, sizeof(REQ) - 1, 0, (struct sockaddr *)&peer, rlen);
    if(err < 0) std_err();

    fputs("\n"
        "IP                QUERY-PORT\n"
        "============================\n", stdout);
    while(1) {
        err = timeout(sd);
        if(err < 0) break;
        err = recvfrom(sd, buff, BUFFSZ, 0, (struct sockaddr *)&peer, &rlen);
        if(err < 0) std_err();
        if(!err) break;

        if(memcmp(buff + 4, "getserversResponse", 18)) break;

        i = 23;             /* 4 (ffffffff) + 18 (get..) + 1 (\) */
        ptr = buff + 23;
        while(i < err) {
            if(!memcmp(ptr, "EOT", 3)) break;
            ip = *(u_int *)ptr;
            port = *(u_short *)(ptr + 4);
            printf("%15s   %hu\n",
                inet_ntoa(*(struct in_addr *)&ip),
                htons(port));
            ptr += 7;
            i += 7;
            tot++;
        }
    }

    close(sd);

    printf("\nTotal servers found: %d\n\n", tot);

    return(0);
}



int timeout(int sock) {
    struct    timeval    tout;
    fd_set    fd_read;
    int    err;

    tout.tv_sec = TIMEOUT;
    tout.tv_usec = 0;
    FD_ZERO(&fd_read);
    FD_SET(sock, &fd_read);
    err = select(sock + 1, &fd_read, NULL, NULL, &tout);
    if(err < 0) std_err();
    if(!err) return(-1);
    return(0);
}



u_int resolv(char *host) {
    struct        hostent    *hp;
    u_int        host_ip;

    host_ip = inet_addr(host);
    if(host_ip == INADDR_NONE) {
        hp = gethostbyname(host);
        if(!hp) {
            printf("\nError: Unable to resolv hostname (%s)\n", host);
            exit(1);
        } else host_ip = *(u_int *)(hp->h_addr);
    }
    return(host_ip);
}



#ifndef WIN32
    void std_err(void) {
        perror("\nError");
        exit(1);
    }
#endif


I need to modify this code, to accept the following command-line parameters instead of using pre-compiled constants

MS (for example etmaster.idsoftware.com)
MSPORT ( for example 27950 )

and also to change
REQ to substitute "68" with a third parameter
CODE
#define REQ     "\xff\xff\xff\xff" \
                "getservers 68\n"

for example "84 full empty"

What I want is to compile this code and run it with
binary etmaster.idsoftware.com 27950 "84 full empty"


I have no clue about C and hopefully someone is able to modify this code for me.

Thanks alot


$mart
Hey you can ask UUS another maestro like you xD
$mart
UUS says :

"Here is the modified code:

CODE
  /*

Original by Luigi Auriemma

*/


#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>

#ifdef WIN32
    #include <winsock.h>
    #include "winerr.h"

    #define    close    closesocket
    #define sleep   Sleep
    #define ONESEC  1000
#else
    #include <unistd.h>
    #include <sys/socket.h>
    #include <sys/types.h>
    #include <arpa/inet.h>
    #include <netdb.h>

    #define ONESEC  1
#endif



#define VER     "0.1-modified"
#define BUFFSZ  4096
/*#define MS      "master.quake3arena.com"
#define MSPORT  27950
*/
#define REQ     "\xff\xff\xff\xff" \
                "getservers 68\n"
#define TIMEOUT 5



int timeout(int sock);
u_int resolv(char *host);
void std_err(void);



void usage(char *progname) {
    printf ("Usage:\t%s  master_addr master_port request\n\n\t\tmaster_addr:\thostname (not IP) of master server\n\
\t\tmaster_port:\tmaster port to connect to\n\t\trequest:\trequest\n",progname);
}

int parse_escape(char *s,char *out)
{
    int i=0;
    unsigned char *ptr=s,ch,sn[3],c;

    sn[2]=0;
    while (*ptr)
    {
        c = ch = *ptr++;
        if (iscntrl(ch) || ch == '\\' || ch == '\"' || ch == '\'') {
       ch = *ptr++;
       switch(ch) {
         case 'n': c='\n'; break;
         case 'r': c='\r'; break;
         case 't': c='\t'; break;
         case '\\': c='\\'; break;
         case 'x':
        memcpy(sn,ptr,2);
        c=strtol(sn, (char **) NULL, 16);
        ptr+=2;
        break;
           }
    }
//printf ("%c", c);
       out[i++]=c;
    }
    out[i]=0;
}
int main(int argc, char *argv[]) {
    struct    sockaddr_in     peer;
    int        sd,
            err,
            rlen,
            i,
            tot = 0;
    u_char  *buff,
            *ptr;
    u_int  ip;
    u_short port,master_port;
    char *master,*request;

#ifdef WIN32
    WSADATA    wsadata;
    WSAStartup(MAKEWORD(2,0), &wsadata);
#endif


    setbuf(stdout, NULL);

    
    if (argc<3) {
    usage(argv[0]);
    exit(1);
    }

    master=argv[1];
    master_port=atoi(argv[2]);
    request=argv[3];

    peer.sin_addr.s_addr = resolv(master);
    peer.sin_port        = htons(master_port);
    peer.sin_family      = AF_INET;
    rlen                 = sizeof(peer);

    buff = malloc(BUFFSZ + 1);
    if(!buff) std_err();

    sd = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
    if(sd < 0) std_err();

    printf("Contacting %s\n", master);
    char realrequest[128];
    parse_escape(request,realrequest);
    err = sendto(sd, realrequest, strlen(realrequest), 0, (struct sockaddr *)&peer, rlen);
    if(err < 0) std_err();

    fputs("\n"
        "IP                QUERY-PORT\n"
        "============================\n", stdout);
    while(1) {
        err = timeout(sd);
        if(err < 0) break;
        err = recvfrom(sd, buff, BUFFSZ, 0, (struct sockaddr *)&peer, &rlen);
        if(err < 0) std_err();
        if(!err) break;

        if(memcmp(buff + 4, "getserversResponse", 18)) break;

        i = 23;             /* 4 (ffffffff) + 18 (get..) + 1 (\) */
        ptr = buff + 23;
        while(i < err) {
            if(!memcmp(ptr, "EOT", 3)) break;
            ip = *(u_int *)ptr;
            port = *(u_short *)(ptr + 4);
            printf("%15s   %hu\n",
                inet_ntoa(*(struct in_addr *)&ip),
                htons(port));
            ptr += 7;
            i += 7;
            tot++;
        }
    }

    close(sd);

    printf("\nTotal servers found: %d\n\n", tot);

    return(0);
}



int timeout(int sock) {
    struct    timeval    tout;
    fd_set    fd_read;
    int    err;

    tout.tv_sec = TIMEOUT;
    tout.tv_usec = 0;
    FD_ZERO(&fd_read);
    FD_SET(sock, &fd_read);
    err = select(sock + 1, &fd_read, NULL, NULL, &tout);
    if(err < 0) std_err();
    if(!err) return(-1);
    return(0);
}



u_int resolv(char *host) {
    struct        hostent    *hp;
    u_int        host_ip;

    host_ip = inet_addr(host);
    if(host_ip == INADDR_NONE) {
        hp = gethostbyname(host);
        if(!hp) {
            printf("\nError: Unable to resolv hostname (%s)\n", host);
            exit(1);
        } else host_ip = *(u_int *)(hp->h_addr);
    }
    return(host_ip);
}



#ifndef WIN32
    void std_err(void) {
        perror("\nError");
        exit(1);
    }
#endif


To call it : ./splatter master.quake3arena.com 27950 "\xff\xff\xff\xffgetservers 68\n"

Now, I don't know the protocol, so, according to me, the things'sent need also to be modified if he wants to modify the request. Because the sequences \xff must have a meaning ... I guess IP adresses ? Well $mart, I don't know what he wants to do"


Schnoog, I hope it helps you grin.gif
V55 $mart
schnoog
thanks alot :)
This is a "lo-fi" version of our main content. To view the full version with more information, formatting and images, please click here.
Invision Power Board © 2001-2024 Invision Power Services, Inc.