Skip to content

Commit 81b7f02

Browse files
committed
Update to build on Norcroft.
The code had only been compiled properly for GCC and was known to not work on Norcroft. This change introduces a Makefile (using my own makefile system, which will be updated later) and the necessary code changes to allow it to build on Norcroft. Specifically... * We use TCPIPLibs variable to find the network libraries. This makes it easier to include things in the exact same way on GCC and Norcroft. * Code is modified to work with pre-C99 format variables. My compiler doesn't support them, and requiring C99 format requires the developer to spend (more) money to get the later compiler. * Magic packet sending has been moved to a separate function because of this, to isolate the parsing from the packet sending. * Bug in leaking the socket due to not closing it is now fixed.
1 parent 1980e0e commit 81b7f02

File tree

3 files changed

+122
-42
lines changed

3 files changed

+122
-42
lines changed

src/MakefileNorcroft,fe1

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
#!/usr/bin/env riscos-amu -f
2+
# Makefile for WakeOnLan
3+
#
4+
5+
#
6+
# Program specific options:
7+
#
8+
COMPONENT = WakeOnLan
9+
10+
# Specifies additional targets for startup
11+
#INITTARGET = inittarget
12+
13+
# Specifies additional targets for clean
14+
#CLEANTARGET = cleantarget
15+
16+
# aif, for linked objects
17+
# aof, for a partially linked AOF object
18+
# util, for utilities built with objasm
19+
# basic, for BASIC tools
20+
TYPE = aif
21+
22+
# The file to output (defaults ${COMPONENT})
23+
#TARGET = <filename>
24+
25+
# Comma-separated list of paths to use for includes, such as:
26+
# <Lib$Dir>.LibName.
27+
INCLUDES = TCPIPLibs:
28+
29+
# Space separated list of defines to set, eg -DDEBUG
30+
CDEFINES =
31+
32+
# Space separated list of libraries to link against.
33+
LIBS = ${CLIB} ${TCPIPLIBS}
34+
35+
# Objects to build, using the format o.<name> (will be varied for build type)
36+
OBJS = o.magic \
37+
o.main \
38+
39+
# Space separated list of XML files for building documentation.
40+
#DOCSRC = <prm-in-xml-sources>
41+
42+
43+
include LibraryCommand
44+
45+
46+
#---------------------------------------------------------------------------
47+
# Dynamic dependencies:

src/c/main

Lines changed: 72 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -48,23 +48,27 @@
4848
#include <string.h>
4949
#include <ctype.h>
5050

51-
#ifdef __GNUC__
52-
#include <unistd.h>
53-
#include <sys/types.h>
54-
#include <sys/socket.h>
55-
#include <netinet/in.h>
56-
#include <netdb.h>
57-
#else
58-
#include "TCPIPLibs:sys.h.unistd"
59-
#include "TCPIPLibs:sys.h.types"
60-
#include "TCPIPLibs:sys.h.socket"
61-
#include "TCPIPLibs:netinet.h.in"
62-
#include "TCPIPLibs:netdb.h"
51+
#include <unistd.h>
52+
#include <sys/types.h>
53+
#include <sys/socket.h>
54+
#include <netinet/in.h>
55+
#include <arpa/inet.h>
56+
#include <netdb.h>
57+
58+
#ifndef __GNUC__
59+
#include "unixlib.h"
60+
#include "socklib.h"
61+
char *__progname = "WakeOnLan";
6362
#endif
6463

6564
#include "magic.h"
65+
6666
static verbose_output = 0;
6767

68+
69+
int sendMagicPacket(unsigned int mac[6], const char *broadcastAddress);
70+
71+
6872
void show_syntax()
6973
{
7074
printf("Syntax: *wakeonlan -m <mac address> [ -b <broadcast address> ] [-v]\n");
@@ -98,12 +102,6 @@ void check_broadcast(char bAddress[], const char *user_input )
98102
}
99103

