all:
@make -C cokebank all
@make -C server all
+ @make -C client all
clean:
@make -C cokebank clean
@make -C server clean
+ @make -C client clean
#include <arpa/inet.h>
#include <openssl/sha.h> // SHA1
+#define USE_NCURSES_INTERFACE 0
+
// === TYPES ===
typedef struct sItem {
char *Ident;
}
// and choose what to dispense
- // TODO: ncurses interface (with separation between item classes)
- // - Hmm... that would require standardising the item ID to be <class>:<index>
- // Oh, why not :)
- #if 1
+ #if USE_NCURSES_INTERFACE
i = ShowNCursesUI();
#else
printf("Item failed to dispense, is the slot empty?\n");
break;
default:
- printf("Unknown response code %i\n", responseCode);
+ printf("Unknown response code %i ('%s')\n", responseCode, buffer);
break;
}
}
*/
int ShowNCursesUI(void)
{
+ // TODO: ncurses interface (with separation between item classes)
+ // - Hmm... that would require standardising the item ID to be <class>:<index>
+ // Oh, why not :)
int ch;
int i, times;
int xBase, yBase;
// TODO: Get Salt
// Expected format: 100 SALT <something> ...
// OR : 100 User Set
- printf("string = '%s'\n", buf);
RunRegex(&gSaltRegex, buf, 4, matches, "Malformed server response");
if( atoi(buf) != 100 ) {
exit(-1); // ERROR
// Set salt
memcpy( salt, buf + matches[3].rm_so, matches[3].rm_eo - matches[3].rm_so );
salt[ matches[3].rm_eo - matches[3].rm_so ] = 0;
- printf("Salt: '%s'\n", salt);
+// printf("Salt: '%s'\n", salt);
}
fflush(stdout);
h[ 0], h[ 1], h[ 2], h[ 3], h[ 4], h[ 5], h[ 6], h[ 7], h[ 8], h[ 9],
h[10], h[11], h[12], h[13], h[14], h[15], h[16], h[17], h[18], h[19]
);
- printf("Final hash: '%s'\n", buf);
+// printf("Final hash: '%s'\n", buf);
fflush(stdout); // Debug
}
#include <openssl/sha.h>
#include "common.h"
-#define HACK_TPG_NOAUTH 1
-
// === IMPORTS ===
extern int Bank_GetMinAllowedBalance(int ID);
extern int Bank_GetUserBalance(int ID);
#ifndef _COMMON_H_
#define _COMMON_H_
+#include <regex.h>
+
// === CONSTANTS ===
#define DEFAULT_CONFIG_FILE "/etc/opendispense/main.cfg"
#define DEFAULT_ITEM_FILE "/etc/opendispense/items.cfg"
extern int giDebugLevel;
// === FUNCTIONS ===
+// --- Helpers --
+extern void CompileRegex(regex_t *Regex, const char *Pattern, int Flags);
+extern int RunRegex(regex_t *regex, const char *string, int nMatches, regmatch_t *matches, const char *errorMessage);
+
+// --- Dispense ---
extern int DispenseItem(int User, tItem *Item);
// --- Logging ---
if( giCoke_SerialFD == -1 ) {
fprintf(stderr, "ERROR: Unable to open coke serial port ('%s')\n", gsCoke_SerialPort);
}
- regcomp(&gCoke_StatusRegex, "^slot\\s+(\\d)\\s+([^:]+):([a-zA-Z]+)\\s*", REG_EXTENDED);
+ CompileRegex(&gCoke_StatusRegex, "^slot\\s+(\\d)\\s+([^:]+):([a-zA-Z]+)\\s*", REG_EXTENDED);
return 0;
}
{
char tmp[32], *status;
regmatch_t matches[4];
+ int ret;
// Sanity please
- if( Item < 0 || Item > 6 ) return -1;
+ if( Item < 0 || Item > 6 ) return -1; // -EYOURBAD
// Ask the coke machine
sprintf(tmp, "s%i\n", Item);
write(giCoke_SerialFD, tmp, 2);
// Read the response
- read(giCoke_SerialFD, tmp, sizeof(tmp)-1);
- regexec(&gCoke_StatusRegex, tmp, sizeof(matches)/sizeof(matches[0]), matches, 0);
+ tmp[0] = '\0';
+ ret = read(giCoke_SerialFD, tmp, sizeof(tmp)-1);
+ //printf("ret = %i\n", ret);
+ if( ret <= 0 ) {
+ fprintf(stderr, "Coke machine is not being chatty (read = %i)\n", ret);
+ return -1;
+ }
+ ret = RunRegex(&gCoke_StatusRegex, tmp, sizeof(matches)/sizeof(matches[0]), matches, "Bad Response");
+ if( ret ) {
+ return -1;
+ }
tmp[ matches[3].rm_eo ] = '\0';
status = &tmp[ matches[3].rm_so ];
return 0;
}
+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);
+ }
+}
+
+
#include <unistd.h>
#include <string.h>
+// HACKS
+#define HACK_TPG_NOAUTH 1
+
+// Statistics
#define MAX_CONNECTION_QUEUE 5
#define INPUT_BUFFER_SIZE 256
-#define HASH_TYPE SHA512
-#define HASH_LENGTH 64
+#define HASH_TYPE SHA1
+#define HASH_LENGTH 20
#define MSG_STR_TOO_LONG "499 Command too long (limit "EXPSTR(INPUT_BUFFER_SIZE)")\n"
// === PROTOTYPES ===
void Server_Start(void);
+void Server_Cleanup(void);
void Server_HandleClient(int Socket, int bTrusted);
char *Server_ParseClientCommand(tClient *Client, char *CommandString);
// --- Commands ---
{"DISPENSE", Server_Cmd_DISPENSE}
};
#define NUM_COMMANDS (sizeof(gaServer_Commands)/sizeof(gaServer_Commands[0]))
+ int giServer_Socket;
// === CODE ===
/**
*/
void Server_Start(void)
{
- int server_socket, client_socket;
+ int client_socket;
struct sockaddr_in server_addr, client_addr;
+ atexit(Server_Cleanup);
+
// Create Server
- server_socket = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);
- if( server_socket < 0 ) {
+ giServer_Socket = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);
+ if( giServer_Socket < 0 ) {
fprintf(stderr, "ERROR: Unable to create server socket\n");
return ;
}
server_addr.sin_port = htons(giServer_Port); // Port
// Bind
- if( bind(server_socket, (struct sockaddr *) &server_addr, sizeof(server_addr)) < 0 ) {
+ if( bind(giServer_Socket, (struct sockaddr *) &server_addr, sizeof(server_addr)) < 0 ) {
fprintf(stderr, "ERROR: Unable to bind to 0.0.0.0:%i\n", giServer_Port);
+ perror("Binding");
return ;
}
// Listen
- if( listen(server_socket, MAX_CONNECTION_QUEUE) < 0 ) {
+ if( listen(giServer_Socket, MAX_CONNECTION_QUEUE) < 0 ) {
fprintf(stderr, "ERROR: Unable to listen to socket\n");
+ perror("Listen");
return ;
}
uint len = sizeof(client_addr);
int bTrusted = 0;
- client_socket = accept(server_socket, (struct sockaddr *) &client_addr, &len);
+ client_socket = accept(giServer_Socket, (struct sockaddr *) &client_addr, &len);
if(client_socket < 0) {
fprintf(stderr, "ERROR: Unable to accept client connection\n");
return ;
}
}
+void Server_Cleanup(void)
+{
+ printf("Close(%i)\n", giServer_Socket);
+ close(giServer_Socket);
+}
+
/**
* \brief Reads from a client socket and parses the command strings
* \param Socket Client socket number/handle