* Converted line endings to LF. master
authorUrban Wallasch <urban.wallasch@freenet.de>
Fri, 1 Jun 2018 13:25:52 +0000 (15:25 +0200)
committerUrban Wallasch <urban.wallasch@freenet.de>
Fri, 1 Jun 2018 13:25:52 +0000 (15:25 +0200)
fident.c

index 16c52775c18091667bdb7615988170329233dbe2..23362d34e7ddb83ba894b8df1d1c8dd4117d3052 100644 (file)
--- a/fident.c
+++ b/fident.c
-#define _DEFAULT_SOURCE\r
-\r
-#include <sys/types.h>\r
-#include <sys/socket.h>\r
-\r
-#include <errno.h>\r
-#include <stdint.h>\r
-#include <inttypes.h>\r
-#include <stdio.h>\r
-#include <stdlib.h>\r
-#include <string.h>\r
-#include <ctype.h>\r
-#include <unistd.h>\r
-#include <pwd.h>\r
-#include <grp.h>\r
-#include <pthread.h>\r
-#include <netdb.h>\r
-#include <netinet/in.h>\r
-#include <arpa/inet.h>\r
-\r
-\r
-#ifdef DEBUG\r
-    #define DPRINT(...)    do{ fprintf( stderr, __VA_ARGS__ ); }while(0)\r
-#else\r
-    #define DPRINT(...)    do{;}while(0)\r
-#endif\r
-\r
-typedef\r
-    struct {\r
-        int sd;\r
-        struct sockaddr_in addr;\r
-        socklen_t addrlen;\r
-    }\r
-    srvarg_t;\r
-\r
-static void die( const char *msg )\r
-{\r
-    perror( msg );\r
-    exit( EXIT_FAILURE );\r
-}\r
-\r
-static void droproot( const char *uname, const char *gname )\r
-{\r
-    const struct group *gr = getgrnam( gname );\r
-    const struct passwd *pw = getpwnam( uname );\r
-\r
-    if ( NULL == gr )\r
-        die( gname );\r
-    if ( NULL == pw )\r
-        die( uname );\r
-\r
-    const gid_t newgid = gr->gr_gid;\r
-    const uid_t newuid = pw->pw_uid;\r
-    const gid_t oldgid = getegid();\r
-    const uid_t olduid = geteuid();\r
-\r
-    if ( 0 == olduid )\r
-        setgroups( 1, &newgid );\r
-    if ( newgid != oldgid && 0 != setregid( newgid, newgid ) )\r
-        die( "setregid" );\r
-    if ( newuid != olduid && 0 != setreuid( newuid, newuid ) )\r
-        die( "setreuid" );\r
-\r
-    /* Check by trying to regain old IDs: */\r
-    if ( newgid != oldgid && ( 0 == setegid( oldgid ) || getegid() != newgid ) )\r
-        die( "setegid" );\r
-    if ( newuid != olduid && ( 0 == seteuid( olduid ) || geteuid() != newuid ) )\r
-        die( "seteuid" );\r
-\r
-    DPRINT( "EGID=%d, EUID=%d\n", getegid(), geteuid() );\r
-}\r
-\r
-\r
-// #define DFLT_MSG "ERROR : UNKNOWN-ERROR"\r
-#define DFLT_MSG "USERID : OTHER : UNKNOWN"\r
-\r
-static void *servlet( void *parg )\r
-{\r
-    srvarg_t *arg = parg;\r
-    uint16_t ps = 0, pc = 0;\r
-    int sd = arg->sd;\r
-    ssize_t rb = 0;\r
-    char buf[200] = "";\r
-    char rsp[400] = "";\r
-    char *ep = NULL;\r
-    struct timeval timeout;\r
-\r
-    timeout.tv_sec = 3;\r
-    timeout.tv_usec = 0;\r
-    setsockopt( sd, SOL_SOCKET, SO_RCVTIMEO, &timeout, sizeof timeout );\r
-    DPRINT( "(%s:%d) ", inet_ntoa( arg->addr.sin_addr ), (int)arg->addr.sin_port );\r
-    rb = recv( sd, buf, sizeof buf - 1, 0 );\r
-    if ( 0 < rb )\r
-    {\r
-        buf[rb] = '\0';\r
-        ep = buf;\r
-        while ( *ep )\r
-            if ( '\r' == *ep || '\n' == *ep )\r
-                *ep = '\0';\r
-            else\r
-                ++ep;\r
-        DPRINT( "[%s] ", buf );\r
-        if ( 2 == sscanf( buf, "%"SCNu16" ,%"SCNu16" ", &ps, &pc )\r
-            && 0 < snprintf( rsp, sizeof rsp, "%"PRIu16" , %"PRIu16" : %s\r\n", ps, pc, DFLT_MSG ) )\r
-        {\r
-            DPRINT( "%s", rsp );\r
-            send( sd, rsp, strlen( rsp ), 0 );\r
-        }\r
-    }\r
-    DPRINT( "%s", *rsp ? "" : "\n" );\r
-    close( sd );\r
-    free( parg );\r
-    return 0;\r
-}\r
-\r
-int main( int argc, char *argv[] )\r
-{\r
-    struct sockaddr_in addr;\r
-    int sd, port;\r
-    const int enable = 1;\r
-\r
-    if ( argc != 2 )\r
-    {\r
-        fprintf( stderr, "usage: %s <protocol or portnum>\n", argv[0] );\r
-        exit( EXIT_FAILURE );\r
-    }\r
-\r
-    if ( !isdigit( argv[1][0] ) )\r
-    {\r
-        struct servent *srv = getservbyname( argv[1], "tcp" );\r
-        if ( srv == NULL )\r
-            die( argv[1] );\r
-        DPRINT( "%s: port=%d\n", srv->s_name, ntohs( srv->s_port ) );\r
-        port = srv->s_port;\r
-    }\r
-    else\r
-    {\r
-        port = atoi( argv[1] );\r
-        DPRINT( "port=%d\n", port );\r
-        port = htons( port );\r
-    }\r
-\r
-    sd = socket( PF_INET, SOCK_STREAM, 0 );\r
-    if ( sd < 0 )\r
-        die( "socket" );\r
-    if ( 0 > setsockopt( sd, SOL_SOCKET, SO_REUSEADDR, &enable, sizeof enable ) )\r
-        die( "setsockopt(SO_REUSEADDR)" );\r
-\r
-    memset( &addr, 0, sizeof addr );\r
-    addr.sin_family = AF_INET;\r
-    addr.sin_port = port;\r
-    addr.sin_addr.s_addr = INADDR_ANY;\r
-    if ( bind( sd, (struct sockaddr*)&addr, sizeof addr ) != 0 )\r
-        die( "bind" );\r
-\r
-    droproot( "nobody", "nogroup" );\r
-\r
-    if ( listen( sd, 10 ) != 0 )\r
-        die( "listen" );\r
-\r
-    puts( "" );\r
-\r
-    while ( 1 )\r
-    {\r
-        int csd;\r
-        socklen_t addrlen = sizeof addr;\r
-\r
-        if ( 0 > ( csd = accept( sd, (struct sockaddr *)&addr, &addrlen ) ) )\r
-        {\r
-            switch ( errno )\r
-            {\r
-                case EBADF:\r
-                case EFAULT:\r
-                case EINVAL:\r
-                case ENOTSOCK:\r
-                case EOPNOTSUPP:\r
-                case EPROTO:\r
-                    die( "accept" );\r
-                    break;\r
-                default:\r
-                    break;\r
-            }\r
-        }\r
-        else\r
-        {\r
-            srvarg_t *parg;\r
-            pthread_t child;\r
-\r
-            if ( NULL != ( parg = malloc( sizeof *parg ) ) )\r
-            {\r
-                if ( sizeof addr < addrlen )\r
-                    addrlen = sizeof addr;\r
-                memcpy( &parg->addr, &addr, addrlen );\r
-                parg->addrlen = addrlen;\r
-                parg->sd = csd;\r
-                if ( 0 != pthread_create( &child, 0, servlet, (void *)parg ) )\r
-                    free( parg );\r
-                else /* parg is free'd in child! */\r
-                    pthread_detach( child );\r
-            }\r
-        }\r
-        sleep( 1 );  /* hard throttle */\r
-    }\r
-}\r
+#define _DEFAULT_SOURCE
+
+#include <sys/types.h>
+#include <sys/socket.h>
+
+#include <errno.h>
+#include <stdint.h>
+#include <inttypes.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <ctype.h>
+#include <unistd.h>
+#include <pwd.h>
+#include <grp.h>
+#include <pthread.h>
+#include <netdb.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+
+
+#ifdef DEBUG
+    #define DPRINT(...)    do{ fprintf( stderr, __VA_ARGS__ ); }while(0)
+#else
+    #define DPRINT(...)    do{;}while(0)
+#endif
+
+typedef
+    struct {
+        int sd;
+        struct sockaddr_in addr;
+        socklen_t addrlen;
+    }
+    srvarg_t;
+
+static void die( const char *msg )
+{
+    perror( msg );
+    exit( EXIT_FAILURE );
+}
+
+static void droproot( const char *uname, const char *gname )
+{
+    const struct group *gr = getgrnam( gname );
+    const struct passwd *pw = getpwnam( uname );
+
+    if ( NULL == gr )
+        die( gname );
+    if ( NULL == pw )
+        die( uname );
+
+    const gid_t newgid = gr->gr_gid;
+    const uid_t newuid = pw->pw_uid;
+    const gid_t oldgid = getegid();
+    const uid_t olduid = geteuid();
+
+    if ( 0 == olduid )
+        setgroups( 1, &newgid );
+    if ( newgid != oldgid && 0 != setregid( newgid, newgid ) )
+        die( "setregid" );
+    if ( newuid != olduid && 0 != setreuid( newuid, newuid ) )
+        die( "setreuid" );
+
+    /* Check by trying to regain old IDs: */
+    if ( newgid != oldgid && ( 0 == setegid( oldgid ) || getegid() != newgid ) )
+        die( "setegid" );
+    if ( newuid != olduid && ( 0 == seteuid( olduid ) || geteuid() != newuid ) )
+        die( "seteuid" );
+
+    DPRINT( "EGID=%d, EUID=%d\n", getegid(), geteuid() );
+}
+
+
+// #define DFLT_MSG "ERROR : UNKNOWN-ERROR"
+#define DFLT_MSG "USERID : OTHER : UNKNOWN"
+
+static void *servlet( void *parg )
+{
+    srvarg_t *arg = parg;
+    uint16_t ps = 0, pc = 0;
+    int sd = arg->sd;
+    ssize_t rb = 0;
+    char buf[200] = "";
+    char rsp[400] = "";
+    char *ep = NULL;
+    struct timeval timeout;
+
+    timeout.tv_sec = 3;
+    timeout.tv_usec = 0;
+    setsockopt( sd, SOL_SOCKET, SO_RCVTIMEO, &timeout, sizeof timeout );
+    DPRINT( "(%s:%d) ", inet_ntoa( arg->addr.sin_addr ), (int)arg->addr.sin_port );
+    rb = recv( sd, buf, sizeof buf - 1, 0 );
+    if ( 0 < rb )
+    {
+        buf[rb] = '\0';
+        ep = buf;
+        while ( *ep )
+            if ( '\r' == *ep || '\n' == *ep )
+                *ep = '\0';
+            else
+                ++ep;
+        DPRINT( "[%s] ", buf );
+        if ( 2 == sscanf( buf, "%"SCNu16" ,%"SCNu16" ", &ps, &pc )
+            && 0 < snprintf( rsp, sizeof rsp, "%"PRIu16" , %"PRIu16" : %s\r\n", ps, pc, DFLT_MSG ) )
+        {
+            DPRINT( "%s", rsp );
+            send( sd, rsp, strlen( rsp ), 0 );
+        }
+    }
+    DPRINT( "%s", *rsp ? "" : "\n" );
+    close( sd );
+    free( parg );
+    return 0;
+}
+
+int main( int argc, char *argv[] )
+{
+    struct sockaddr_in addr;
+    int sd, port;
+    const int enable = 1;
+
+    if ( argc != 2 )
+    {
+        fprintf( stderr, "usage: %s <protocol or portnum>\n", argv[0] );
+        exit( EXIT_FAILURE );
+    }
+
+    if ( !isdigit( argv[1][0] ) )
+    {
+        struct servent *srv = getservbyname( argv[1], "tcp" );
+        if ( srv == NULL )
+            die( argv[1] );
+        DPRINT( "%s: port=%d\n", srv->s_name, ntohs( srv->s_port ) );
+        port = srv->s_port;
+    }
+    else
+    {
+        port = atoi( argv[1] );
+        DPRINT( "port=%d\n", port );
+        port = htons( port );
+    }
+
+    sd = socket( PF_INET, SOCK_STREAM, 0 );
+    if ( sd < 0 )
+        die( "socket" );
+    if ( 0 > setsockopt( sd, SOL_SOCKET, SO_REUSEADDR, &enable, sizeof enable ) )
+        die( "setsockopt(SO_REUSEADDR)" );
+
+    memset( &addr, 0, sizeof addr );
+    addr.sin_family = AF_INET;
+    addr.sin_port = port;
+    addr.sin_addr.s_addr = INADDR_ANY;
+    if ( bind( sd, (struct sockaddr*)&addr, sizeof addr ) != 0 )
+        die( "bind" );
+
+    droproot( "nobody", "nogroup" );
+
+    if ( listen( sd, 10 ) != 0 )
+        die( "listen" );
+
+    puts( "" );
+
+    while ( 1 )
+    {
+        int csd;
+        socklen_t addrlen = sizeof addr;
+
+        if ( 0 > ( csd = accept( sd, (struct sockaddr *)&addr, &addrlen ) ) )
+        {
+            switch ( errno )
+            {
+                case EBADF:
+                case EFAULT:
+                case EINVAL:
+                case ENOTSOCK:
+                case EOPNOTSUPP:
+                case EPROTO:
+                    die( "accept" );
+                    break;
+                default:
+                    break;
+            }
+        }
+        else
+        {
+            srvarg_t *parg;
+            pthread_t child;
+
+            if ( NULL != ( parg = malloc( sizeof *parg ) ) )
+            {
+                if ( sizeof addr < addrlen )
+                    addrlen = sizeof addr;
+                memcpy( &parg->addr, &addr, addrlen );
+                parg->addrlen = addrlen;
+                parg->sd = csd;
+                if ( 0 != pthread_create( &child, 0, servlet, (void *)parg ) )
+                    free( parg );
+                else /* parg is free'd in child! */
+                    pthread_detach( child );
+            }
+        }
+        sleep( 1 );  /* hard throttle */
+    }
+}