100104
int main(int argc, char** argv){
101-
// WakeOnLAN requires at least 2 arguments
102-
if(argc < 2)
103-
{
104-
show_syntax();
105-
exit(EXIT_FAILURE);
106-
}
107105

108106
// bAddress is the default Broadcasting Address
109107
// by default it's set to a commonly used address
@@ -112,18 +110,17 @@ int main(int argc, char** argv){
112110
// Mac address
113111
unsigned int mac[6];
114112

115-
// Packet Buffer
116-
unsigned char packet[102];
117-
118-
// Set broadcast
119-
int broadcast = 1;
120-
121-
// Socket address
122-
struct sockaddr_in udpClient, udpServer;
123-
124113
int user_mac = 0;
125114
int c = 0;
126115
opterr = 0;
116+
117+
// WakeOnLAN requires at least 2 arguments
118+
if(argc < 2)
119+
{
120+
show_syntax();
121+
exit(EXIT_FAILURE);
122+
}
123+
127124
while (( c = getopt (argc, argv, "m:b:v")) != -1 )
128125
switch (c)
129126
{
@@ -162,46 +159,82 @@ int main(int argc, char** argv){
162159
if (verbose_output)
163160
printf("Using %s broadcast address\n", bAddress);
164161

162+
if (!sendMagicPacket(mac, bAddress))
163+
{
164+
exit(EXIT_FAILURE);
165+
}
166+
exit(EXIT_SUCCESS);
167+
}
168+
169+
170+
/******************************************************************
171+
Function: sendMagicPacket
172+
Description: Send a wake-on-lan packet to a remote machine
173+
Errors are printed to stdout.
174+
Parameters: mac-> list of 6 ints to send (only the low 8 bits of each int will be used)
175+
broadcastAddress-> string representation of address to send to
176+
Returns: 0 for success, 1 for failure
177+
******************************************************************/
178+
int sendMagicPacket(unsigned int mac[6], const char *broadcastAddress)
179+
{
180+
// Packet Buffer
181+
unsigned char packet[102];
182+
int udpSocket;
183+
int result;
184+
int success = 0;
185+
186+
// Set broadcast
187+
int broadcast = 1;
188+
189+
// Socket address
190+
struct sockaddr_in udpClient, udpServer;
191+
165192
genMagicPacket(packet, mac);
166193

167-
int udpSocket = socket(AF_INET, SOCK_DGRAM, 0);
194+
udpSocket = socket(AF_INET, SOCK_DGRAM, 0);
168195
if (udpSocket == -1)
169196
{
170197
printf("An error was encountered creating the UDP socket: '%s'.\n", strerror(errno));
171-
exit(EXIT_FAILURE);
198+
goto cleanup;
172199
}
173-
int setsock_result = setsockopt(udpSocket, SOL_SOCKET, SO_BROADCAST, &broadcast, sizeof broadcast);
174-
if (setsock_result == -1)
200+
result = setsockopt(udpSocket, SOL_SOCKET, SO_BROADCAST, &broadcast, sizeof broadcast);
201+
if (result == -1)
175202
{
176203
printf("Failed to set socket options: '%s'.\n", strerror(errno));
177-
exit(EXIT_FAILURE);
204+
goto cleanup;
178205
}
179206

180207
udpClient.sin_family = AF_INET;
181208
udpClient.sin_addr.s_addr = INADDR_ANY;
182209
udpClient.sin_port = 0;
183210

184-
int bind_result = bind(udpSocket, (struct sockaddr*) &udpClient, sizeof(udpClient));
185-
if (bind_result == -1)
211+
result = bind(udpSocket, (struct sockaddr*) &udpClient, sizeof(udpClient));
212+
if (result == -1)
186213
{
187214
printf("Failed to bind socket: '%s'.\n", strerror(errno));
188-
exit(EXIT_FAILURE);
215+
goto cleanup;
189216
}
190217

191218
udpServer.sin_family = AF_INET;
192-
udpServer.sin_addr.s_addr = inet_addr(bAddress);
219+
udpServer.sin_addr.s_addr = inet_addr(broadcastAddress);
193220
udpServer.sin_port = htons(9);
194221

195222
// Send the packet
196-
int result = sendto(udpSocket, &packet, sizeof(unsigned char) * 102, 0, (struct sockaddr*) &udpServer, sizeof(udpServer));
223+
result = sendto(udpSocket, &packet, sizeof(unsigned char) * 102, 0, (struct sockaddr*) &udpServer, sizeof(udpServer));
197224
if (result == -1)
198225
{
199226
printf("Failed to send magic packet to socket: '%s'.\n", strerror(errno));
200-
exit(EXIT_FAILURE);
227+
goto cleanup;
228+
}
229+
else
230+
{
231+
success = 1;
201232
}
202233

203234
if (verbose_output)
204235
printf("Wake up packet was sent.\n");
205236

206-
exit(EXIT_SUCCESS);
237+
cleanup:
238+
socketclose(udpSocket);
239+
return success;
207240
}

src/h/magic

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
#ifdef __WOL_MAGIC
2-
#define __WOL_MAGIC
1+
#ifndef WOL_MAGIC
2+
#define WOL_MAGIC
33

44
/*
55
* WakeOnLAN command for RISC OS
@@ -25,4 +25,4 @@
2525
// This function below creates one in memory.
2626
void genMagicPacket(unsigned char packet[], unsigned int macAddress[]);
2727

28-
#endif
28+
#endif

0 commit comments

Comments
 (0)