📄 httpserv.c
字号:
/*
* Copyright (C) 2001-2007 by egnite Software GmbH. All rights reserved.
* Copyright (C) 2008 by egnite GmbH. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the copyright holders nor the names of
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
* THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* For additional information see http://www.ethernut.de/
*
*/
/*!
* \file httpserv.c
* \brief HTTP interface.
*
* \verbatim
*
* $Log$
*
* \endverbatim
*/
#ifndef MY_FSDEV
#define MY_FSDEV devUrom
#endif
#ifdef MY_FSDEV_NAME
#define MY_HTTPROOT MY_FSDEV_NAME ":/"
#endif
#include <cfg/os.h>
#include <cfg/memory.h>
#include "config.h"
#ifdef USE_HTTPSERVER
#ifndef HTTPD_THREAD_STACK
#define HTTPD_THREAD_STACK 2048
#endif
#include <stdlib.h>
#include <string.h>
#include <io.h>
#include <fcntl.h>
#include <time.h>
#include <dev/board.h>
#include <dev/urom.h>
#include <dev/vscodec.h>
#include <dev/watchdog.h>
#include <arpa/inet.h>
#include <netinet/tcp.h>
#include <netdb.h>
#include <sys/confos.h>
#include <sys/confnet.h>
#include <sys/thread.h>
#include <sys/timer.h>
#include <sys/heap.h>
#include <sys/bankmem.h>
#include <sys/socket.h>
#include <sys/version.h>
#include <pro/ssi.h>
#include <pro/httpd.h>
#include "logmsg.h"
#include "utils.h"
#include "favlist.h"
#include "httpserv.h"
/*! \brief Dummy gain.
*
* Used to determine volume field that had been left empty.
* We can't use zero.
*/
#define EMPTY_GAIN 999
extern void *__heap_start;
//extern void *_etext;
int h_timevalid;
/* Service thread counter. */
static int httpd_tc;
static int StartServiceThread(void);
/*!
* \brief Create table of favorites.
*/
static int CgiStationFavorites(FILE * stream, REQUEST * req)
{
int i;
int row;
int count = 0;
char *value;
char *id = NULL;
int action = 0;
count = NutHttpGetParameterCount(req);
while (count--) {
value = NutHttpGetParameterValue(req, count);
if (strcmp(value, "edit") == 0) {
action = 1;
id = NutHttpGetParameterName(req, count);
} else if (strcmp(value, "add new Favorite") == 0) {
action = 2;
}
}
if (action == 1 && id) {
int idx = atoi(id);
fputs("<tr class=\"tr1\"><td>Station Name</td>", stream);
fprintf(stream,
"<td align=\"left\"><INPUT type=\"hidden\" value=\"saveedit\" name=\"%s\"><INPUT type=\"text\" name=\"sname\" value=\"%s\" class=\"inputl\"></td>",
id, favlist[idx].rs_name);
fputs("</tr><tr class=\"tr2\"><td>Station URL's</td>", stream);
fprintf(stream, "<td align=\"left\"><TEXTAREA class=\"inputl\" name=\"surl\" style=\"height:100;\">");
for (i = 0; i < favlist[idx].rs_streams; i++) {
fprintf(stream, "%s\n", favlist[idx].rs_uri[i]);
}
fprintf(stream, "</TEXTAREA></td>");
fputs
("</tr><tr class=\"tr1\"><td>Save Settings</td><td align=\"right\"><INPUT type=\"submit\" value=\"Apply\" class=\"submit\"></td></tr>",
stream);
} else if (action == 2) {
fputs("<tr class=\"tr1\"><td>Station Name</td>", stream);
fputs
("<td align=\"left\"><INPUT type=\"hidden\" value=\"savenew\" name=\"0\"><INPUT type=\"text\" name=\"sname\" class=\"inputl\"></td>",
stream);
fputs("</tr><tr class=\"tr2\"><td>Station URL's</td>", stream);
fputs("<td align=\"left\"><TEXTAREA class=\"inputl\" name=\"surl\" style=\"height:100;\"></TEXTAREA></td>", stream);
fputs
("</tr><tr class=\"tr1\"><td>Save Settings</td><td align=\"right\"><INPUT type=\"submit\" name=\"func\" value=\"Apply\" class=\"submit\"></td></tr>",
stream);
} else {
for (i = LAST_FAVORITE + 1, row = 0; i < MAX_FAVORITES; i++) {
if (favlist[i].rs_name == NULL) {
continue;
}
if (row & 1) {
fputs("<tr class=\"tr1\">\r\n", stream);
} else {
fputs("<tr class=\"tr2\">\r\n", stream);
}
row++;
fprintf(stream, "<td>%s</td>\r\n", favlist[i].rs_name);
fprintf(stream, "<td><INPUT type=\"submit\" name=\"%d\" value=\"edit\" class=\"submit\"></td>\r\n", i);
fprintf(stream,
"<td><INPUT type=\"submit\" name=\"%d\" value=\"delete\" class=\"submit\" onClick=\"return confirm('Are you sure you want to delete %s ?');\"></td>\r\n",
i, favlist[i].rs_name);
fprintf(stream, "<td><INPUT type=\"submit\" name=\"%d\" value=\"play now\" class=\"submit\"></td>\r\n", i);
fputs("</tr>\r\n", stream);
}
if (row & 1) {
fputs("<tr class=\"tr1\">\r\n", stream);
} else {
fputs("<tr class=\"tr2\">\r\n", stream);
}
fputs
("<td colspan=\"4\" align=\"right\"><INPUT type=\"submit\" name=\"0\" value=\"add new Favorite\" class=\"submit\"></td>",
stream);
fputs("</tr>\r\n", stream);
}
fflush(stream);
return 0;
}
static int CgiShoutCastGenres(FILE * stream, REQUEST * req)
{
int i;
int count;
char *name;
char *genre;
char *getgenre = NULL;
count = NutHttpGetParameterCount(req);
for (i = 0; i < count; i++) {
name = NutHttpGetParameterName(req, i);
if (strcmp(name, "genre") == 0) {
getgenre = NutHttpGetParameterValue(req, i);
break;
}
}
#if 0
if (getgenre == NULL) {
fprintf(stream, "<OPTION SELECTED id=\"Top500\">Top500</OPTION>\r\n");
} else {
fprintf(stream, "<OPTION id=\"Top500\">Top500</OPTION>\r\n");
}
#else
if (getgenre == NULL) {
fprintf(stream, "<OPTION SELECTED id=\"TopTen\">TopTen</OPTION>\r\n");
} else {
fprintf(stream, "<OPTION id=\"Top500\">TopTen</OPTION>\r\n");
}
#endif
for (i = 0;; i++) {
genre = ShoutCastGetGenre(i);
if (genre == NULL) {
break;
}
if (strcmp(getgenre, genre) == 0) {
fprintf(stream, "<OPTION SELECTED id=\"%s\">%s</OPTION>\r\n", genre, genre);
} else {
fprintf(stream, "<OPTION id=\"%s\">%s</OPTION>\r\n", genre, genre);
}
}
fflush(stream);
return 0;
}
static int CgiShoutCastStations(FILE * stream, REQUEST * req)
{
int count;
char *name;
char *genre = NULL;
int i;
count = NutHttpGetParameterCount(req);
for (i = 0; i < count; i++) {
name = NutHttpGetParameterName(req, i);
if (strcmp(name, "genre") == 0) {
genre = NutHttpGetParameterValue(req, i);
break;
}
}
for (i = 0;; i++) {
if (genre) {
name = ShoutCastGetStationName(genre, i);
} else {
name = ShoutCastGetStationName("Top500", i);
}
if (name == NULL) {
break;
}
if (i & 1) {
fputs("<tr class=\"tr1\">\r\n", stream);
} else {
fputs("<tr class=\"tr2\">\r\n", stream);
}
fprintf(stream, "<td>%s</td>\r\n", name);
fprintf(stream, "<td><INPUT type=\"submit\" name=\"%d\" value=\"play now\" class=\"submit\"></td>\r\n", i);
fprintf(stream, "<td><INPUT type=\"submit\" name=\"%d\" value=\"add to favorites\" class=\"submit\"></td>\r\n", i);
fputs("</tr>\r\n", stream);
}
fflush(stream);
return 0;
}
static int CgiShoutCastControl(FILE * stream, REQUEST * req)
{
int count;
char *name;
char *value;
int action = 0;
int idx = 0;
count = NutHttpGetParameterCount(req);
while (count--) {
value = NutHttpGetParameterValue(req, count);
if (strcmp(value, "add to favorites") == 0) {
action = 1;
}
if (strcmp(value, "play now") == 0) {
action = 2;
}
if (action) {
if ((name = NutHttpGetParameterName(req, count)) == NULL) {
action = 0;
} else {
idx = atoi(name);
break;
}
}
}
if (action == 1) {
ShoutCastAddStation(idx, MAX_FAVORITES);
webradio.wr_favupd = 10;
} else if (action == 2) {
ShoutCastAddStation(idx, TOP_FAVORITE);
}
return 0;
}
static void AddStationUris(int idx, CONST char *str)
{
char *uri = malloc(256);
CONST char *cp;
char *up;
if (uri) {
cp = str;
while (*cp) {
while (*cp && *cp < ' ') {
cp++;
}
up = uri;
while (*cp) {
if (*cp < ' ') {
break;
}
*up++ = *cp++;
}
*up = 0;
if (strlen(uri)) {
LogMsg(LOG_HTTPD, "Add '%s'\n", uri);
FavListSet(idx, NULL, uri);
}
}
free(uri);
}
}
static int CgiFavoritesControl(FILE * stream, REQUEST * req)
{
int count;
char *name;
char *value;
int action = 0;
int idx = 0;
char *sname = NULL;
char *surl = NULL;
count = NutHttpGetParameterCount(req);
while (count--) {
name = NutHttpGetParameterName(req, count);
value = NutHttpGetParameterValue(req, count);
if (strcmp(name, "sname") == 0) {
sname = value;
} else if (strcmp(name, "surl") == 0) {
surl = value;
} else if (strcmp(value, "saveedit") == 0) {
action = 1;
idx = atoi(name);
} else if (strcmp(value, "delete") == 0) {
action = 2;
idx = atoi(name);
} else if (strcmp(value, "play now") == 0) {
action = 3;
idx = atoi(name);
} else if (strcmp(value, "savenew") == 0) {
action = 4;
}
}
if (action == 1) {
/* Save existing. */
idx = FavListSet(idx, sname, NULL);
AddStationUris(idx, surl);
webradio.wr_favupd = 2;
} else if (action == 2) {
FavListSet(idx, NULL, NULL);
webradio.wr_favupd = 20;
} else if (action == 3) {
FavListCopy(idx, TOP_FAVORITE);
} else if (action == 4) {
/* Add new. */
idx = FavListSet(MAX_FAVORITES, sname, NULL);
AddStationUris(idx, surl);
webradio.wr_favupd = 2;
}
return 0;
}
static int CgiSettings(FILE * stream, REQUEST * req)
{
int count;
char *name;
char *value = NULL;
char *hostname = NULL;
char *prox = NULL;
char *dhcp = NULL;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -