+
+// === HELPERS ===
+int sendf(int Socket, const char *Format, ...)
+{
+ va_list args;
+ int len;
+
+ va_start(args, Format);
+ len = vsnprintf(NULL, 0, Format, args);
+ va_end(args);
+
+ {
+ char buf[len+1];
+ va_start(args, Format);
+ vsnprintf(buf, len+1, Format, args);
+ va_end(args);
+
+ return send(Socket, buf, len, 0);
+ }
+}
+
+int OpenConnection(const char *Host, int Port)
+{
+ struct hostent *host;
+ struct sockaddr_in serverAddr;
+ int sock;
+
+ host = gethostbyname(Host);
+ if( !host ) {
+ fprintf(stderr, "Unable to look up '%s'\n", Host);
+ return -1;
+ }
+
+ memset(&serverAddr, 0, sizeof(serverAddr));
+
+ serverAddr.sin_family = AF_INET; // IPv4
+ // NOTE: I have a suspicion that IPv6 will play sillybuggers with this :)
+ serverAddr.sin_addr.s_addr = *((unsigned long *) host->h_addr_list[0]);
+ serverAddr.sin_port = htons(Port);
+
+ sock = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);
+ if( sock < 0 ) {
+ fprintf(stderr, "Failed to create socket\n");
+ return -1;
+ }
+
+ #if USE_AUTOAUTH
+ {
+ struct sockaddr_in localAddr;
+ memset(&localAddr, 0, sizeof(localAddr));
+ localAddr.sin_family = AF_INET; // IPv4
+ localAddr.sin_port = 1023; // IPv4
+ // Attempt to bind to low port for autoauth
+ bind(sock, &localAddr, sizeof(localAddr));
+ }
+ #endif
+
+ if( connect(sock, (struct sockaddr *) &serverAddr, sizeof(serverAddr)) < 0 ) {
+ fprintf(stderr, "Failed to connect to server\n");
+ return -1;
+ }
+
+ return sock;
+}
+
+void Authenticate(int Socket)
+{
+ struct passwd *pwd;
+ char buf[512];
+ int responseCode;
+
+ // Get user name
+ pwd = getpwuid( getuid() );
+
+ // Attempt automatic authentication
+ sendf(Socket, "AUTOAUTH %s\n", pwd->pw_name);
+
+ // Check if it worked
+ recv(Socket, buf, 511, 0);
+ trim(buf);
+
+ responseCode = atoi(buf);
+ switch( responseCode )
+ {
+ case 200: // Authenticated, return :)
+ return ;
+ case 401: // Untrusted, attempt password authentication
+ break;
+ case 404: // Bad Username
+ fprintf(stderr, "Bad Username '%s'\n", pwd->pw_name);
+ exit(-1);
+ default:
+ fprintf(stderr, "Unkown response code %i from server\n", responseCode);
+ printf("%s\n", buf);
+ exit(-1);
+ }
+
+ printf("%s\n", buf);
+}
+
+char *trim(char *string)
+{
+ int i;
+
+ while( isspace(*string) )
+ string ++;
+
+ for( i = strlen(string); i--; )
+ {
+ if( isspace(string[i]) )
+ string[i] = '\0';
+ else
+ break;
+ }
+
+ return string;
+}
+
+int RunRegex(regex_t *regex, const char *string, int nMatches, regmatch_t *matches, const char *errorMessage)
+{
+ int ret;
+
+ ret = regexec(regex, string, nMatches, matches, 0);
+ if( ret ) {
+ size_t len = regerror(ret, regex, NULL, 0);
+ char errorStr[len];
+ regerror(ret, regex, errorStr, len);
+ printf("string = '%s'\n", string);
+ fprintf(stderr, "%s\n%s", errorMessage, errorStr);
+ exit(-1);
+ }
+
+ return ret;
+}
+
+void CompileRegex(regex_t *regex, const char *pattern, int flags)
+{
+ int ret = regcomp(regex, pattern, flags);
+ if( ret ) {
+ size_t len = regerror(ret, regex, NULL, 0);
+ char errorStr[len];
+ regerror(ret, regex, errorStr, len);
+ fprintf(stderr, "Regex compilation failed - %s\n", errorStr);
+ exit(-1);
+ }
+}