Tiny programs (C, C++, C#, ...)
File detail
Source code
/*
* file: net_client.c - TCP layer encapsulation
* project: nntpbackup (ISA)
* By Kamil Dudka, xdudka00
* mailto: xdudka00@gmail.com
* Note: This modul was primarily developed for project BSD sockets (IPK)
*/
#include <stdlib.h>
#include <stdio.h>
#include <strings.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <sys/stat.h>
#include <signal.h>
#include <fcntl.h>
#include <unistd.h>
#include <string.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netdb.h>
#include <errno.h>
#include <ctype.h>
#include <sys/socket.h>
#include "tcp_client.h"
/*
* TCP I/O private data (initialized by netLineInit ())
*/
struct NetLine {
unsigned defLineLength;
unsigned cbBuff;
char *pBuff;
TSocket sockfd;
};
static inline int readChar (int sockfd, char *);
static inline int writeBlock (int sockfd, const char *, size_t);
/*
* Connect to remote server
* Set sockfd in *pSock
* Return 0 if no error occur
*/
int netConnect (const char *serverName, unsigned portNumber, TSocket *pSock) {
// Server address
struct sockaddr_in sa;
bzero (&sa, sizeof (sa));
sa.sin_family = PF_INET;
sa.sin_port = htons (portNumber);
// Deteremine type of addr (IP/URL)
if (isdigit(*serverName)) {
// Direct IP adress
if (0>= inet_pton (PF_INET, serverName, &sa.sin_addr)) {
return 1;
}
} else {
// NS-lookup
struct hostent *pHost;
if (NULL== (pHost= gethostbyname (serverName))) {
return 1;
}
memcpy (&sa.sin_addr, pHost->h_addr_list[0], pHost->h_length);
}
// Create socket
if (0> (*pSock = socket (PF_INET, SOCK_STREAM, 0))) {
return 1;
}
// Connect to server
if (0!= connect (*pSock, (const struct sockaddr*) &sa, sizeof (sa))) {
close (*pSock);
return 1;
}
return 0;
}
/*
* Close opened socket
*/
void netClose (TSocket socket) {
close (socket);
}
/*
* Initialize TCP I/O
*/
PNetLine netLineInit (TSocket socket, unsigned defLineLength) {
PNetLine pNL = malloc (sizeof (TNetLine));
if (NULL== pNL)
return NULL;
pNL->sockfd = socket;
pNL->defLineLength = defLineLength;
pNL->cbBuff= defLineLength;
pNL->pBuff = malloc (defLineLength *sizeof(char));
return pNL;
}
/*
* Destroy TCP I/O
*/
void netLineDestroy (PNetLine pNL) {
free (pNL->pBuff);
free (pNL);
}
/*
* Read one line from other side
*/
int netLineGet (PNetLine pNL, const char **szText) {
// Initial allocation
if (pNL->cbBuff != pNL->defLineLength) {
pNL->cbBuff= pNL->defLineLength;
free (pNL->pBuff);
pNL->pBuff = malloc (pNL->cbBuff *sizeof(char));
}
// Read one line
unsigned cbWritten=0;
while ( 0<readChar (pNL->sockfd, pNL->pBuff + cbWritten) && pNL->pBuff[cbWritten] != '\r')
if (++cbWritten >= pNL->cbBuff) {
pNL->cbBuff <<= 1;
if (NULL== (pNL->pBuff= realloc (pNL->pBuff, pNL->cbBuff) ))
return -1;
}
char tmp;
if (0>= readChar (pNL->sockfd, &tmp) || '\n'!= tmp)
// Bad CR-LF sequnce
return -1;
if (pNL->pBuff [cbWritten] != '\r')
// Error during reading
return -1;
// End with zero end return string
pNL->pBuff [cbWritten] = '\0';
*szText = pNL->pBuff;
// All ok
return 0;
}
/*
* Send plain text to other side
*/
int netPut (PNetLine pNL, const char *szText) {
if (0> writeBlock (pNL->sockfd, szText, strlen (szText)))
return -1;
return 0;
}
/*
* Read one char from socket
*/
static inline int readChar (int sockfd, char *pTo) {
while (0> read (sockfd, pTo, 1))
if (errno != EINTR)
return -1;
return 1;
}
/*
* Write block to socket
*/
static inline int writeBlock (int sockfd, const char *pBuff, size_t size) {
int cbWritten = 0;
while (size > 0) {
if (0>= (cbWritten= write (sockfd, pBuff, size) )) {
if (cbWritten<0 && errno==EINTR)
cbWritten = 0;
else
return -1;
}
size -= cbWritten;
pBuff += cbWritten;
}
return cbWritten;
}