Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <stdlib.h>
- #include <stdio.h>
- #include <assert.h>
- #include <sys/socket.h>
- #include <sys/types.h>
- #include <unistd.h>
- #include "server.h"
- #include "http.h"
- #include "util.h"
- #include "mandelbrot.h"
- #define DEFAULT_PORT 1917
- #define BACKLOG_SIZE 10
- #define IMG_WIDTH 512
- #define IMG_HEIGHT 512
- #define BASE_VISIBLE 2
- int main(void) {
- int sockfd, theirfd;
- int quit = FALSE;
- char buf[BUF_SIZE];
- int read;
- struct triordinate t;
- int sent;
- /* I can't use global variables so this is what you get.
- TODO: Move the headers to separate functions. */
- char HTTPHeader[] = "HTTP/1.0 200 OK\r\n"
- "Content-Type: image/bmp\r\n"
- "\r\n";
- /* Contains both bitmap file and DIB headers.
- NOTE: This uses the OS/2 variant of DIB headers.
- See: en.wikipedia.org/wiki/BMP_file_format#DIB_header_(bitmap_information_header) */
- unsigned char BMPHeader[] = {
- /* Bitmap file header */
- 'B', 'M', 0x1a, 0x00, 0x0c, 0xc0, 0xde, 0xd0,
- 0x0d, 0x00, 0x1a,
- /* DIB header */
- 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- /* Image width and height (offset 0x12 and 0x14 respectively). */
- 0x00, 0x02, 0x00, 0x02,
- 0x01, 0x00, 0x18, 0x00
- };
- double wunit, hunit, x, y, xlimit, ylimit;
- struct complex c;
- /* Create and bind network socket and get its file descriptor. */
- sockfd = initServer(DEFAULT_PORT);
- assert(sockfd != -1 && fuck("initServer")); // See util.c
- /* Begin listening on the socket. */
- while (!quit) {
- /* Get client file descriptor. */
- theirfd = serve(sockfd, BACKLOG_SIZE);
- /* When serve (i.e listen() or accept()) fails, it is fatal.
- See listen(3P) and accept(3P) for details. */
- assert(theirfd != -1 && fuck("serve"));
- /* Read HTTP request into a buffer for parsing. */
- buf[BUF_SIZE - 1] = '\0';
- read = recv(theirfd, buf, BUF_SIZE - 1, 0);
- /* When recv fails, it is usually fatal.
- See recv(3P) for details. */
- assert(read != -1 && fuck("recv"));
- fprintf(stderr, "request received:\n%s\n", buf);
- /* Ensure the request path follows the correct pattern
- parsing, and parse it. */
- if (!matchString(buf)) {
- /* Send a 404. */
- fputs("error 404\n", stderr);
- /* TODO: Add error 404 page */
- } else {
- t = parseRequest(buf);
- fprintf(stderr,
- "triordinate received: "
- "{ .zoom = %d, .x = %f , .y = %f }\n",
- t.zoom, t.x, t.y
- );
- /* Send HTTP response header. */
- sent = send(
- theirfd,
- HTTPHeader,
- sizeof(HTTPHeader) + 1,
- 0
- );
- fprintf(stderr,
- "HTTP response header transmitted:\n%s\n",
- HTTPHeader
- );
- /* When send fails, it is usually fatal.
- See send(3P) for details. */
- assert(sent != -1 && fuck("send"));
- /* This should never happen. */
- assert(sent == sizeof(HTTPHeader) + 1 && "impossible");
- /* Set width and height fields in the BMP header.
- Because integers are stored in little-endian, the bytes of the
- dimension must be stored in reverse. Casting to unsigned char
- truncates the integer to its least significant byte.*/
- BMPHeader[0x12] = (unsigned char)IMG_WIDTH;
- BMPHeader[0x13] = (unsigned char)bitshiftRight(IMG_WIDTH, CHAR_BIT);
- BMPHeader[0x14] = (unsigned char)IMG_HEIGHT;
- BMPHeader[0x15] = (unsigned char)bitshiftRight(IMG_HEIGHT, CHAR_BIT);
- /* Send BMP header. */
- sent = send(
- theirfd,
- BMPHeader,
- sizeof(BMPHeader) + 1,
- 0
- );
- /* See above. */
- assert(sent != -1 && fuck("send"));
- /* This should also never happen. */
- assert(sent == sizeof(BMPHeader) + 1 && "impossible");
- /* Generate BMP pixel array. */
- fputs("Generating pixel array...", stderr);
- wunit = BASE_VISIBLE / t.zoom / IMG_WIDTH;
- hunit = BASE_VISIBLE / t.zoom / IMG_HEIGHT;
- /* The pixel array starts with the bottom left. */
- x = t.x - (IMG_WIDTH / 2 * wunit);
- y = t.y + (IMG_HEIGHT / 2 * hunit);
- xlimit = x + IMG_WIDTH * wunit;
- ylimit = y - IMG_HEIGHT * hunit;
- /* Begin sending each pixel to the client. */
- while (x < xlimit) {
- while (y > ylimit) {
- c.real = x;
- c.imag = y;
- int escape = escapeSteps(c);
- /* TODO: Add colours. */
- unsigned char colourbuf[3] = { escape, escape, escape };
- send(theirfd, colourbuf, sizeof(colourbuf), 0);
- y -= hunit;
- }
- x += wunit;
- }
- fputs("\nDone.\n", stderr);
- }
- /* Close server connection. Keep Australia beautiful. */
- close(theirfd);
- }
- /* Close the socket. Keep Australia beautiful. */
- close(sockfd);
- return EXIT_SUCCESS;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement