C++ ile QT için signal ve slot kullanmaya örnek bir proje
1 ////////////////////////////////////////////////////// Main.cpp
2 //////////////////////////////////////////////////////
3
4 #include <QtGui>
5 #include "pencere.h"
6
7 int main(int argc, char *argv[])
8 {
9 QApplication app(argc, argv);
10
11 if (!QSystemTrayIcon::isSystemTrayAvailable()) {
12 QMessageBox::critical(0, QObject::tr("Uyari!"),
13 QObject::tr("Bu bilgisayarda herhangi bir "
14 "görev bölmesi bulunamad?."));
15 return 1;
16 }
17
18
19 AnaPencere p;
20
21 p.show();
22 return app.exec();
23 }
24
25 ////////////////////////////////////////////////////// pencere.h
26 //////////////////////////////////////////////////////
27
28 #include <QMainWindow>
29 #include <QSystemTrayIcon>
30 #include "ui_pencere.h"
31
32 class AnaPencere:public QMainWindow, Ui::MainWindow
33 {
34 Q_OBJECT
35 public:
36 QSystemTrayIcon *SistemTepsiSimgesi;
37
38 //kurucu fonksiyon
39 AnaPencere():QMainWindow()
40 {
41 setupUi(this);
42 connect(dugme, SIGNAL(clicked()), this, SLOT(balonac()));
43
44 SistemTepsisineSimgeKoy();
45 }
46
47
48
49 public slots:
50 void balonac()
51 {
52 // bu slot dugmeye basinca calisacak
53 QSystemTrayIcon::MessageIcon ipucusimgesi = QSystemTrayIcon::MessageIcon(1);
54 SistemTepsiSimgesi->showMessage(baslik->text(), ileti->toPlainText(), ipucusimgesi, 5000);
55 }
56
57 void AnaPencere::SistemTepsisineSimgeKoy()
58 {
59 //Buradan simgeye sa? tu? menüsü eklenebilir.
60 SistemTepsiSimgesi = new QSystemTrayIcon(this);
61 SistemTepsiSimgesi->show();
62 SistemTepsiSimgesi->setIcon(QIcon(QString::fromUtf8(":/simgeler/resimler/heart.svg")));
63 }
64
65
66 };
67
68
69 ////////////////////////////////////////////////////// pencere.ui
70 //////////////////////////////////////////////////////
71
72 <ui version="4.0" >
73 <class>MainWindow</class>
74 <widget class="QMainWindow" name="MainWindow" >
75 <property name="geometry" >
76 <rect>
77 <x>0</x>
78 <y>0</y>
79 <width>349</width>
80 <height>265</height>
81 </rect>
82 </property>
83 <property name="windowTitle" >
84 <string>Pencere</string>
85 </property>
86 <property name="windowIcon" >
87 <iconset resource="resim_kaynagi.qrc" >:/simgeler/resimler/bad.svg</iconset>
88 </property>
89 <widget class="QWidget" name="centralwidget" >
90 <widget class="QLabel" name="etiket1" >
91 <property name="geometry" >
92 <rect>
93 <x>10</x>
94 <y>20</y>
95 <width>44</width>
96 <height>18</height>
97 </rect>
98 </property>
99 <property name="text" >
100 <string>Ba?l?k :</string>
101 </property>
102 </widget>
103 <widget class="QLabel" name="etiket2" >
104 <property name="geometry" >
105 <rect>
106 <x>20</x>
107 <y>60</y>
108 <width>31</width>
109 <height>18</height>
110 </rect>
111 </property>
112 <property name="text" >
113 <string>?leti :</string>
114 </property>
115 </widget>
116 <widget class="QLineEdit" name="baslik" >
117 <property name="geometry" >
118 <rect>
119 <x>80</x>
120 <y>20</y>
121 <width>251</width>
122 <height>23</height>
123 </rect>
124 </property>
125 </widget>
126 <widget class="QTextEdit" name="ileti" >
127 <property name="geometry" >
128 <rect>
129 <x>80</x>
130 <y>60</y>
131 <width>251</width>
132 <height>141</height>
133 </rect>
134 </property>
135 </widget>
136 <widget class="QPushButton" name="dugme" >
137 <property name="enabled" >
138 <bool>true</bool>
139 </property>
140 <property name="geometry" >
141 <rect>
142 <x>230</x>
143 <y>220</y>
144 <width>101</width>
145 <height>27</height>
146 </rect>
147 </property>
148 <property name="text" >
149 <string>Göster</string>
150 </property>
151 </widget>
152 </widget>
153 </widget>
154 <resources>
155 <include location="resim_kaynagi.qrc" />
156 </resources>
157 <connections/>
158 </ui>
159
160
161 ////////////////////////////////////////////////////// resim_kaynagi.qrc
162 ////////////////////////////////////////////////////// Bu çok önemli degil, saatin yanina simge koymak için kullanmistim.
163 ////////////////////////////////////////////////////// internetten herhangi bir svg uzantili resim bulup koyun. ben wikipedia 'dan bulmustum.
164
165
166 <RCC>
167 <qresource prefix="/simgeler" >
168 <file>resimler/bad.svg</file>
169 <file>resimler/heart.svg</file>
170 <file>resimler/trash.svg</file>
171 </qresource>
172 </RCC>
src/css/styles.css
1 .flatColorRectangleSkin {
2
3 fontFamily: Arial;
4 fontSize: 12;
5 color: #FFFFFF;
6 textAlign:left;
7 width:150;
8 height:30;
9
10 upSkin:ClassReference('charts.NodeSkin');
11 downSkin:ClassReference('programmaticSkinClasses.FlatColorRectangleSkin');
12 overSkin:ClassReference('programmaticSkinClasses.FlatColorRectangleSkin');
13 disabledSkin:ClassReference('programmaticSkinClasses.FlatColorRectangleSkin');
14 }
15
16 .flatColorRoundedRectangleSkin {
17
18 fontFamily: Arial;
19 fontSize: 12;
20 color: #FFFFFF;
21 textAlign:left;
22 width:150;
23 height:30;
24
25 upSkin:ClassReference('programmaticSkinClasses.FlatColorRoundedRectangleSkin');
26 downSkin:ClassReference('programmaticSkinClasses.FlatColorRoundedRectangleSkin');
27 overSkin:ClassReference('programmaticSkinClasses.FlatColorRoundedRectangleSkin');
28 disabledSkin:ClassReference('programmaticSkinClasses.FlatColorRoundedRectangleSkin');
29 }
30
31 .gradientRectangleSkin {
32
33 fontFamily: Arial;
34 fontSize: 12;
35 color: #FFFFFF;
36 textAlign:left;
37 width:150;
38 height:30;
39
40 upSkin:ClassReference('programmaticSkinClasses.GradientRectangleSkin');
41 downSkin:ClassReference('programmaticSkinClasses.GradientRectangleSkin');
42 overSkin:ClassReference('programmaticSkinClasses.GradientRectangleSkin');
43 disabledSkin:ClassReference('programmaticSkinClasses.GradientRectangleSkin');
44 }
src/charts/Node.as
1 package charts
2 {
3 import flash.display.DisplayObject;
4 import flash.events.Event;
5
6 import mx.core.IFlexDisplayObject;
7 import mx.core.UIComponent;
8 import mx.core.mx_internal;
9 import mx.events.FlexEvent;
10 import mx.messaging.messages.ErrorMessage;
11 import mx.styles.ISimpleStyleClient;
12
13 use namespace mx_internal;
14
15 //[Style(name="upSkin",type="Class",inherit="no")]
16
17 public class Node extends UIComponent
18 {
19 public var nodeId:int = -1;
20
21 public function Node(/*nodeId_:int*/)
22 {
23 //nodeId = nodeId_;
24 addEventListener(FlexEvent.INITIALIZE, myInitialize);
25 }
26
27 protected function myInitialize(event:Event):void
28 {
29 if(nodeId == -1)
30 throw new Error("The Node ID Property is Mandatory");
31 }
32
33 protected override function updateDisplayList(unscaledWidth:Number,
34 unscaledHeight:Number):void
35 {
36 showSkin("upSkin");
37 }
38
39 mx_internal function showSkin(skinName:String):void
40 {
41 var skinClass:Class = Class(getStyle(skinName));
42 var skin:IFlexDisplayObject = IFlexDisplayObject(getChildByName(skinName));
43
44 if (!skin)
45 {
46 if (skinClass)
47 {
48 skin = IFlexDisplayObject(new skinClass());
49 skin.name = skinName;
50 (skin as ISimpleStyleClient).styleName = this;
51 addChild(DisplayObject(skin));
52 skin.setActualSize(unscaledWidth, unscaledHeight);
53 }
54 }
55
56 }
57
58
59 }
60 }
src/charts/NodeSkin.mxml
1 <?xml version="1.0" encoding="utf-8"?>
2 <Degrafa:GraphicBorderSkin xmlns:mx="http://www.adobe.com/2006/mxml"
3 xmlns:Degrafa="http://www.degrafa.com/2007">
4
5 <mx:Script>
6 <![CDATA[
7 [Bindable]
8 private var awidth:Number=0;
9
10 [Bindable]
11 private var aheight:Number=0;
12
13 override protected function updateDisplayList(unscaledWidth:Number, unscaledHeight:Number):void{
14 super.updateDisplayList(unscaledWidth, unscaledHeight);
15 awidth = unscaledWidth;
16 aheight = unscaledHeight;
17 }
18 ]]>
19 </mx:Script>
20
21 <Degrafa:fills>
22 <Degrafa:RadialGradientFill id="MainFill" angle="90" >
23 <Degrafa:GradientStop ratio="0" alpha="1" color="#EE9819"/>
24 <Degrafa:GradientStop ratio="1" alpha="1" color="#FAE38F"/>
25 </Degrafa:RadialGradientFill>
26
27 <Degrafa:RadialGradientFill id="WashFill" angle="90" >
28 <Degrafa:GradientStop ratio="0" alpha=".75" color="#FFFFFF"/>
29 <Degrafa:GradientStop ratio="1" alpha="0" color="#FFFFFF"/>
30 </Degrafa:RadialGradientFill>
31 </Degrafa:fills>
32
33 <Degrafa:stroke>
34 <Degrafa:SolidStroke color="#EE9819" id="theStroke" />
35 </Degrafa:stroke>
36
37 <Degrafa:geometry>
38 <Degrafa:Circle centerX="{awidth/2}" centerY="{aheight/2}" radius="{Math.max(awidth/2,aheight/2)}"
39 fill="{MainFill}" stroke="{theStroke}" />
40
41 <Degrafa:Ellipse width="{awidth-7}" height="{aheight/1.5}" x="3" y="3"
42 fill="{WashFill}" />
43 </Degrafa:geometry>
44
45 </Degrafa:GraphicBorderSkin>
src/programmaticSkinClasses/GradientRectangleSkin.as
1 package programmaticSkinClasses {
2
3 import mx.core.UIComponent;
4 import flash.filters.DropShadowFilter;
5
6 public class GradientRectangleSkin extends UIComponent {
7
8 import flash.display.Graphics;
9 import flash.geom.Rectangle;
10 import mx.graphics.GradientEntry;
11 import mx.graphics.LinearGradient;
12
13 protected override function updateDisplayList(unscaledWidth:Number, unscaledHeight:Number):void {
14 super.updateDisplayList(unscaledWidth,unscaledHeight);
15 var w:Number = unscaledWidth;
16 var h:Number = unscaledHeight;
17
18 // hold the values of the gradients depending on button state
19 var backgroundFillColor:Number;
20 var backgroundFillColor2:Number;
21 var backgroundFillColor3:Number;
22
23
24 var fill:LinearGradient = new LinearGradient();
25
26 // reference the graphics object of this skin class
27 var g:Graphics = graphics;
28 g.clear();
29
30 // which skin is the button currently looking for? Which skin to use?
31 switch (name) {
32 case "upSkin":
33 backgroundFillColor = 0x929292;
34 backgroundFillColor2 = 0x000000;
35 break;
36 case "overSkin":
37 backgroundFillColor = 0x696969;
38 backgroundFillColor2 = 0x504F4F;
39 break;
40 case "downSkin":
41 backgroundFillColor = 0x888888;
42 backgroundFillColor2 = 0x777777;
43 color: 0xFF0000;
44 break;
45 case "disabledSkin":
46 backgroundFillColor = 0xCCCCCC;
47 backgroundFillColor2 = 0xCCCCCC;
48 break;
49 }
50 // depending on which state the button's in, we set our color for the
51 // gradients on the skin
52 var g1:GradientEntry = new GradientEntry(backgroundFillColor,.10,100);
53 var g2:GradientEntry = new GradientEntry(backgroundFillColor2,.60,100);
54
55 fill.entries = [g1,g2];
56 fill.angle = 90;
57 // fill the rectangle
58 g.moveTo(0,0);
59 fill.begin(g,new Rectangle(0,0,w,h));
60 g.lineTo(w,0);
61 g.lineTo(w,h);
62 g.lineTo(0,h);
63 g.lineTo(0,0);
64 fill.end(g);
65 // if we're not showing the down skin, show the shadow. Otherwise hide it on the "down state" to look like it's being pressed
66 if(name != "downSkin") {
67 filters = [new DropShadowFilter(4, 45,0x000000,.2)];
68 }
69 }
70 }
71 }
src/programmaticSkinClasses/FlatColorRoundedRectangleSkin.as
1 package programmaticSkinClasses {
2
3 import flash.filters.DropShadowFilter;
4 import mx.skins.ProgrammaticSkin;
5
6 public class FlatColorRoundedRectangleSkin extends ProgrammaticSkin {
7
8 protected override function updateDisplayList(unscaledWidth:Number,unscaledHeight:Number):void{
9
10 super.updateDisplayList(unscaledWidth, unscaledHeight);
11 var backgroundFillColor:Number;
12 var cornerRadius:Number = getStyle("cornerRadius");
13 var backgroundAlpha:Number = getStyle("backgroundAlpha");
14
15 graphics.clear();
16
17 switch (name) {
18 case "upSkin":
19 backgroundFillColor = 0x6987AC;
20 break;
21 case "overSkin":
22 backgroundFillColor = 0x92B0C0;
23 break;
24 case "downSkin":
25 backgroundFillColor = 0x92B0C0;
26 color: 0xFF0000;
27 break;
28 case "disabledSkin":
29 backgroundFillColor = 0xCCCCCC;
30 break;
31 }
32
33 graphics.beginFill(backgroundFillColor);
34 drawRoundRect(0,0,unscaledWidth,unscaledHeight,{tl: cornerRadius, tr: cornerRadius, bl: cornerRadius, br: cornerRadius},
35 backgroundFillColor,backgroundAlpha);
36 graphics.endFill();
37
38 if(name != "downSkin") {
39 filters = [new DropShadowFilter(4, 45,0x000000,.2)];
40 }
41
42 }
43 }
44 }
src/programmaticSkinClasses/FlatColorRectangleSkin.as
1 package programmaticSkinClasses {
2
3 import flash.filters.DropShadowFilter;
4 import mx.effects.Glow;
5 import mx.skins.ProgrammaticSkin;
6
7 public class FlatColorRectangleSkin extends ProgrammaticSkin {
8
9 protected override function updateDisplayList(unscaledWidth:Number,unscaledHeight:Number):void{
10
11 super.updateDisplayList(unscaledWidth, unscaledHeight);
12 var backgroundFillColor:Number;
13 graphics.clear();
14
15 switch (name) {
16 case "upSkin":
17 backgroundFillColor = 0x69AC69;
18 break;
19 case "overSkin":
20 backgroundFillColor = 0x808080;
21 break;
22 case "downSkin":
23 backgroundFillColor = 0xACACAB;
24 break;
25 case "disabledSkin":
26 backgroundFillColor = 0xCCCCCC;
27 break;
28 }
29
30 graphics.beginFill(backgroundFillColor);
31 graphics.drawRect(0, 0, unscaledWidth, unscaledHeight);
32 graphics.endFill();
33
34 if(name != "downSkin") {
35 filters = [new DropShadowFilter(4, 45,0x000000,.2)];
36 }
37
38 }
39 }
40 }
src/ProgrammaticSkinning.mxml
1 <?xml version="1.0" encoding="utf-8"?>
2 <mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute"
3 xmlns:components="charts.*">
4
5 <mx:Style source="css/styles.css" />
6
7 <components:Node id="button4" x="22" y="170" nodeId="1"
8 styleName="flatColorRoundedRectangleSkin" height="32" width="345"/>
9
10 <components:Node id="button5" x="22" y="240" nodeId="2"
11 styleName="gradientRectangleSkin" height="32" width="345"/>
12
13 <components:Node id="button6" x="22" y="295" nodeId="3"
14 styleName="flatColorRectangleSkin" height="32" width="32"/>
15
16 </mx:Application>
hasErrorLoginUIManipulation(outputLoc,key)
1 function hasErrorLoginUIManipulation(outputLoc,key) {
2
3 $('loginPage').style.display = 'block';
4
5 if (getResourceString(key).indexOf('undefine:') == -1) {
6 errorHandling('login_error_msg', getResourceString(key), 'block');
7 } else {
8 errorHandling('login_error_msg', outputLoc["description"], 'block');
9 }
10
11 }
This was part of an assignment for a Computer Networks course. It implemente GET and conditional GET. Supports persistent connections.
1 // Copyright (c) 2008, Luis Rei (http://luisrei.com <luis.rei@gmail.com>)
2 // All rights reserved.
3 //
4 // Redistribution and use in source and binary forms, with or without
5 // modification, are permitted provided that the following conditions are met:
6 //
7 // * Redistributions of source code must retain the above copyright notice,
8 // this list of conditions and the following disclaimer.
9 // * Redistributions in binary form must reproduce the above copyright
10 // notice, this list of conditions and the following disclaimer in the
11 // documentation and/or other materials provided with the distribution.
12 // * Neither the name of the <ORGANIZATION> nor the names of its
13 // contributors may be used to endorse or promote products derived from
14 // this software without specific prior written permission.
15 //
16 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
17 // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19 // ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
20 // LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21 // CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22 // SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
23 // INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
24 // CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
25 // ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
26 // POSSIBILITY OF SUCH DAMAGE.
27
28
29
30 #include <sys/types.h>
31 #include <sys/socket.h>
32 #include <sys/stat.h>
33 #include <netinet/in.h>
34 #include <arpa/inet.h>
35 #include <sys/wait.h>
36 #include <stdio.h>
37 #include <string.h>
38 #include <getopt.h>
39 #include <time.h>
40 #include <stdlib.h>
41 #include <unistd.h>
42 #include <errno.h>
43 #include <fcntl.h>
44 #include <signal.h>
45 #include <netdb.h>
46 #include <strings.h>
47
48
49 #define MAXLEN 1024
50 #define TERMINATOR1 "\xD\xA\xD\xA" /*CRLFCRLF - separates header from msg*/
51 #define TERMINATOR2 "\n\n" /*apparently this is supposed to work too*/
52 #define SEP " \xD\xA\n\0" /*this is used for string processing*/
53 #define BACKLOG 10
54 #define DEFAULT_PORT 80
55 #define DEFAULT_ROOT "/var/www/data"
56 #define SERVER "reihttpd/0.1.0\n"
57
58
59 #define R_BADREQUEST "<html><head>\n\
60 <title>400 Bad Request</title>\n\
61 </head><body>\n\
62 <h1>Bad Request</h1>\n\
63 <p>Your browser sent a request that this server could not understand.<br />\n\
64 </p>\n\
65 </body></html>\n"
66
67 #define R_FORBIDDEN "<html><head>\n\
68 <title>403 Forbidden</title>\n\
69 </head><body>\n\
70 <h1>Forbidden</h1>\n\
71 <p>You don't have permission to access this resource.</p>\n\
72 </body></html>\n"
73
74 #define R_NOTFOUND "<html><head>\n\
75 <title>404 Not Found</title>\n\
76 </head><body>\n\
77 <h1>Not Found</h1>\n\
78 <p>The requested URL was not found on this server.</p>\n\
79 </body></html>\n"
80
81 #define R_NOTIMPLEMENTED "<html><head>\n\
82 <title>501 Not Implemented</title>\n\
83 </head><body>\n\
84 <h1>Not Implemented</h1>\n\
85 <p>The method you tried to use is not supported by this server.</p>\n\
86 </body></html>\n"
87
88 #define R_INTERNAL "<html><head>\n\
89 <title>500 Internal Server Error</title>\n\
90 </head><body>\n\
91 <h1>Internal Server Error</h1>\n\
92 <p>Something is broken. Try going back to where you came from.</p>\n\
93 </body></html>\n"
94
95 typedef enum _code {
96 C_OK = 202,
97 C_NOTMOD = 304,
98 C_BADREQUEST = 400,
99 C_FORBIDDEN = 403,
100 C_NOTFOUND = 404,
101 C_INTERNAL = 500,
102 C_NOTIMPLEMENTED = 501
103 } code;
104
105 int port;
106 char *root;
107
108
109 int process_request(int sockfd, char *buf, int bytes) {
110 struct stat st;
111 struct tm since_tm, file_tm;
112 code rcode;
113 time_t now, since_tt, file_tt;
114 size_t fsize;
115 int file_des;
116 char *line;
117 char *request, *location, *protocol, *host, *since, *connection, *rstr;
118 char *args[MAXLEN];
119 char rbuf[MAXLEN];
120 char temp[MAXLEN];
121 char headers[MAXLEN];
122 int ret, ii, argc, rbytes, major, minor;
123 int COND_FLAG;
124
125
126 printf("++++++++++++++++++++++ REQUEST ++++++++++++++++++++++++++++\n");
127 printf("%s", buf);
128 printf("---------------------- REQUEST ----------------------------\n");
129
130
131 argc = 0;
132 line = strtok(buf, "\n");
133 do {
134 args[argc] = (char *) malloc(MAXLEN);
135 if (args[argc] == NULL) {
136 perror("malloc");
137 exit(0);
138 }
139 strncpy(args[argc], line, MAXLEN-1);
140
141 argc++;
142 } while ((line = strtok(NULL, "\n")) != NULL);
143
144 /* Parse the GET request */
145 request = strtok(args[0], SEP);
146 location = strtok(NULL, SEP);
147 protocol = strtok(NULL, SEP);
148
149
150 /*check the protocol used, if < HTTP/1.1 it's a non-persistent connection*/
151 major = minor = 0;
152 if (protocol == NULL)
153 ret = -1; /*protocol not specified*/
154 else {
155 strncpy(temp, protocol, MAXLEN-1);
156 line = strtok(temp, "/");
157 if (strcmp(temp, "HTTP") != 0)
158 ret = -1; /*protocol not HTTP*/
159 else {
160 line = strtok(NULL, ".");
161 major = atoi(line);
162 if(major < 1)
163 ret = -1; /*< HTTP/1.0*/
164 else {
165 line = strtok(NULL, "\0");
166 minor = atoi(line);
167 if(major == 1 && minor == 0)
168 ret = -1; /*HTTP/1.0*/
169 }
170 }
171 }
172
173 /*method*/
174 if (strcmp(request, "GET") == 0) {
175 if (strcmp(location, "/") == 0)
176 location = "index.html";
177 else if(*location == '/')
178 location++; /*skip forward slash */
179 else
180 exit(0);
181
182
183 file_des = open(location, O_RDONLY);
184 if (file_des < 0) {
185 if (errno == EACCES)
186 rcode = C_FORBIDDEN;
187 else
188 rcode = C_NOTFOUND; /*as far as I care*/
189 }
190 else
191 rcode = C_OK;
192
193 /* Parse Headers */
194 connection = NULL;
195 host = NULL;
196 since = NULL;
197 COND_FLAG = 0;
198
199 for (ii = 1; ii < argc; ii++) {
200 line = strtok(args[ii], ": ");
201 if (line == NULL) {
202 printf("Line is null.\n");
203 continue;
204 }
205
206 /*host*/
207 else if (strcmp(line, "Host") == 0)
208 host = strtok(NULL, " ");
209
210 /*If-Modified-Since*/
211 else if(strcmp(line, "If-Modified-Since") == 0) {
212 since = strtok(NULL, "\n");
213 COND_FLAG = 1;
214 if(since != NULL)
215 since++; /*skip whitespace*/
216 else {
217 COND_FLAG = 0;
218 continue;
219 }
220
221 if (since[3] == ',') { /*Sun, 06 Nov 1994 08:49:37 GMT*/
222 rstr = strptime(since, "%a, %d %b %Y %T GMT", &since_tm);
223 if(rstr == NULL) {
224 COND_FLAG = 0;
225 }
226 }
227 else if (since[6] == ',') { /*Sunday, 06-Nov-94 08:49:37 GMT*/
228 rstr = strptime(since, "%a, %d-%b-%y %T GMT", &since_tm);
229 if(rstr == NULL) {
230 COND_FLAG = 0;
231 }
232 }
233 else { /*Sun Nov 6 08:49:37 1994*/
234 rstr = strptime(since, "%a %b %d %T %Y", &since_tm);
235 if(rstr == NULL) {
236 COND_FLAG = 0;
237 }
238 }
239 if (COND_FLAG) {
240 since_tt = mktime(&since_tm);
241 if (time(NULL) < since_tt)
242 COND_FLAG = 0; /*this is not the future!*/
243 }
244 }
245
246 /*Connection*/
247 else if(strcmp(line, "Connection") == 0)
248 connection = strtok(NULL, " ");
249
250 /*unknown*/
251 else
252 continue;
253 }
254
255 /*if protocol >= HTTP/1.1 Host must be specified*/
256 if ((major == 1 && minor >= 1) || major > 1)
257 if (host == NULL) {
258 rcode = C_BADREQUEST;
259 }
260 }
261 else
262 rcode = C_NOTIMPLEMENTED;
263
264
265 /*build Header*/
266
267 /*get current time*/
268 now = time(NULL);
269
270 /*message type*/
271 if (rcode == C_OK) {
272 /*get size and last modified date*/
273 fstat(file_des, &st);
274
275
276 if (COND_FLAG) {
277 /* convert file time to a time_t value for comparison*/
278 /*this way of doing is lame but it works*/
279 strftime(temp, MAXLEN-1, "%a, %d %b %Y %T GMT%n",
280 gmtime(&st.st_mtimespec.tv_sec));
281 strptime(temp, "%a, %d %b %Y %T GMT", &file_tm);
282 file_tt = mktime(&file_tm);
283
284 /*compare*/
285 if(file_tt <= since_tt) { /*the file has not been modified*/
286 rcode = C_NOTMOD;
287 fsize = 0;
288 }
289 }
290 }
291
292 switch(rcode) {
293 case C_OK:
294 fsize = st.st_size;
295 sprintf(headers, "HTTP/1.1 %d OK\n", C_OK);
296 break;
297 case C_NOTMOD:
298 sprintf(headers, "HTTP/1.1 %d Not Modified\n", C_NOTMOD);
299 break;
300 case C_FORBIDDEN:
301 strcpy(rbuf, R_FORBIDDEN);
302 sprintf(headers, "HTTP/1.1 %d Forbidden\n", C_FORBIDDEN);
303 break;
304 case C_NOTFOUND:
305 strcpy(rbuf, R_NOTFOUND);
306 sprintf(headers, "HTTP/1.1 %d Not Found\n", C_NOTFOUND);
307 break;
308 case C_NOTIMPLEMENTED:
309 strcpy(rbuf, R_NOTIMPLEMENTED);
310 sprintf(headers, "HTTP/1.1 %d Not Implemented\n",
311 C_NOTIMPLEMENTED);
312 break;
313 case C_BADREQUEST:
314 strcpy(rbuf, R_BADREQUEST);
315 sprintf(headers, "HTTP/1.1 %d Bad Request\n", C_BADREQUEST);
316 break;
317 default: /*internal error*/
318 strcpy(rbuf, R_INTERNAL);
319 sprintf(headers, "HTTP/1.1 %d Internal Server Error\n",
320 C_INTERNAL);
321 break;
322 }
323
324 if(rcode != C_OK && rcode != C_NOTMOD) {
325 fsize = strlen(rbuf);
326 ret = -1;
327 }
328
329
330
331 /*example: Date: Mon, 05 May 2008 10:06:01 GMT*/
332 strcat(headers, "Date: ");
333 strftime(temp, MAXLEN-1, "%a, %d %b %Y %T GMT%n", gmtime(&now));
334 strcat(headers, temp);
335
336 /*example: Server: Apache/2.2.8 (Unix) [...]*/
337 strcat(headers, "Server: ");
338 strcat(headers, SERVER);
339
340 if (rcode == C_OK) {
341 /*example: Last-Modified: Mon, 05 May 2008 10:06:01 GMT*/
342 strcat(headers, "Last-Modified: ");
343 strftime(temp, MAXLEN-1, "%a, %d %b %Y %T GMT%n",
344 gmtime(&st.st_mtimespec.tv_sec));
345 strcat(headers, temp);
346 }
347
348 /*example: Content-Length: 5754 */
349 strcat(headers, "Content-Length: ");
350 sprintf(temp, "%lu\n", (unsigned long) fsize);
351 strcat(headers, temp);
352
353 /*TODO: example: Content-Type: text/html*/
354
355 /*add a newline*/
356 strcat(headers, "\n");
357
358
359 /*send header fields and data*/
360 printf("++++++++++++++++++++++ REPLY +++++++++++++++++++++++++++\n");
361 printf("header:\n%s", headers);
362 send(sockfd, headers, strlen(headers), 0);
363 if (rcode == C_OK)
364 while ((rbytes = read(file_des, rbuf, MAXLEN-1)) > 0)
365 send(sockfd, rbuf, rbytes, 0);
366 else
367 send(sockfd, rbuf, fsize, 0);
368 printf("message:\n%s\n", rbuf);
369 printf("---------------------- REPLY ---------------------------\n");
370
371
372 if (connection != NULL)
373 if (strncmp(connection, "close", 5) == 0)
374 ret = -1; /*client asked to close the connection*/
375
376 /*free dynamically allocated memory*/
377 for (ii=0; ii < argc; ii++)
378 free(args[ii]);
379
380
381 return ret;
382 }
383
384
385 int main(int argc, char** argv){
386
387 int sockfd, newsockfd;
388 unsigned int cli_size;
389 struct sockaddr_in serv_addr, cli_addr;
390 int childpid;
391 int opt, long_index;
392 char buf[MAXLEN], request[MAXLEN];
393 int bytes, ret;
394
395 static const char *opt_string = "hp:r:";
396 static const struct option long_opts[] = {
397 {"Port", required_argument, NULL, 'p'},
398 {"Root", required_argument, NULL, 'r'},
399 {"help", no_argument, NULL, 'h'},
400 {NULL, no_argument, NULL, 0}
401 };
402
403 /*set defaults*/
404 port = DEFAULT_PORT;
405 root = DEFAULT_ROOT;
406
407 /*command-line arguments*/
408 while ((opt = getopt_long(argc, argv, opt_string, long_opts, &long_index))
409