Dillo v3.1.1-46-g8a360e32
Loading...
Searching...
No Matches
hello.c
Go to the documentation of this file.
1/*
2 * Dpi for "Hello World".
3 *
4 * This server is an example. Play with it and modify to your taste.
5 *
6 * Copyright 2003-2007 Jorge Arellano Cid <jcid@dillo.org>
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 3 of the License, or
11 * (at your option) any later version.
12 *
13 */
14
15#include <unistd.h>
16#include <sys/types.h>
17#include <stdio.h>
18#include <stdlib.h>
19#include <string.h>
20#include <errno.h>
21#include "../dpip/dpip.h"
22#include "dpiutil.h"
23
24/*
25 * Debugging macros
26 */
27#define _MSG(...)
28#define MSG(...) printf("[hello dpi]: " __VA_ARGS__)
29
30/*---------------------------------------------------------------------------*/
31
32
33/*
34 *
35 */
36int main(void)
37{
38 FILE *in_stream;
39 Dsh *sh;
40 char *dpip_tag, *cmd = NULL, *url = NULL, *child_cmd = NULL;
41 char *esc_tag, *d_cmd;
42 size_t n;
43 int ret;
44 char buf[4096];
45 char *choice[] = {"Window was closed", "Yes", "No",
46 "Could be", "It's OK", "Cancel"};
47 /* "Could>be", ">It's OK", "Can'>cel"}; --for testing */
48 int choice_num = -1;
49
50 MSG("starting...\n");
51 /* sleep(20) */
52
53 /* Initialize the SockHandler.
54 * This means we'll use stdin for input and stdout for output.
55 * In case of a server dpi, we'd use a socket and pass its file descriptor
56 * twice (e.g. a_Dpip_dsh_new(sock_fd, sock_fd, 1024).
57 * (Note: by now the last parameter is not used) */
58 sh = a_Dpip_dsh_new(STDIN_FILENO, STDOUT_FILENO, 2*1024);
59
60 /* Authenticate our client...
61 * As we're using Internet domain sockets, DPIP checks whether the client
62 * runs with the user's ID, by means of a shared secret. The DPIP API does
63 * the work for us. */
64 if (!(dpip_tag = a_Dpip_dsh_read_token(sh, 1)) ||
65 a_Dpip_check_auth(dpip_tag) < 0) {
66 MSG("can't authenticate request: %s\n", dStrerror(errno));
68 return 1;
69 }
70 dFree(dpip_tag);
71
72 /* Read the dpi command from STDIN
73 * Now we're past the authentication phase, let's see what's dillo
74 * asking from us. a_Dpip_dsh_read_token() will block and return
75 * a full dpip token or null on error (it's commented in dpip.c) */
76 dpip_tag = a_Dpip_dsh_read_token(sh, 1);
77 MSG("tag = [%s]\n", dpip_tag);
78
79 /* Now that we have the dpip_tag, let's isolate the command and url */
80 cmd = a_Dpip_get_attr(dpip_tag, "cmd");
81 url = a_Dpip_get_attr(dpip_tag, "url");
82
83/*-- Dialog part */
84/* This is the dialog window. This is an example of interaction with
85 * the user. If you're starting to understand dpis, comment this out
86 * by switching to "#if 0" and the dialog will be disabled. */
87#if 1
88{
89 char *dpip_tag2, *dialog_msg;
90
91 /* Let's confirm the request */
92 /* NOTE: you can send less alternatives (e.g. only alt1 and alt2) */
93 d_cmd = a_Dpip_build_cmd(
94 "cmd=%s title=%s msg=%s alt1=%s alt2=%s alt3=%s alt4=%s alt5=%s",
95 "dialog", "Dillo: Hello", "Do you want to see the hello page?",
96 choice[1], choice[2], choice[3], choice[4], choice[5]);
97 a_Dpip_dsh_write_str(sh, 1, d_cmd);
98 dFree(d_cmd);
99
100 /* Get the answer */
101 dpip_tag2 = a_Dpip_dsh_read_token(sh, 1);
102 MSG("tag = [%s]\n", dpip_tag2);
103
104 /* Get "msg" value */
105 dialog_msg = a_Dpip_get_attr(dpip_tag2, "msg");
106 choice_num = 0;
107 if (dialog_msg)
108 choice_num = *dialog_msg - '0';
109
110 dFree(dialog_msg);
111 dFree(dpip_tag2);
112}
113#endif
114/*-- EOD part */
115
116 /* Start sending our answer.
117 * (You can read the comments for DPIP API functions in dpip/dpip.c) */
118 d_cmd = a_Dpip_build_cmd("cmd=%s url=%s", "start_send_page", url);
119 a_Dpip_dsh_write_str(sh, 0, d_cmd);
120 dFree(d_cmd);
121
123 "Content-type: text/html\n\n"
124 "<!DOCTYPE HTML PUBLIC '-//W3C//DTD HTML 4.01 Transitional//EN'>\n"
125 "<html>\n"
126 "<head><title>Simple dpi test page (hello.dpi)</title></head>\n"
127 "<body><hr><h1>Hello world!</h1><hr>\n<br><br>\n");
128
129 /* Show the choice received with the dialog */
131 "<hr>\n"
132 "<table width='100%%' border='1' bgcolor='burlywood'><tr><td>\n"
133 "<big><em>Dialog question:</em> Do you want to see the hello page?<br>\n"
134 "<em>Answer received:</em> <b>%s</b></big> </table>\n"
135 "<hr>\n",
136 choice_num < 0 ? "There was NO dialog!" : choice[choice_num]);
137
138 /* Show the dpip tag we received */
139 esc_tag = Escape_html_str(dpip_tag);
141 "<h3>dpip tag received:</h3>\n"
142 "<pre>\n%s</pre>\n"
143 "<br><small>(<b>dpip:</b> dpi protocol)</small><br><br><br>\n",
144 esc_tag);
145 dFree(esc_tag);
146
147
148 /* Now something more interesting,
149 * fork a command and show its feedback.
150 * (An example of generating dynamic content with an external
151 * program). */
152 if (cmd && url) {
153 child_cmd = dStrdup("date -R");
154 MSG("[%s]\n", child_cmd);
155
156 /* Fork, exec command, get its output and answer */
157 if ((in_stream = popen(child_cmd, "r")) == NULL) {
158 perror("popen");
159 return EXIT_FAILURE;
160 }
161
162 a_Dpip_dsh_write_str(sh, 0, "<h3>date:</h3>\n");
163 a_Dpip_dsh_write_str(sh, 0, "<pre>\n");
164
165 /* Read/Write */
166 while ((n = fread (buf, 1, 4096, in_stream)) > 0) {
167 a_Dpip_dsh_write(sh, 0, buf, n);
168 }
169
170 a_Dpip_dsh_write_str(sh, 0, "</pre>\n");
171
172 if ((ret = pclose(in_stream)) != 0)
173 MSG("popen: [%d]\n", ret);
174
175 dFree(child_cmd);
176 }
177
178 a_Dpip_dsh_write_str(sh, 1, "</body></html>\n");
179
180 dFree(cmd);
181 dFree(url);
182 dFree(dpip_tag);
183
184 /* Finish the SockHandler */
187
188 return 0;
189}
190
static Dsh * sh
Definition datauri.c:39
void dFree(void *mem)
Definition dlib.c:68
char * dStrdup(const char *s)
Definition dlib.c:77
#define dStrerror
Definition dlib.h:95
void a_Dpip_dsh_free(Dsh *dsh)
Free the SockHandler structure.
Definition dpip.c:525
char * a_Dpip_build_cmd(const char *format,...)
Printf like function for building dpip commands.
Definition dpip.c:83
int a_Dpip_dsh_write_str(Dsh *dsh, int flush, const char *str)
Convenience function.
Definition dpip.c:374
char * a_Dpip_get_attr(const char *tag, const char *attrname)
Task: given a tag and an attribute name, return its value.
Definition dpip.c:192
char * a_Dpip_dsh_read_token(Dsh *dsh, int blocking)
Return a newlly allocated string with the next dpip token in the socket.
Definition dpip.c:493
void a_Dpip_dsh_close(Dsh *dsh)
Close this socket for reading and writing.
Definition dpip.c:504
int a_Dpip_check_auth(const char *auth_tag)
Check whether the given 'auth' string equals what dpid saved.
Definition dpip.c:201
int a_Dpip_dsh_write(Dsh *dsh, int flush, const char *Data, int DataSize)
Streamed write to socket.
Definition dpip.c:317
Dsh * a_Dpip_dsh_new(int fd_in, int fd_out, int flush_sz)
Create and initialize a dpip socket handler.
Definition dpip.c:247
#define a_Dpip_dsh_printf(sh, flush,...)
Definition dpip.h:77
char * Escape_html_str(const char *str)
Definition dpiutil.c:93
#define MSG(...)
Definition hello.c:28
int main(void)
Definition hello.c:36
Dpip socket handler type.
Definition dpip.h:31