/**************************************************************************/ // File: cvsserve.cpp /**************************************************************************/ // - This can be used to setup a cvs repository without having root access // - Molded into shape from an example inetd server by Kalahn // compile with: g++ -o cvsserve cvsserve.cpp #define SERV_TCP_PORT 2401 // default port #define CVS_PATH "/usr/bin/" #define CVS_ROOT "/dawn/cvsroot" #include <stdio.h> #include <stdlib.h> #include <ctype.h> #include <sys/types.h> #include <sys/socket.h> #include <netinet/in.h> #include <arpa/inet.h> #include <unistd.h> #include <string.h> #include <sys/types.h> #include <sys/socket.h> #include <signal.h> char *portnum; #define IS_NULLSTR(str) ((str)==NULL || (str)[0]=='\0') /**************************************************************************/ bool is_number( char *arg ) { if ( *arg == '\0' ) return false; if ( *arg == '+' || *arg == '-' ) arg++; for ( ; *arg != '\0'; arg++ ) { if ( !isdigit( *arg ) ) return false; } return true; } /**************************************************************************/ main(int argc, char *argv[], char **envp) { int sockfd, newsockfd, childpid; unsigned int clilen; struct sockaddr_in cli_addr, serv_addr; int port; port=SERV_TCP_PORT; portnum = argv[1]; if ((sockfd = socket (AF_INET,SOCK_STREAM,0)) <0) { fprintf(stderr, "error: can't open stream socket\r\n"); exit(0); } if(!IS_NULLSTR(portnum)){ if(is_number(portnum)){ port=atoi(portnum); }else{ fprintf(stderr, "syntax %s [portnumber]\r\n", argv[0]); exit(0); } } bzero((char *) &serv_addr, sizeof(serv_addr)); serv_addr.sin_family = AF_INET; serv_addr.sin_addr.s_addr = htonl(INADDR_ANY); serv_addr.sin_port = htons(port); if (bind(sockfd, (struct sockaddr *) &serv_addr, sizeof(serv_addr)) < 0) { fprintf(stderr, "error: can't bind local address to port %d!\r\n", port); exit(0); } listen (sockfd, 5); signal(SIGCLD, SIG_IGN); for ( ; ; ) { clilen = sizeof(cli_addr); newsockfd = accept(sockfd, (struct sockaddr * ) &cli_addr,&clilen); if (newsockfd < 0) { fprintf(stderr, "error: accept error\r\n"); exit(0); } if ((childpid = fork()) < 0) { close(sockfd); fprintf(stderr, "error: fork error\r\n"); exit(0); } else if (childpid == 0) { signal(SIGCLD, SIG_DFL); close (sockfd); close(0); close(1); close(2); dup(newsockfd); dup(newsockfd); dup(newsockfd); (void) execlp (CVS_PATH "cvs","cvs","--allow-root=" CVS_ROOT,"pserver",NULL); close (newsockfd); exit(0); } close (newsockfd); } } /**************************************************************************/ // compile with: g++ -o cvsserve cvsserve.cpp // change the #defines at the top to customise default port etc /**************************************************************************/