编程实战:自己编写HTTP服务器(系列5:执行后台命令)

news2024/12/23 9:40:16

 系列入口:编程实战:自己编写HTTP服务器(系列1:概述和应答)-CSDN博客

         本文介绍执行后台命令的shell.asp的实现。

目录

一、概述

二、主体代码

三、详解

3.1 参数


一、概述

        这个功能就相当于一个终端,不过只能执行一个命令。有什么好处看自己,可以加入自己喜欢的特性。

        入口:

        别的不说了,主体代码是doPageShell()。

二、主体代码

        主体代码如下:

		bool doPageShell()
		{
#ifdef _MS_VC
			return true;
#else
			FILE * fp;
			string changedir=m_request.GetParam("changedir");
			string curdir=m_request.GetParam("curdir");
			string cmd=m_request.GetParam("command");
			bool noform=(m_request.GetParam("noform")=="true");
			bool term=(m_request.GetParam("term")=="true");
			long bufsize=1024*1024;
			char * buf=new char[bufsize];
			if(NULL==buf)
			{
				m_respond.AppendBody("<P><FONT color=RED>内存不足</FONT><P>");
				return true;
			}

			//切换路径
			if(0!=curdir.size())
			{
				if(0!=chdir(curdir.c_str()))
				{
					m_respond.AppendBody("<P><FONT color=RED>设置初始路径出错</FONT><P>"+curdir+"<P>");
					return true;
				}
			}
			if(0!=changedir.size())
			{
				if(0!=chdir(changedir.c_str()))
				{
					m_respond.AppendBody("<P><FONT color=RED>切换工作路径出错</FONT><P>"+changedir+"<P>");
					return true;
				}
			}

			//执行命令
			if(0==cmd.size())
			{
				m_respond.AppendBody("<P>空命令<P>");
			}
			else
			{
				if(0!=setpgid(getpid(),getpid()))
				{
					m_respond.AppendBody("设置进程组ID出错<P>");
				}
				if(NULL==(fp=popen((cmd+" 2>&1").c_str(),"r")))
				{
					m_respond.AppendBody("<P><FONT color=RED>无法执行,原因:popen error</FONT><P>");
					if(!m_respond.Flush(m_s))return true;
				}
				else
				{
					int fd=fileno(fp);
					int flags;
					fd_set fdset;
					struct timeval tv;

					tv.tv_sec=300;
					tv.tv_usec=0;
					flags = fcntl(fd, F_GETFL, 0);
					flags |= O_NONBLOCK;
					fcntl(fd, F_SETFL, flags);

					char * tmpp;
					m_respond.AppendBody("开始执行&nbsp;");
					m_respond.AppendBody(CHtmlDoc::HTMLEncode(cmd));
					m_respond.Flush(m_s);
					m_respond.AppendBody("<HR></HR><CODE>");
					while(true)
					{
						FD_ZERO(&fdset);
						FD_SET(fd,&fdset);
#ifdef _HPOS
						int selectret=select(fd+1,(int *)&fdset,NULL,NULL,&tv);
#else
						int selectret=select(fd+1,&fdset,NULL,NULL,&tv);
#endif
						if(selectret<0)
						{
							LOG<<"select error"<<ENDE;
						}
						else if(0==selectret)
						{//超时没有数据
							m_respond.AppendBody("注意,长时间没有收到输出.");
							if(!m_respond.Flush(m_s))
							{
								LOG<<"发送失败,客户端已断开,直接退出"<<ENDI;
								if(term)
								{
									if(0!=kill(0,SIGTERM))
									{
										LOG<<"发送停止信号出错,shell会持续执行到命令结束"<<ENDE;
									}
								}
								return true;
							}
							continue;
						}
						else
						{
						}

						bool fileend=false;
						while(true)
						{
							tmpp=fgets(buf,int(bufsize-1),fp);
							if(NULL==tmpp)
							{
								//正常结束
								if(0!=feof(fp))
								{
									fileend=true;
									break;
								}

								if(EWOULDBLOCK==errno || EAGAIN==errno)
								{//无数据
									break;
								}
								else
								{//出错结束
									m_respond.AppendBody("<P><FONT color=RED>执行出错,原因:read error</FONT><P>");
									m_respond.AppendBody(strerror(errno));
									m_respond.Flush(m_s);
									fileend=true;
									break;
								}
							}
							else
							{
								m_respond.AppendBody(LogToHtml(buf,false,false));
								m_respond.AppendBodyHtmlScroll();
								if(!m_respond.Flush(m_s))
								{
									LOG<<"发送失败,客户端已断开,直接退出"<<ENDI;
									if(term)
									{
										if(0!=kill(0,SIGTERM))
										{
											LOG<<"发送停止信号出错,shell会持续执行到命令结束"<<ENDE;
										}
									}
									return true;
								}
							}
						}
						if(fileend)break;
					}
					m_respond.AppendBody("</CODE><HR></HR>");
					int ret=pclose(fp);
					if(0!=ret)
					{
						if(WIFEXITED(ret))
						{
							sprintf(buf,"<FONT color=RED>执行完毕,返回代码 %d 。</FONT><BR>",WEXITSTATUS(ret));//(0xFF00&ret)/256);
						}
						else if(WIFSIGNALED(ret))
						{
							sprintf(buf,"<FONT color=RED>被信号终止,信号 %d 。</FONT><BR>",WTERMSIG(ret));
						}
						else if(WCOREDUMP(ret))
						{
							sprintf(buf,"<FONT color=RED>执行失败,COREDUMP。</FONT><BR>");
						}
						else
						{
							sprintf(buf,"<FONT color=RED>未知的返回值:%d。</FONT><BR>",ret);
						}
					}
					else sprintf(buf,"执行完毕,返回代码 %d 。<BR>",ret);
					m_respond.AppendBody(buf);
				}
			}

			if(!noform)
			{
				char cwd[1024];
				if(NULL!=getcwd(cwd,1024))
				{
					sprintf(buf,
						"<FORM ACTION=\"/shell.asp\" METHOD=\"GET\" >\n"
						"当前路径:%s<BR>"
						"<INPUT TYPE=\"hidden\" NAME=\"curdir\" VALUE=\"%s\" >\n"
						"切换路径到:<INPUT TYPE=\"text\" SIZE=\"30\" NAME=\"changedir\" ><BR>\n"
						"Shell命令: <INPUT TYPE=\"text\" SIZE=\"30\" NAME=\"command\" VALUE=\"%s\">\n"
						"<INPUT TYPE=SUBMIT VALUE=\"执行\" >\n"
						"</FORM>\n"
						,cwd,cwd,cmd.c_str());
				}
				else
				{
					sprintf(buf,"获取当前工作路径出错");
				}
				m_respond.AppendBody(buf);
			}

			delete[] buf;
			return true;
#endif
		}

