- Install to ~/.local/bin/winamp-mpris - Use ~/.local/state/winamp-mpris/bridge.log for logging - Use $XDG_RUNTIME_DIR/winamp-mpris.pid for PID management - Add detailed user notification for 401 Unauthorized errors - Add install.sh for automated, standard-compliant setup - Include Winamp Web Interface source code and installer in repository
531 lines
14 KiB
C++
531 lines
14 KiB
C++
/* --- WEBADMIN.CPP ---
|
|
/
|
|
/ Written by Phil Himsworth, 2001-2002.
|
|
/
|
|
/*/
|
|
|
|
#include <windows.h>
|
|
#include "types.h"
|
|
#include "main.h"
|
|
#include "html.h"
|
|
#include "plugin.h"
|
|
#include "resource.h"
|
|
|
|
#include "op_winamp.h"
|
|
|
|
extern char mp3root[MAX_PATH], playlistdir[MAX_PATH], logfiledir[MAX_PATH], filetypes[255];
|
|
extern int browse_enable, dl_wa_files, dl_other_files, show_other_files, frames, title_refresh, securepassword;
|
|
|
|
extern char szAppVer[];
|
|
extern char pagetitle[255];
|
|
|
|
extern winampGeneralPurposePlugin plugin;
|
|
|
|
// --------------------------------------------------------------------------------
|
|
// Returns Web Admin page
|
|
int CControl::WebAdmin(connection * conn)
|
|
{
|
|
OpenHTTPHeader(conn,"text/html",0,NULL);
|
|
if (conn->http.reqID == RID_HEAD)
|
|
return ST_CLOSE;
|
|
|
|
OpenHtmlHeader(conn);
|
|
Style(conn);
|
|
CloseHeader(conn);
|
|
OpenPageBody(conn);
|
|
|
|
prints(conn,"<h3>\n<i>\n... Wawi Remote Admin ...\n</i></h3>\n");
|
|
|
|
prints(conn,"<h4>");
|
|
Link(conn,"/user","<font color=red>[</font>User Management<font color=red>]</font>",T_MAIN);
|
|
prints(conn,"</h4>\n");
|
|
|
|
prints(conn,"<form action=\"/apply\" method=\"get\">\n");
|
|
|
|
prints(conn,"<table width=\"100%\" cellspacing=\"5\" cellpadding=\"0\" border=\"0\">\n<tr>\n");
|
|
prints(conn,"<td align=\"right\">Main Page Title</td>\n<td><input type=\"text\" name=\"title\" size=\"30\" value=\"");
|
|
prints(conn,pagetitle);
|
|
prints(conn,"\"></td>\n</tr>\n<tr>\n");
|
|
prints(conn,"<td align=\"right\">Loadable Filetypes</td>\n<td><input type=\"text\" name=\"filetypes\" size=\"30\" value=\"");
|
|
prints(conn,filetypes);
|
|
prints(conn,"\"></td>\n</tr>\n<tr>\n");
|
|
prints(conn,"<td align=\"right\">Music Root Directory</td>\n<td><input type=\"text\" name=\"root\" size=\"30\" value=\"");
|
|
prints(conn,mp3root);
|
|
prints(conn,"\"></td>\n</tr>\n<tr>\n");
|
|
prints(conn,"<td align=\"right\">Playlists Directory</td>\n<td><input type=\"text\" name=\"playlists\" size=\"30\" value=\"");
|
|
prints(conn,playlistdir);
|
|
prints(conn,"\"></td>\n</tr>\n<tr>\n<td> </td>\n</tr>\n<tr>\n");
|
|
|
|
|
|
// Frames mode radio buttons
|
|
prints(conn,"<td align=\"right\">Frames:</td>\n<td><input type=\"radio\" name=\"frames\" value=\"1\"");
|
|
if (frames == 1)
|
|
prints(conn," checked=\"on\"");
|
|
prints(conn,">No Frames</td>\n</tr>\n<tr>\n<td align=\"right\"> </td>\n<td><input type=\"radio\" name=\"frames\" value=\"2\"");
|
|
if (frames == 2)
|
|
prints(conn," checked=\"on\"");
|
|
prints(conn,">2</td>\n</tr>\n<tr>\n<td align=\"right\"> </td>\n<td><input type=\"radio\" name=\"frames\" value=\"3\"");
|
|
if (frames == 3)
|
|
prints(conn," checked=\"on\"");
|
|
|
|
prints(conn,">3</td>\n</tr>\n<tr>\n");
|
|
prints(conn,"<td align=\"right\">Secure Passwords</td>\n<td><input type=\"checkbox\" name=\"securepassword\"");
|
|
if (securepassword == 1)
|
|
prints(conn," checked=\"on\"");
|
|
prints(conn,"><b>Warning!</b> Changing this will invalidate all user passwords.</td>\n</tr>\n<tr>");
|
|
prints(conn,"<td> </td>\n</tr>\n<tr>\n");
|
|
prints(conn,"<td align=\"right\">Winamp Files</td>\n<td><input type=\"checkbox\" name=\"dl_wa_files\"");
|
|
if (dl_wa_files == 1)
|
|
prints(conn," checked=\"on\"");
|
|
prints(conn,">Download</td>\n</tr>\n<tr>\n");
|
|
prints(conn,"<td align=\"right\">Other Files</td>\n<td><input type=\"checkbox\" name=\"dl_other_files\"");
|
|
if (dl_other_files == 1)
|
|
prints(conn," checked=\"on\"");
|
|
prints(conn,">Download <input type=\"checkbox\" name=\"show_other_files\"");
|
|
if (show_other_files == 1)
|
|
prints(conn," checked=\"on\"");
|
|
prints(conn,">Show</td>\n</tr>\n");
|
|
prints(conn,"<td colspan=\"2\" align=\"center\"><input type=\"image\" alt=\"Apply Changes\" src=\"img?image=");
|
|
printsi(conn,IDR_IMG_OK);
|
|
prints(conn,"\"></td>\n</tr>\n</table>");
|
|
prints(conn,"</form>\n");
|
|
|
|
|
|
|
|
if (frames == 1)
|
|
LinkBar(conn);
|
|
prints(conn,"<p> </p>");
|
|
|
|
return ST_CLOSEBODY;
|
|
}
|
|
|
|
// Returns admin apply page and actually does the stuff
|
|
int CControl::ApplyAdmin(connection * conn)
|
|
{
|
|
bool changed = false;
|
|
OpenHTTPHeader(conn,"text/html",0,NULL);
|
|
if (conn->http.reqID == RID_HEAD)
|
|
return ST_CLOSE;
|
|
|
|
OpenHtmlHeader(conn);
|
|
Style(conn);
|
|
CloseHeader(conn);
|
|
OpenPageBody(conn);
|
|
|
|
prints(conn,"<h3>\n<i>\n... Wawi Remote Admin ...\n</i></h3>\n");
|
|
|
|
char instring[255]; // used for everything
|
|
|
|
if (GetArgValue(conn,"title",instring,255))
|
|
{
|
|
Unescape_url(instring);
|
|
if (!StrComp(pagetitle,instring))
|
|
{
|
|
lstrcpy(pagetitle,instring);
|
|
prints(conn,"<p>Page title changed to <b>");
|
|
prints(conn,pagetitle);
|
|
prints(conn,"</b></p>\n");
|
|
changed = true;
|
|
}
|
|
}
|
|
|
|
if (GetArgValue(conn,"filetypes",instring,255))
|
|
{
|
|
Unescape_url(instring);
|
|
if (!StrComp(filetypes,instring))
|
|
{
|
|
lstrcpy(filetypes,instring);
|
|
prints(conn,"<p>Filetypes changed to <b>");
|
|
prints(conn,filetypes);
|
|
prints(conn,"</b></p>\n");
|
|
changed = true;
|
|
}
|
|
}
|
|
|
|
if (GetArgValue(conn,"root",instring,255))
|
|
{
|
|
Unescape_url(instring);
|
|
if (!StrComp(mp3root,instring))
|
|
{
|
|
lstrcpy(mp3root,instring);
|
|
prints(conn,"<p>Root music directory changed to <b>");
|
|
prints(conn,mp3root);
|
|
prints(conn,"</b></p>\n");
|
|
changed = true;
|
|
}
|
|
}
|
|
|
|
if (GetArgValue(conn,"playlists",instring,255))
|
|
{
|
|
Unescape_url(instring);
|
|
if (!StrComp(playlistdir,instring))
|
|
{
|
|
lstrcpy(playlistdir,instring);
|
|
prints(conn,"<p>Playlist directory changed to <b>");
|
|
prints(conn,playlistdir);
|
|
prints(conn,"</b></p>\n");
|
|
changed = true;
|
|
}
|
|
}
|
|
|
|
wsprintf(instring,"2");
|
|
GetArgValue(conn,"frames",instring,255);
|
|
if (StrComp(instring,"1"))
|
|
{
|
|
if (frames != 1)
|
|
{
|
|
frames = 1;
|
|
prints(conn,"<p>No Frames mode turned <b>On</b></p>");
|
|
changed = true;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if (StrComp(instring,"3"))
|
|
{
|
|
if (frames != 3)
|
|
{
|
|
frames = 3;
|
|
prints(conn,"<p>Three Frames mode turned <b>On</b></p>");
|
|
changed = true;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if (frames != 2)
|
|
{
|
|
frames = 2;
|
|
prints(conn,"<p>Two Frames mode turned <b>On</b></p>");
|
|
changed = true;
|
|
}
|
|
}
|
|
}
|
|
|
|
wsprintf(instring,"off");
|
|
GetArgValue(conn,"securepassword",instring,255);
|
|
if (StrComp(instring,"on"))
|
|
{
|
|
if (securepassword == 0)
|
|
{
|
|
securepassword = 1;
|
|
prints(conn,"<p>Secure passwords turned <b>On</b></p>");
|
|
changed = true;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if (securepassword == 1)
|
|
{
|
|
securepassword = 0;
|
|
prints(conn,"<p>Secure passwords turned <b>Off</b></p>");
|
|
changed = true;
|
|
}
|
|
}
|
|
|
|
wsprintf(instring,"off");
|
|
GetArgValue(conn,"dl_wa_files",instring,255);
|
|
if (StrComp(instring,"on"))
|
|
{
|
|
if (dl_wa_files == 0)
|
|
{
|
|
dl_wa_files = 1;
|
|
prints(conn,"<p>Downloading of Winamp files is <b>Enabled</b></p>");
|
|
changed = true;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if (dl_wa_files == 1)
|
|
{
|
|
dl_wa_files = 0;
|
|
prints(conn,"<p>Downloading of Winamp files is <b>Disabled</b></p>");
|
|
changed = true;
|
|
}
|
|
}
|
|
|
|
wsprintf(instring,"off");
|
|
GetArgValue(conn,"dl_other_files",instring,255);
|
|
if (StrComp(instring,"on"))
|
|
{
|
|
if (dl_other_files == 0)
|
|
{
|
|
dl_other_files = 1;
|
|
prints(conn,"<p>Downloading other files is <b>Enabled</b></p>");
|
|
changed = true;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if (dl_other_files == 1)
|
|
{
|
|
dl_other_files = 0;
|
|
prints(conn,"<p>Downloading other files is <b>Disabled</b></p>");
|
|
changed = true;
|
|
}
|
|
}
|
|
|
|
wsprintf(instring,"off");
|
|
GetArgValue(conn,"show_other_files",instring,255);
|
|
if (StrComp(instring,"on"))
|
|
{
|
|
if (show_other_files == 0)
|
|
{
|
|
show_other_files = 1;
|
|
prints(conn,"<p>Listing other files is <b>Enabled</b></p>");
|
|
changed = true;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if (show_other_files == 1)
|
|
{
|
|
show_other_files = 0;
|
|
prints(conn,"<p>Listing other files is <b>Disabled</b></p>");
|
|
changed = true;
|
|
}
|
|
}
|
|
|
|
if (changed == false)
|
|
prints(conn,"<p>No changes made.</p>\n");
|
|
|
|
config_write();
|
|
|
|
prints(conn,"<p>");
|
|
ImgLink(conn,"/",IDR_IMG_OK,"Return to Main Page",0,0,T_TOP);
|
|
prints(conn,"</p>\n");
|
|
|
|
return ST_CLOSEBODY;
|
|
}
|
|
|
|
// --------------------------------------------------------------------------------
|
|
// User admin page
|
|
int CControl::User(connection * conn)
|
|
{
|
|
|
|
char username[20];
|
|
char password[40];
|
|
int access;
|
|
|
|
if (!GetArgValue(conn,"user",username,20))
|
|
wsprintf(username,"anon");
|
|
|
|
OpenHTTPHeader(conn,"text/html",0,NULL);
|
|
if (conn->http.reqID == RID_HEAD)
|
|
return ST_CLOSE;
|
|
|
|
|
|
OpenHtmlHeader(conn);
|
|
Style(conn);
|
|
CloseHeader(conn);
|
|
OpenPageBody(conn);
|
|
|
|
prints(conn,"<h3>\n<i>\n... Wawi User Admin ...\n</i></h3>\n");
|
|
|
|
prints(conn,"<form action=\"/user\" method=\"get\">\n<p>\n");
|
|
prints(conn,"<table border=\"0\" cellpadding=\"0\" cellspacing=\"5\">\n<tr>\n<td align=\"right\">");
|
|
prints(conn,"Show User:</td>\n<td colspan=\"2\"><select onchange=\"form.submit()\" size=\"1\" name=\"user\">\n");
|
|
|
|
user * users = NULL;
|
|
|
|
char ini_file[MAX_PATH], *p;
|
|
GetModuleFileName(plugin.hDllInstance,ini_file,sizeof(ini_file));
|
|
p=ini_file+lstrlen(ini_file);
|
|
while (p >= ini_file && *p != '\\') p--;
|
|
if (++p >= ini_file) *p = 0;
|
|
lstrcat(ini_file,"gen_httpsrv.ini");
|
|
|
|
users = RetrieveUsers(users, ini_file); // fill list 'users' with usernames
|
|
user * current = users; // pointer to start of list
|
|
|
|
bool goodname = false;
|
|
|
|
while(current != NULL)
|
|
{
|
|
prints(conn,"<option value=\"");
|
|
prints(conn,current->name);
|
|
if (StrComp(current->name,username))
|
|
{
|
|
prints(conn,"\" selected>");
|
|
goodname = true;
|
|
}
|
|
else
|
|
prints(conn,"\">");
|
|
prints(conn,current->name);
|
|
prints(conn,"</option>\n");
|
|
current = current->next;
|
|
delete users;
|
|
users = current;
|
|
}
|
|
|
|
prints(conn,"</select>\n");
|
|
|
|
prints(conn,"<input type=\"image\" alt=\"Show information\" src=\"img?image=");
|
|
printsi(conn,IDR_IMG_OK);
|
|
prints(conn,"\"></td>\n</tr>\n</table>\n</p>\n</form>\n");
|
|
|
|
if (!goodname)
|
|
{
|
|
prints(conn,"<p>User <b>");
|
|
prints(conn,username);
|
|
prints(conn,"</b> is not a user of this server.</p>");
|
|
return ST_CLOSEBODY;
|
|
}
|
|
else
|
|
{
|
|
char userkey[30];
|
|
wsprintf(userkey,"#%s_access",username);
|
|
access = GetPrivateProfileInt("Users",userkey,AUTH_ANON,ini_file);
|
|
GetPrivateProfileString("Users",username,"password",password,40,ini_file);
|
|
|
|
prints(conn,"<form action=\"/setuser\" method=\"get\">\n<p>\n");
|
|
prints(conn,"<table width=\"100%\" border=\"0\" cellpadding=\"0\" cellspacing=\"5\">\n");
|
|
prints(conn,"<tr>\n<td align=\"right\">User</td>\n");
|
|
prints(conn,"<td colspan=\"2\"><input type=\"text\" name=\"user\" size=\"40\" value=\"");
|
|
prints(conn,username);
|
|
prints(conn,"\"></td>\n</tr>\n");
|
|
prints(conn,"<tr>\n<td align=\"right\">Password</td>\n");
|
|
prints(conn,"<td colspan=\"2\"><input type=\"password\" name=\"p\" size=\"40\" value=\"");
|
|
if (!StrComp(username,"anon"))
|
|
prints(conn,password);
|
|
prints(conn,"\"></td>\n</tr>\n");
|
|
|
|
prints(conn,"<tr>\n<td colspan=\"2\"> </td>\n</tr>\n");
|
|
prints(conn,"<tr>\n<td align=\"right\">Server<input type=\"checkbox\" name=\"a_server\" ");
|
|
if (access & AUTH_SERVER)
|
|
prints(conn,"checked=\"on\"");
|
|
prints(conn,"></td>\n");
|
|
|
|
prints(conn,"<td align=\"left\"><input type=\"checkbox\" name=\"a_playlist\" ");
|
|
if (access & AUTH_PLAYLIST)
|
|
prints(conn,"checked=\"on\"");
|
|
prints(conn,">Add files</td>\n</tr>\n");
|
|
|
|
prints(conn,"<tr>\n<td align=\"right\">Play<input type=\"checkbox\" name=\"a_control\" ");
|
|
if (access & AUTH_CONTROL)
|
|
prints(conn,"checked=\"on\"");
|
|
prints(conn,"></td>\n");
|
|
|
|
prints(conn,"<td align=\"left\"><input type=\"checkbox\" name=\"a_download\" ");
|
|
if (access & AUTH_DOWNLOAD)
|
|
prints(conn,"checked=\"on\"");
|
|
prints(conn,">Download</td>\n</tr>\n");
|
|
|
|
prints(conn,"<tr>\n<td align=\"right\">Remove files<input type=\"checkbox\" name=\"a_clear\" ");
|
|
if (access & AUTH_CLEAR)
|
|
prints(conn,"checked=\"on\"");
|
|
prints(conn,"></td>\n");
|
|
|
|
prints(conn,"<td align=\"left\"><input type=\"checkbox\" name=\"a_browse\" ");
|
|
if (access & AUTH_BROWSE)
|
|
prints(conn,"checked=\"on\"");
|
|
prints(conn,">Browse</td>\n</tr>\n<tr>\n<td colspan=\"2\" align=\"center\">");
|
|
|
|
prints(conn,"<input type=\"submit\" name=\"addupd\" value=\"Add/Update\">");
|
|
prints(conn,"<input type=\"submit\" name=\"delete\" value=\"Delete\">\n</td>\n</tr>\n</table>\n</p>\n</form>\n");
|
|
|
|
}
|
|
|
|
if (frames == 1)
|
|
LinkBar(conn);
|
|
|
|
prints(conn,"<p> </p>\n");
|
|
|
|
|
|
|
|
return ST_CLOSEBODY;
|
|
}
|
|
|
|
// --------------------------------------------------------------------------------
|
|
// Sets stuff from the user admin page
|
|
int CControl::SetUser(connection * conn)
|
|
{
|
|
OpenHTTPHeader(conn,"text/html",0,NULL);
|
|
if (conn->http.reqID == RID_HEAD)
|
|
return ST_CLOSE;
|
|
|
|
OpenHtmlHeader(conn);
|
|
Style(conn);
|
|
|
|
prints(conn,"<h3>\n<i>\n... Wawi User Admin ...\n</i></h3>\n");
|
|
char username[20];
|
|
char password[40];
|
|
if (!GetArgValue(conn,"user",username,20) || StrComp(username,""))
|
|
{
|
|
CloseHeader(conn);
|
|
OpenPageBody(conn);
|
|
prints(conn,"<p>No user selected.</p>\n");
|
|
ImgLink(conn,"/main",IDR_IMG_OK,"Return to main page",0,0,T_MAIN);
|
|
return ST_CLOSEBODY;
|
|
}
|
|
|
|
char ini_file[MAX_PATH], *p;
|
|
GetModuleFileName(plugin.hDllInstance,ini_file,sizeof(ini_file));
|
|
p=ini_file+lstrlen(ini_file);
|
|
while (p >= ini_file && *p != '\\') p--;
|
|
if (++p >= ini_file) *p = 0;
|
|
lstrcat(ini_file,"gen_httpsrv.ini");
|
|
|
|
|
|
char whichbutton[20];
|
|
if (GetArgValue(conn,"delete",whichbutton,20))
|
|
{
|
|
DeleteUser(ini_file,username);
|
|
RefreshHeader(conn,"/user");
|
|
CloseHeader(conn);
|
|
OpenPageBody(conn);
|
|
prints(conn,"<p>Deleting user <b>");
|
|
prints(conn,username);
|
|
prints(conn,"</b></p>\n");
|
|
|
|
return ST_CLOSEBODY;
|
|
}
|
|
|
|
|
|
|
|
char refreshto[40];
|
|
wsprintf(refreshto,"/user?user=%s",username);
|
|
RefreshHeader(conn,refreshto);
|
|
CloseHeader(conn);
|
|
OpenPageBody(conn);
|
|
|
|
prints(conn,"<p>Updating user information for <b>");
|
|
prints(conn,username);
|
|
prints(conn,"</b></p>\n");
|
|
|
|
GetArgValue(conn,"p",password,40);
|
|
//MessageBox(NULL,password,"password",MB_OK | MB_TOPMOST);
|
|
|
|
int access = 0;
|
|
char authstring[10];
|
|
|
|
if (GetArgValue(conn,"a_server",authstring,10))
|
|
if (StrComp(authstring,"on"))
|
|
access += AUTH_SERVER;
|
|
|
|
if (GetArgValue(conn,"a_control",authstring,10))
|
|
if (StrComp(authstring,"on"))
|
|
access += AUTH_CONTROL;
|
|
|
|
if (GetArgValue(conn,"a_clear",authstring,10))
|
|
if (StrComp(authstring,"on"))
|
|
access += AUTH_CLEAR;
|
|
|
|
if (GetArgValue(conn,"a_playlist",authstring,10))
|
|
if (StrComp(authstring,"on"))
|
|
access += AUTH_PLAYLIST;
|
|
|
|
if (GetArgValue(conn,"a_download",authstring,10))
|
|
if (StrComp(authstring,"on"))
|
|
access += AUTH_DOWNLOAD;
|
|
|
|
if (GetArgValue(conn,"a_browse",authstring,10))
|
|
if (StrComp(authstring,"on"))
|
|
access += AUTH_BROWSE;
|
|
|
|
|
|
|
|
UpdateUser(ini_file,username,password,access);
|
|
|
|
return ST_CLOSEBODY;
|
|
}
|