三、详解

3.1 参数

(我还没写完)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1303873.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

商城免费搭建之java商城 java电子商务Spring Cloud+Spring Boot+mybatis+MQ+VR全景+b2b2c 鸿鹄云商

鸿鹄云商 SAAS云产品概述 【SAAS云平台】打造全行业全渠道全场景的SaaS产品&#xff0c;为店铺经营场景提供一体化解决方案&#xff1b;门店经营区域化、网店经营一体化&#xff0c;本地化、全方位、一站式服务&#xff0c;为多门店提供统一运营解决方案&#xff1b;提供丰富多…

MySQL:从MySQL看主从架构高可用性实现

目录 1 主备延迟 1.1 主备延迟 1.2 主备延迟的来源 1.2.1 主备机性能有差距 1.2.2 备库压力大 1.2.3 大事务 1.3 主备延迟的排查思路 3&#xff09;查看MySQL状态 2 主备切换策略 2.1 可靠性优先策略 2.2 可用性优先策略 2.3 常见切换技术 从进入互联网时代开始&a…

Linux之进程(三)(环境变量)

目录 一、基本概念 二、环境变量 1、PATH 2、HOME 3、SHELL 三、环境变量参数 四、argc和argv 一、基本概念 环境变量(environment variables)一般是指在操作系统中用来指定操作系统运行环境的一些参数。如&#xff1a;临时文件夹位置和系统文件夹位置等。环境变量通常…

【软考】信息系统项目管理师论文方向猜想

报喜不报忧&#xff0c;每天都在为鸡零狗碎推诿扯皮&#xff0c;属实是有辱师门。 通过软考&#xff0c;目前算是真正有意义的事情。 虽然都说高项的论文是个玄学&#xff0c;但是道听途说了一些通关感想还是蛮有启发的。 文件要求 参考了一份广西省高级工程师评审的文件&am…

【C语言】二分查找(详解)

&#x1f3a5; 岁月失语唯石能言的个人主页 &#x1f525;个人栏专&#xff1a;秒懂C语言 ⭐若在许我少年时&#xff0c;一两黄金一两风 一、二分查找的思路 二分查找也叫折半查找&#xff0c;二分查找针对的是一个有序的数据集合&#xff0c;每次都通过跟区间的…

C# 图解教程 第5版 —— 第18章 泛型

文章目录 18.1 什么是泛型18.2 C# 中的泛型18.3 泛型类18.3.1 声明泛型类18.3.2 创建构造类型18.3.3 创建变量和实例18.3.4 使用泛型的示例18.3.5 比较泛型和非泛型栈 18.4 类型参数的约束18.4.1 Where 子句18.4.2 约束类型和次序 18.5 泛型方法18.5.1 声明泛型方法18.5.2 调用…

宿舍智能电能表预付费系统的费控策略及应用

安科瑞电气股份有限公司 上海嘉定 201801 摘要:基于智能电能表的预付费系统平台可以实现对预付费客户的适时算费、远程费控和服务。预付费系统的费控策略包括算费子策略、催费预警提醒子策略、欠费停电子策略,介绍3个子策略的制定原则、设计流程,并以示例说明策略的实现方式,通…

每日一博 - Cache Miss Attack

文章目录 概述解决思路缓存空值键并设置短期 TTL&#xff08;生存时间&#xff09;使用布隆过滤器 伪代码1. 缓存空值键并设置短期 TTLa. 缓存空值键b. 设置短期 TTL 2. 使用布隆过滤器a. 集成布隆过滤器b. 查询布隆过滤器 进一步优化系统性能的建议 概述 在缓存管理中&#x…

(C++)VS下sizeof(string(““))与linux-g++下sizeof(string(““))大小区别及原因剖析

个人主页&#xff1a;Lei宝啊 愿所有美好如期而遇 说明 博主是x86平台&#xff0c;所以下面的结果是28&#xff1b;x64平台下是40&#xff0c;size_t变了&#xff0c;由int变long long。 接下来我们先来介绍 vs 下string的数据结构 我们可以看到有一个_Buf数组&#xff0c;…

【IDEA】反向撤销操作快捷键 ctrl+shift+z 和搜狗热键冲突的解决办法

当我们执行某些操作时与搜狗热键冲突&#xff0c;直接取消搜狗的快捷键即可&#xff01;&#xff01;&#xff01;以下以 ctrlshiftz 为例。 在输入悬浮框右键找到更多设置 按键里面找到系统功能快捷键设置 取消掉冲突的热键即可

Word插件-好用的插件-PPT 素材该怎么积累-大珩助手

PPT 素材该怎么积累&#xff1f; 使用大珩助手中的素材库功能&#xff0c;将Word中的&#xff0c;或系统中的文本文件、图片、其他word文档、pdf&#xff0c;所有见到的好素材&#xff0c;一键收纳。 步骤&#xff1a;选中文件&#xff0c;按住鼠标左键拖到素材库界面中&…

IBM DMC运行在RedHat 9的FIPS模式

文章目录 环境步骤打开RedHat的FIPS模式安装DMCnssdbpk12util和certutil导入certificate导入Liberty的SSL key导入Java的certificate查看nssdb&#xff08;可选&#xff09; 配置jvm.options配置server.xml配置java.security配置dswebserver_override.properties重启DMC验证 常…

End-to-End Reconstruction-Classification Learning for Face Forgery Detection

一、研究背景 现有模型主要通过提取特定的伪造模式进行深度伪造检测&#xff0c;导致学习到的表征与训练集中已知的伪造类型高度相关&#xff0c;因此模型难以泛化到未知的伪造类型上使用。 二、研究动机 1.真实样本的特征分布相对更为紧凑&#xff0c;因此学习真实人脸之间的…

漏洞复现-华为Auth-HTTP服务器任意文件读取漏洞(附漏洞检测脚本)

免责声明 文章中涉及的漏洞均已修复&#xff0c;敏感信息均已做打码处理&#xff0c;文章仅做经验分享用途&#xff0c;切勿当真&#xff0c;未授权的攻击属于非法行为&#xff01;文章中敏感信息均已做多层打马处理。传播、利用本文章所提供的信息而造成的任何直接或者间接的…

MyBatis缓存机制流程分析

前言 在进行分析之前&#xff0c;建议快速浏览之前写的理解MyBatis原理、思想&#xff0c;这样更容易阅读、理解本篇内容。 验证一级缓存 MyBatis的缓存有两级&#xff0c;一级缓存默认开启&#xff0c;二级缓存需要手动开启。 重复读取跑缓存 可以看到&#xff0c;第二次…

ubuntu install sqlmap

refer: https://github.com/sqlmapproject/sqlmap 安装sqlmap&#xff0c;可以直接使用git 克隆整个sqlmap项目&#xff1a; git clone --depth 1 https://github.com/sqlmapproject/sqlmap.git sqlmap-dev 2.然后进入sqlmap-dev&#xff0c;使用命令&#xff1a; python s…

利差是什么?anzo Capital昂首资本换个角度学利差

在交易论坛上最常问也是问的最多的一个问题就是“外汇中的利差是多少?”&#xff0c;今天让anzo Capital昂首资本换个角度试着找出答案。 在现代生活中&#xff0c;我们必须为商品和服务付费&#xff0c;包括金融市场上提供的商品和服务。同样的在金融市场中也需要为商品和服…

庙算兵棋推演平台配置

9月23开始&#xff0c;9月26完成。因为那时刚从大连回来&#xff0c;十一之后又一个紧急项目当项目负责人&#xff0c;所以隔了这么久才发出来。 我尝试进行制作平台AI&#xff0c;想在我的小平板上配好&#xff0c;最好还可以移植。于是我采用WSL&#xff08;windows自带的do…

万界星空科技MES系统中的生产调度流程

MES系统生产调度的目标是达到作业有序、协调、可控和高效的运行效果&#xff0c;作业计划的快速生成以及面向生产扰动事件的快速响应处理是生产调度系统的核心和关键。 为了顺利生成作业计划&#xff0c;需要为调度系统提供完整的产品和工艺信息&#xff0c;MES系统生成作业计…

打工人副业变现秘籍,某多/某手变现底层引擎-Stable Diffusion 局部重绘(利用SD进行换脸)

首先明确一个概念:绘图是对整个图片进行重绘,但局部重绘是对你选中的位置重绘,这就是两个功能的不同点。 局部重绘详细步骤: 1、用画笔涂黑你想修改的地方,图片右边的蓝色点可以拖动 改变画笔大小,边缘适合用小画笔,中间用粗画笔; 2、在正向关…