Initial Mercurial commit.

This commit is contained in:
rude
2009-07-26 15:46:49 +02:00
commit dcb3dfd83d
417 changed files with 124060 additions and 0 deletions
+48
View File
@@ -0,0 +1,48 @@
/**
* Copyright (c) 2006-2009 LOVE Development Team
*
* This software is provided 'as-is', without any express or implied
* warranty. In no event will the authors be held liable for any damages
* arising from the use of this software.
*
* Permission is granted to anyone to use this software for any purpose,
* including commercial applications, and to alter it and redistribute it
* freely, subject to the following restrictions:
*
* 1. The origin of this software must not be misrepresented; you must not
* claim that you wrote the original software. If you use this software
* in a product, an acknowledgment in the product documentation would be
* appreciated but is not required.
* 2. Altered source versions must be plainly marked as such, and must not be
* misrepresented as being the original software.
* 3. This notice may not be removed or altered from any source distribution.
**/
#ifndef LOVE_DATA_H
#define LOVE_DATA_H
// LOVE
#include "Object.h"
namespace love
{
class Data : public Object
{
public:
virtual ~Data() {};
/**
* Gets a pointer to the data.
**/
virtual void * getData() const = 0 ;
/**
* Gets the size of the data buffer.
**/
virtual int getSize() const = 0;
}; // Data
} // love
#endif // LOVE_DATA_H
+38
View File
@@ -0,0 +1,38 @@
/**
* Copyright (c) 2006-2009 LOVE Development Team
*
* This software is provided 'as-is', without any express or implied
* warranty. In no event will the authors be held liable for any damages
* arising from the use of this software.
*
* Permission is granted to anyone to use this software for any purpose,
* including commercial applications, and to alter it and redistribute it
* freely, subject to the following restrictions:
*
* 1. The origin of this software must not be misrepresented; you must not
* claim that you wrote the original software. If you use this software
* in a product, an acknowledgment in the product documentation would be
* appreciated but is not required.
* 2. Altered source versions must be plainly marked as such, and must not be
* misrepresented as being the original software.
* 3. This notice may not be removed or altered from any source distribution.
**/
#include "Exception.h"
namespace love
{
Exception::Exception(const char * fmt, ...)
{
va_list args;
va_start(args, fmt);
vsnprintf(buffer, BUFFER_SIZE, fmt, args);
va_end(args);
}
const char * Exception::what() const throw()
{
return (const char *)buffer;
}
}
+44
View File
@@ -0,0 +1,44 @@
/**
* Copyright (c) 2006-2009 LOVE Development Team
*
* This software is provided 'as-is', without any express or implied
* warranty. In no event will the authors be held liable for any damages
* arising from the use of this software.
*
* Permission is granted to anyone to use this software for any purpose,
* including commercial applications, and to alter it and redistribute it
* freely, subject to the following restrictions:
*
* 1. The origin of this software must not be misrepresented; you must not
* claim that you wrote the original software. If you use this software
* in a product, an acknowledgment in the product documentation would be
* appreciated but is not required.
* 2. Altered source versions must be plainly marked as such, and must not be
* misrepresented as being the original software.
* 3. This notice may not be removed or altered from any source distribution.
**/
#ifndef LOVE_EXCEPTION_H
#define LOVE_EXCEPTION_H
#include <exception>
#include <string>
#include <cstdarg>
#include <cstdio>
namespace love
{
class Exception : public std::exception
{
private:
static const int BUFFER_SIZE = 256;
char buffer[BUFFER_SIZE];
public:
Exception(const char * fmt, ...);
virtual const char * what() const throw();
};
}
#endif // LOVE_EXCEPTION_H
+176
View File
@@ -0,0 +1,176 @@
/**
* Copyright (c) 2006-2009 LOVE Development Team
*
* This software is provided 'as-is', without any express or implied
* warranty. In no event will the authors be held liable for any damages
* arising from the use of this software.
*
* Permission is granted to anyone to use this software for any purpose,
* including commercial applications, and to alter it and redistribute it
* freely, subject to the following restrictions:
*
* 1. The origin of this software must not be misrepresented; you must not
* claim that you wrote the original software. If you use this software
* in a product, an acknowledgment in the product documentation would be
* appreciated but is not required.
* 2. Altered source versions must be plainly marked as such, and must not be
* misrepresented as being the original software.
* 3. This notice may not be removed or altered from any source distribution.
**/
#include "Matrix.h"
// STD
#include <cstring>
#include <cmath>
// LOVE
#include "Vector.h"
namespace love
{
// | e0 e4 e8 e12 |
// | e1 e5 e9 e13 |
// | e2 e6 e10 e14 |
// | e3 e7 e11 e15 |
Matrix::Matrix()
{
setIdentity();
}
Matrix::~Matrix()
{
}
// | e0 e4 e8 e12 |
// | e1 e5 e9 e13 |
// | e2 e6 e10 e14 |
// | e3 e7 e11 e15 |
// | e0 e4 e8 e12 |
// | e1 e5 e9 e13 |
// | e2 e6 e10 e14 |
// | e3 e7 e11 e15 |
Matrix Matrix::operator * (const Matrix & m) const
{
Matrix t;
t.e[0] = (e[0]*m.e[0]) + (e[4]*m.e[1]) + (e[8]*m.e[2]) + (e[12]*m.e[3]);
t.e[4] = (e[0]*m.e[4]) + (e[4]*m.e[5]) + (e[8]*m.e[6]) + (e[12]*m.e[7]);
t.e[8] = (e[0]*m.e[8]) + (e[4]*m.e[9]) + (e[8]*m.e[10]) + (e[12]*m.e[11]);
t.e[12] = (e[0]*m.e[12]) + (e[4]*m.e[13]) + (e[8]*m.e[14]) + (e[12]*m.e[15]);
t.e[1] = (e[1]*m.e[0]) + (e[5]*m.e[1]) + (e[9]*m.e[2]) + (e[13]*m.e[3]);
t.e[5] = (e[1]*m.e[4]) + (e[5]*m.e[5]) + (e[9]*m.e[6]) + (e[13]*m.e[7]);
t.e[9] = (e[1]*m.e[8]) + (e[5]*m.e[9]) + (e[9]*m.e[10]) + (e[13]*m.e[11]);
t.e[13] = (e[1]*m.e[12]) + (e[5]*m.e[13]) + (e[9]*m.e[14]) + (e[13]*m.e[15]);
t.e[2] = (e[2]*m.e[0]) + (e[6]*m.e[1]) + (e[10]*m.e[2]) + (e[14]*m.e[3]);
t.e[6] = (e[2]*m.e[4]) + (e[6]*m.e[5]) + (e[10]*m.e[6]) + (e[14]*m.e[7]);
t.e[10] = (e[2]*m.e[8]) + (e[6]*m.e[9]) + (e[10]*m.e[10]) + (e[14]*m.e[11]);
t.e[14] = (e[2]*m.e[12]) + (e[6]*m.e[13]) + (e[10]*m.e[14]) + (e[14]*m.e[15]);
t.e[3] = (e[3]*m.e[0]) + (e[7]*m.e[1]) + (e[11]*m.e[2]) + (e[15]*m.e[3]);
t.e[7] = (e[3]*m.e[4]) + (e[7]*m.e[5]) + (e[11]*m.e[6]) + (e[15]*m.e[7]);
t.e[11] = (e[3]*m.e[8]) + (e[7]*m.e[9]) + (e[11]*m.e[10]) + (e[15]*m.e[11]);
t.e[15] = (e[3]*m.e[12]) + (e[7]*m.e[13]) + (e[11]*m.e[14]) + (e[15]*m.e[15]);
return t;
}
void Matrix::operator *= (const Matrix & m) const
{
Matrix t = (*this) * m;
memcpy((void*)this->e, (void*)t.e, sizeof(float)*16);
}
const float * Matrix::getElements() const
{
return e;
}
void Matrix::setIdentity()
{
memset(e, 0, sizeof(float)*16);
e[0] = e[5] = e[10] = e[15] = 1;
}
void Matrix::setTranslation(float x, float y)
{
setIdentity();
e[12] = x;
e[13] = y;
}
void Matrix::setRotation(float rad)
{
setIdentity();
float c = cos(rad), s = sin(rad);
e[0] = c; e[4] = -s;
e[1] = s; e[5] = c;
}
void Matrix::setScale(float sx, float sy)
{
setIdentity();
e[0] = sx;
e[5] = sy;
}
void Matrix::setTransformation(float x, float y, float angle, float sx, float sy, float ox, float oy)
{
// TODO: This works fine, but should consider speeding this up a little.
setIdentity();
translate(x, y);
rotate(angle);
scale(sx, sy);
translate(-ox, -oy);
}
void Matrix::translate(float x, float y)
{
Matrix t;
t.setTranslation(x, y);
this->operator *=(t);
}
void Matrix::rotate(float rad)
{
Matrix t;
t.setRotation(rad);
this->operator *=(t);
}
void Matrix::scale(float sx, float sy)
{
Matrix t;
t.setScale(sx, sy);
this->operator *=(t);
}
// | x |
// | y |
// | 0 |
// | 1 |
// | e0 e4 e8 e12 |
// | e1 e5 e9 e13 |
// | e2 e6 e10 e14 |
// | e3 e7 e11 e15 |
void Matrix::transform(vertex * dst, const vertex * src, int size)
{
for(int i = 0;i<size;i++)
{
// Store in temp variables in case src = dst
float x = (e[0]*src[i].x) + (e[4]*src[i].y) + (0) + (e[12]);
float y = (e[1]*src[i].x) + (e[5]*src[i].y) + (0) + (e[13]);
dst[i].x = x;
dst[i].y = y;
}
}
} // love
+96
View File
@@ -0,0 +1,96 @@
/**
* Copyright (c) 2006-2009 LOVE Development Team
*
* This software is provided 'as-is', without any express or implied
* warranty. In no event will the authors be held liable for any damages
* arising from the use of this software.
*
* Permission is granted to anyone to use this software for any purpose,
* including commercial applications, and to alter it and redistribute it
* freely, subject to the following restrictions:
*
* 1. The origin of this software must not be misrepresented; you must not
* claim that you wrote the original software. If you use this software
* in a product, an acknowledgment in the product documentation would be
* appreciated but is not required.
* 2. Altered source versions must be plainly marked as such, and must not be
* misrepresented as being the original software.
* 3. This notice may not be removed or altered from any source distribution.
**/
#ifndef LOVE_MATRIX_H
#define LOVE_MATRIX_H
// STD
#include <cmath>
// LOVE
#include "math.h"
namespace love
{
// Forward declarations.
class Vector;
class Matrix
{
friend class Vector;
public:
// | e0 e4 e8 e12 |
// | e1 e5 e9 e13 |
// | e2 e6 e10 e14 |
// | e3 e7 e11 e15 |
float e[16];
/**
* Creates a new identity matrix.
**/
Matrix();
/**
* Destructor.
**/
~Matrix();
Matrix operator * (const Matrix & m) const;
void operator *= (const Matrix & m) const;
const float * getElements() const;
void setIdentity();
void setTranslation(float x, float y);
void setRotation(float rad);
void setScale(float sx, float sy);
/**
* Creates a transformation with a certain position, orientation, scale
* and offset.
*
* @param x The translation along the x-axis.
* @param y The translation along the y-axis.
* @param angle The rotation (rad) around the center with offset (ox,oy).
* @param sx Scale along x-axis.
* @param sy Scale along y-axis.
* @param ox The offset for rotation along the x-axis.
* @param oy The offset for rotation along the y-axis.
**/
void setTransformation(float x, float y, float angle, float sx, float sy, float ox, float oy);
void translate(float x, float y);
void rotate(float rad);
void scale(float sx, float sy);
/**
* Transforms an array of vertices.
* @stride Stride in bytes.
**/
void transform(vertex * dst, const vertex * src, int size);
};
} //love
#endif// LOVE_MATRIX_H
+56
View File
@@ -0,0 +1,56 @@
/**
* Copyright (c) 2006-2009 LOVE Development Team
*
* This software is provided 'as-is', without any express or implied
* warranty. In no event will the authors be held liable for any damages
* arising from the use of this software.
*
* Permission is granted to anyone to use this software for any purpose,
* including commercial applications, and to alter it and redistribute it
* freely, subject to the following restrictions:
*
* 1. The origin of this software must not be misrepresented; you must not
* claim that you wrote the original software. If you use this software
* in a product, an acknowledgment in the product documentation would be
* appreciated but is not required.
* 2. Altered source versions must be plainly marked as such, and must not be
* misrepresented as being the original software.
* 3. This notice may not be removed or altered from any source distribution.
**/
#ifndef LOVE_MODULE_H
#define LOVE_MODULE_H
// LOVE
#include "runtime.h"
#include "Exception.h"
namespace love
{
/**
* Abstract superclass for all modules.
*
* @author Anders Ruud
**/
class Module
{
public:
/**
* Destructor.
**/
virtual ~Module(){};
/**
* Gets the name of the module. This is used in case of errors
* and other messages.
*
* @return The full name of the module, eg. love.graphics.opengl.
**/
virtual const char * getName() const = 0;
}; // Module
} // love
#endif // LOVE_MODULE_H
+53
View File
@@ -0,0 +1,53 @@
/**
* Copyright (c) 2006-2009 LOVE Development Team
*
* This software is provided 'as-is', without any express or implied
* warranty. In no event will the authors be held liable for any damages
* arising from the use of this software.
*
* Permission is granted to anyone to use this software for any purpose,
* including commercial applications, and to alter it and redistribute it
* freely, subject to the following restrictions:
*
* 1. The origin of this software must not be misrepresented; you must not
* claim that you wrote the original software. If you use this software
* in a product, an acknowledgment in the product documentation would be
* appreciated but is not required.
* 2. Altered source versions must be plainly marked as such, and must not be
* misrepresented as being the original software.
* 3. This notice may not be removed or altered from any source distribution.
**/
// LOVE
#include "Object.h"
namespace love
{
Object::Object()
: count(1)
{
}
Object::~Object()
{
// PURE VIRUTAL!
}
int Object::getReferenceCount() const
{
return count;
}
void Object::retain()
{
++count;
}
void Object::release()
{
if(--count <= 0)
delete this;
}
} // love
+78
View File
@@ -0,0 +1,78 @@
/**
* Copyright (c) 2006-2009 LOVE Development Team
*
* This software is provided 'as-is', without any express or implied
* warranty. In no event will the authors be held liable for any damages
* arising from the use of this software.
*
* Permission is granted to anyone to use this software for any purpose,
* including commercial applications, and to alter it and redistribute it
* freely, subject to the following restrictions:
*
* 1. The origin of this software must not be misrepresented; you must not
* claim that you wrote the original software. If you use this software
* in a product, an acknowledgment in the product documentation would be
* appreciated but is not required.
* 2. Altered source versions must be plainly marked as such, and must not be
* misrepresented as being the original software.
* 3. This notice may not be removed or altered from any source distribution.
**/
#ifndef LOVE_OBJECT_H
#define LOVE_OBJECT_H
namespace love
{
/**
* Superclass for all object that should be able to cross the Lua/C border
* (this pertains to most objects).
*
* This class is an alternative to using smart pointers; it contains retain/release
* methods, and will delete itself with the reference count hits zero. The wrapper
* code assumes that all userdata inherits from this class.
*
* @author Anders Ruud
**/
class Object
{
private:
// The reference count.
int count;
public:
/**
* Constructor. Sets reference count to one.
**/
Object();
/**
* Destructor.
**/
virtual ~Object() = 0;
/**
* Gets the reference count of this Object.
* @returns The reference count.
**/
int getReferenceCount() const;
/**
* Retains the Object, i.e. increases the
* reference count by one.
**/
void retain();
/**
* Releases one reference to the Object, i.e. decrements the
* reference count by one, and potentially deletes the Object
* if there are no more references.
**/
void release();
}; // Object
} // love
#endif // LOVE_OBJECT_H
+70
View File
@@ -0,0 +1,70 @@
/**
* Copyright (c) 2006-2009 LOVE Development Team
*
* This software is provided 'as-is', without any express or implied
* warranty. In no event will the authors be held liable for any damages
* arising from the use of this software.
*
* Permission is granted to anyone to use this software for any purpose,
* including commercial applications, and to alter it and redistribute it
* freely, subject to the following restrictions:
*
* 1. The origin of this software must not be misrepresented; you must not
* claim that you wrote the original software. If you use this software
* in a product, an acknowledgment in the product documentation would be
* appreciated but is not required.
* 2. Altered source versions must be plainly marked as such, and must not be
* misrepresented as being the original software.
* 3. This notice may not be removed or altered from any source distribution.
**/
#include "Reference.h"
namespace love
{
Reference::Reference()
: L(0), idx(LUA_REFNIL)
{
}
Reference::Reference(lua_State * L)
: L(0), idx(LUA_REFNIL)
{
ref(L);
}
Reference::~Reference()
{
unref();
}
void Reference::ref(lua_State * L)
{
unref(); // Just to be safe.
this->L = L;
idx = luaL_ref(L, LUA_GLOBALSINDEX);
}
void Reference::unref()
{
if(idx != LUA_REFNIL)
{
luaL_unref(L, LUA_GLOBALSINDEX, idx);
idx = LUA_REFNIL;
}
}
void Reference::push()
{
if(idx != LUA_REFNIL)
lua_rawgeti(L, LUA_GLOBALSINDEX, idx);
else
lua_pushnil(L);
}
lua_State * Reference::getL()
{
return L;
}
} // love
+87
View File
@@ -0,0 +1,87 @@
/**
* Copyright (c) 2006-2009 LOVE Development Team
*
* This software is provided 'as-is', without any express or implied
* warranty. In no event will the authors be held liable for any damages
* arising from the use of this software.
*
* Permission is granted to anyone to use this software for any purpose,
* including commercial applications, and to alter it and redistribute it
* freely, subject to the following restrictions:
*
* 1. The origin of this software must not be misrepresented; you must not
* claim that you wrote the original software. If you use this software
* in a product, an acknowledgment in the product documentation would be
* appreciated but is not required.
* 2. Altered source versions must be plainly marked as such, and must not be
* misrepresented as being the original software.
* 3. This notice may not be removed or altered from any source distribution.
**/
#ifndef LOVE_REFERENCE_H
#define LOVE_REFERENCE_H
// LOVE
#include "runtime.h"
namespace love
{
/**
* This class wraps the reference functionality built into
* Lua, which allows C++ code to refer to Lua variables.
**/
class Reference
{
private:
// The Lua state in which the reference resides.
lua_State * L;
// Index to the Lua reference.
int idx;
public:
/**
* Creates the reference object, but does not create
* the actual reference.
**/
Reference();
/**
* Creates the object and a reference to the value
* on the top of the stack.
**/
Reference(lua_State * L);
/**
* Deletes the reference, if any.
**/
virtual ~Reference();
/**
* Creates a reference to the value on the
* top of the stack.
**/
void ref(lua_State * L);
/**
* Unrefs the reference, if any.
**/
void unref();
/**
* Pushes the referred value onto the stack.
**/
void push();
/**
* Gets the Lua state associated with this
* reference.
**/
lua_State * getL();
};
} // love
#endif // LOVE_REFERENCE_H
+26
View File
@@ -0,0 +1,26 @@
/**
* Copyright (c) 2006-2009 LOVE Development Team
*
* This software is provided 'as-is', without any express or implied
* warranty. In no event will the authors be held liable for any damages
* arising from the use of this software.
*
* Permission is granted to anyone to use this software for any purpose,
* including commercial applications, and to alter it and redistribute it
* freely, subject to the following restrictions:
*
* 1. The origin of this software must not be misrepresented; you must not
* claim that you wrote the original software. If you use this software
* in a product, an acknowledgment in the product documentation would be
* appreciated but is not required.
* 2. Altered source versions must be plainly marked as such, and must not be
* misrepresented as being the original software.
* 3. This notice may not be removed or altered from any source distribution.
**/
#include "Vector.h"
namespace love
{
// Implementation in header.
}
+310
View File
@@ -0,0 +1,310 @@
/**
* Copyright (c) 2006-2009 LOVE Development Team
*
* This software is provided 'as-is', without any express or implied
* warranty. In no event will the authors be held liable for any damages
* arising from the use of this software.
*
* Permission is granted to anyone to use this software for any purpose,
* including commercial applications, and to alter it and redistribute it
* freely, subject to the following restrictions:
*
* 1. The origin of this software must not be misrepresented; you must not
* claim that you wrote the original software. If you use this software
* in a product, an acknowledgment in the product documentation would be
* appreciated but is not required.
* 2. Altered source versions must be plainly marked as such, and must not be
* misrepresented as being the original software.
* 3. This notice may not be removed or altered from any source distribution.
**/
#ifndef LOVE_VECTOR_H
#define LOVE_VECTOR_H
// STD
#include <cmath>
// LOVE
#include "Matrix.h"
namespace love
{
/**
* 2D Vector class.
*
* @author Anders Ruud
* @date 2006-05-13
**/
class Vector
{
public:
// The components.
float x, y;
/**
* Creates a new (1,1) Vector.
**/
Vector();
/**
* Creates a new Vector.
* @param x The x position/dimension.
* @param y The y position/dimension.
**/
Vector(float x, float y);
/**
* Gets the length of the Vector.
* @return The length of the Vector.
*
* This method requires sqrt() and should be used
* carefully.
**/
float getLength() const;
/**
* Normalizes the Vector.
* @return The old length of the Vector.
**/
float normalize();
/**
* Gets a normal to the Vector.
* @return A normal to the Vector.
**/
Vector getNormal() const;
/**
* Adds a Vector to this Vector.
* @param v The Vector we want to add to this Vector.
* @return The resulting Vector.
**/
Vector operator + (const Vector & v) const;
/**
* Substracts a Vector to this Vector.
* @param v The Vector we want to subtract to this Vector.
* @return The resulting Vector.
**/
Vector operator - (const Vector & v) const;
/**
* Resizes a Vector by a scalar.
* @param s The scalar with which to resize the Vector.
* @return The resulting Vector.
**/
Vector operator * (float s) const;
/**
* Resizes a Vector by a scalar.
* @param s The scalar with which to resize the Vector.
* @return The resulting Vector.
**/
Vector operator / (float s) const;
/**
* Reverses the Vector.
* @return The reversed Vector.
**/
Vector operator - () const;
/**
* Adds a Vector to this Vector, and also saves changes in the first Vector.
* @param v The Vector we want to add to this Vector.
**/
void operator += (const Vector & v);
/**
* Subtracts a Vector to this Vector, and also saves changes in the first Vector.
* @param v The Vector we want to subtract to this Vector.
**/
void operator -= (const Vector & v);
/**
* Resizes the Vector, and also saves changes in the first Vector.
* @param s The scalar by which we want to resize the Vector.
**/
void operator *= (float s);
/**
* Resizes the Vector, and also saves changes in the first Vector.
* @param s The scalar by which we want to resize the Vector.
**/
void operator /= (float s);
/**
* Calculates the dot product of two Vectors.
* @return The dot product of the two Vectors.
**/
float operator * (const Vector & v) const;
/**
* Calculates the cross product of two Vectors.
* @return The cross product of the two Vectors.
**/
float operator ^ (const Vector & v) const;
bool operator == (const Vector & v) const;
bool operator < (const Vector & v) const;
/**
* Gets the x value of the Vector.
* @return The x value of the Vector.
**/
float getX() const;
/**
* Gets the x value of the Vector.
* @return The x value of the Vector.
**/
float getY() const;
/**
* Sets the x value of the Vector.
* @param The x value of the Vector.
**/
void setX(float x);
/**
* Sets the x value of the Vector.
* @param The x value of the Vector.
**/
void setY(float y);
};
inline float Vector::getLength() const
{
return sqrt(x*x + y*y);
}
inline Vector Vector::getNormal() const
{
return Vector(-y, x);
}
inline float Vector::normalize()
{
float len = getLength();
if(len > 0)
(*this) /= len;
return len;
}
/**
* Inline methods must have body in header.
**/
inline Vector::Vector()
{
x = 1;
y = 1;
}
inline Vector::Vector(float x, float y)
{
this->x = x;
this->y = y;
}
inline Vector Vector::operator + (const Vector & v) const
{
return Vector(x + v.x, y + v.y);
}
inline Vector Vector::operator - (const Vector & v) const
{
return Vector(x - v.getX(), y - v.getY());
}
inline Vector Vector::operator * (float s) const
{
return Vector(x*s, y*s);
}
inline Vector Vector::operator / (float s) const
{
return Vector(x/s, y/s);
}
inline Vector Vector::operator - () const
{
return Vector(-x, -y);
}
inline void Vector::operator += (const Vector & v)
{
x += v.getX();
y += v.getY();
}
inline void Vector::operator -= (const Vector & v)
{
x -= v.getX();
y -= v.getY();
}
inline void Vector::operator *= (float s)
{
x *= s;
y *= s;
}
inline void Vector::operator /= (float s)
{
x /= s;
y /= s;
}
inline float Vector::operator * (const Vector & v) const
{
return x * v.getX() + y * v.getY();
}
inline float Vector::operator ^ (const Vector & v) const
{
return x * v.getY() - y * v.getX();
}
inline bool Vector::operator == (const Vector & v) const
{
return getLength() == v.getLength();
}
inline bool Vector::operator < (const Vector & v) const
{
return getLength() < v.getLength();
}
/**
* Accessor methods
**/
inline float Vector::getX() const
{
return x;
}
inline float Vector::getY() const
{
return y;
}
inline void Vector::setX(float x)
{
this->x = x;
}
inline void Vector::setY(float y)
{
this->y = y;
}
} //love
#endif// LOVE_VECTOR_H
+63
View File
@@ -0,0 +1,63 @@
/**
* Copyright (c) 2006-2009 LOVE Development Team
*
* This software is provided 'as-is', without any express or implied
* warranty. In no event will the authors be held liable for any damages
* arising from the use of this software.
*
* Permission is granted to anyone to use this software for any purpose,
* including commercial applications, and to alter it and redistribute it
* freely, subject to the following restrictions:
*
* 1. The origin of this software must not be misrepresented; you must not
* claim that you wrote the original software. If you use this software
* in a product, an acknowledgment in the product documentation would be
* appreciated but is not required.
* 2. Altered source versions must be plainly marked as such, and must not be
* misrepresented as being the original software.
* 3. This notice may not be removed or altered from any source distribution.
**/
#ifndef LOVE_CONFIG_H
#define LOVE_CONFIG_H
// STD
#include <string>
// Platform stuff.
#if defined(WIN32) || defined(_WIN32)
# define LOVE_WINDOWS 1
#endif
#if defined(linux) || defined(__linux) || defined(__linux__)
# define LOVE_LINUX 1
#endif
#if defined(__APPLE__)
# define LOVE_MACOSX 1
#endif
#if defined(macintosh)
# define LOVE_MACOS 1
#endif
// Build.
#define LOVE_BUILD_EXE 1
#define LOVE_BUILD_DLL 0
// Version stuff.
const int LOVE_VERSION = 060;
const int LOVE_VERSION_COMPATIBILITY[] = { 0 };
const std::string LOVE_VERSION_STR = "0.6.0";
const std::string LOVE_VERSION_CODENAME = "Jiggly Juice";
const std::string LOVE_VERSION_FULL_STR = std::string("LOVE ") + LOVE_VERSION_STR + std::string(" (") + LOVE_VERSION_CODENAME + std::string(")");
// DLL-stuff.
#ifdef LOVE_WINDOWS
# ifndef DECLSPEC
# define DECLSPEC __declspec(dllexport)
# endif
#else
# ifndef DECLSPEC
# define DECLSPEC
# endif
#endif
#endif // LOVE_CONFIG_H
+70
View File
@@ -0,0 +1,70 @@
/**
* Copyright (c) 2006-2009 LOVE Development Team
*
* This software is provided 'as-is', without any express or implied
* warranty. In no event will the authors be held liable for any damages
* arising from the use of this software.
*
* Permission is granted to anyone to use this software for any purpose,
* including commercial applications, and to alter it and redistribute it
* freely, subject to the following restrictions:
*
* 1. The origin of this software must not be misrepresented; you must not
* claim that you wrote the original software. If you use this software
* in a product, an acknowledgment in the product documentation would be
* appreciated but is not required.
* 2. Altered source versions must be plainly marked as such, and must not be
* misrepresented as being the original software.
* 3. This notice may not be removed or altered from any source distribution.
**/
#ifndef LOVE_MATH_H
#define LOVE_MATH_H
/* Definitions of useful mathematical constants
* M_E - e
* M_LOG2E - log2(e)
* M_LOG10E - log10(e)
* M_LN2 - ln(2)
* M_LN10 - ln(10)
* M_PI - pi
* M_PI_2 - pi/2
* M_PI_4 - pi/4
* M_1_PI - 1/pi
* M_2_PI - 2/pi
* M_2_SQRTPI - 2/sqrt(pi)
* M_SQRT2 - sqrt(2)
* M_SQRT1_2 - 1/sqrt(2)
*/
#define LOVE_M_E 2.71828182845904523536
#define LOVE_M_LOG2E 1.44269504088896340736
#define LOVE_M_LOG10E 0.434294481903251827651
#define LOVE_M_LN2 0.693147180559945309417
#define LOVE_M_LN10 2.30258509299404568402
#define LOVE_M_PI 3.14159265358979323846
#define LOVE_M_PI_2 1.57079632679489661923
#define LOVE_M_PI_4 0.785398163397448309616
#define LOVE_M_1_PI 0.318309886183790671538
#define LOVE_M_2_PI 0.636619772367581343076
#define LOVE_M_2_SQRTPI 1.12837916709551257390
#define LOVE_M_SQRT2 1.41421356237309504880
#define LOVE_M_SQRT1_2 0.707106781186547524401
#define LOVE_M_TORAD (float)(LOVE_M_PI/180.0)
#define LOVE_M_TODEG (float)(180.0/LOVE_M_PI)
#define LOVE_TORAD(x) (float)(x*LOVE_M_TORAD)
#define LOVE_TODEG(x) (float)(x*LOVE_M_TODEG)
namespace love
{
struct vertex
{
unsigned char r, g, b, a;
float x, y;
float s, t;
};
} // love
#endif // LOVE_MATH_H
+278
View File
@@ -0,0 +1,278 @@
/**
* Copyright (c) 2006-2009 LOVE Development Team
*
* This software is provided 'as-is', without any express or implied
* warranty. In no event will the authors be held liable for any damages
* arising from the use of this software.
*
* Permission is granted to anyone to use this software for any purpose,
* including commercial applications, and to alter it and redistribute it
* freely, subject to the following restrictions:
*
* 1. The origin of this software must not be misrepresented; you must not
* claim that you wrote the original software. If you use this software
* in a product, an acknowledgment in the product documentation would be
* appreciated but is not required.
* 2. Altered source versions must be plainly marked as such, and must not be
* misrepresented as being the original software.
* 3. This notice may not be removed or altered from any source distribution.
**/
#include "runtime.h"
// LOVE
#include "Module.h"
#include "Object.h"
// STD
#include <iostream>
namespace love
{
/**
* Called when an object is collected. The object is released
* once in this function, possibly deleting it.
**/
static int _wrap__gc(lua_State * L)
{
userdata * u = (userdata *)lua_touserdata(L, 1);
Object * t = (Object *)u->data;
t->release();
return 0;
}
/**
* Special garbage collector for Modules.
**/
static int _wrap__Module_gc(lua_State * L)
{
userdata * u = (userdata *)lua_touserdata(L, 1);
Module * t = (Module *)u->data;
delete t;
return 0;
}
void luax_printstack(lua_State * L)
{
for(int i = 1;i<=lua_gettop(L);i++)
{
std::cout << i << " - " << luaL_typename(L, i) << std::endl;
}
}
bool luax_toboolean(lua_State * L, int idx)
{
return (lua_toboolean(L, idx) == 1 ? true : false);
}
void luax_pushboolean(lua_State * L, bool b)
{
lua_pushboolean(L, b ? 1 : 0);
}
bool luax_optboolean(lua_State * L, int idx, bool b)
{
if(lua_isboolean(L, idx) == 1)
return (lua_toboolean(L, idx) == 1 ? true : false);
return b;
}
int luax_assert_argc(lua_State * L, int lower)
{
int argc = lua_gettop(L);
if( argc < lower )
return luaL_error(L, "Incorrect number of arguments. Got [%d], expected at least [%d]", argc, lower);
return 0;
}
int luax_assert_argc(lua_State * L, int lower, int upper)
{
int argc = lua_gettop(L);
if( argc < lower || argc > upper)
return luaL_error(L, "Incorrect number of arguments. Got [%d], expected [%d-%d]", argc, lower, upper);
return 0;
}
int luax_assert_function(lua_State * L, int n)
{
if(!lua_isfunction(L, n))
return luaL_error(L, "Argument must be of type \"function\".");
return 0;
}
int luax_register_gc(lua_State * L, const char * mname, Module * m)
{
lua_getglobal(L, "love");
lua_getfield(L, -1, "__fin");
userdata * u = (userdata *)lua_newuserdata(L, sizeof(userdata));
u->own = true;
u->data = m;
luaL_newmetatable(L, mname);
lua_pushcfunction(L, _wrap__Module_gc);
lua_setfield(L, -2, "__gc");
lua_setmetatable(L, -2);
lua_setfield(L, -2, mname);
lua_pop(L, 2); // __fin, love
return 0;
}
int luax_register_info(lua_State * L, const char * name,
const char * provides, const char * desc, const char * author,
lua_CFunction open)
{
lua_getglobal(L, "love");
lua_getfield(L, -1, "__mod");
lua_getfield(L, -1, provides);
// Make sure it exists.
if(lua_isnil(L, -1))
{
lua_pop(L, 1);
lua_newtable(L);
lua_setfield(L, -2, provides);
lua_getfield(L, -1, provides);
}
lua_newtable(L);
lua_pushstring(L, desc);
lua_setfield(L, -2, "description");
lua_pushstring(L, author);
lua_setfield(L, -2, "author");
lua_pushcfunction(L, open);
lua_setfield(L, -2, "open");
lua_setfield(L, -2, name);
// Pop "provides", __mod, love
lua_pop(L, 3);
return 0;
}
int luax_register_module(lua_State * L, const luaL_Reg * fn, const lua_CFunction * types)
{
// Create new table for module.
lua_newtable(L);
// Register all the functions.
luaL_register(L, 0, fn);
// Register types.
if(types != 0)
for(const lua_CFunction * t = types; *t != 0; t++)
(*t)(L);
return 1;
}
int luax_preload(lua_State * L, lua_CFunction f, const char * name)
{
lua_getglobal(L, "package");
lua_getfield(L, -1, "preload");
lua_pushcfunction(L, f);
lua_setfield(L, -2, name);
lua_pop(L, 2);
return 0;
}
int luax_register_type(lua_State * L, const char * tname, const luaL_Reg * fn)
{
luaL_newmetatable(L, tname);
// m.__index = m
lua_pushvalue(L, -1);
lua_setfield(L, -2, "__index");
// setup gc
lua_pushcfunction(L, _wrap__gc);
lua_setfield(L, -2, "__gc");
luaL_register(L, 0, fn);
lua_pop(L, 1); // Pops metatable.
return 0;
}
int luax_register_searcher(lua_State * L, lua_CFunction f)
{
// Add the package loader to the package.loaders table.
lua_getglobal(L, "package");
if(lua_isnil(L, -1))
return luaL_error(L, "Can't register searcher: package table does not exist.");
lua_getfield(L, -1, "loaders");
if(lua_isnil(L, -1))
return luaL_error(L, "Can't register searcher: package.loaders table does not exist.");
int len = lua_objlen(L, -1);
lua_pushinteger(L, len+1);
lua_pushcfunction(L, f);
lua_settable(L, -3);
lua_pop(L, 2);
return 0;
}
void luax_newtype(lua_State * L, const char * tname, bits flags, void * data, bool own)
{
userdata * u = (userdata *)lua_newuserdata(L, sizeof(userdata));
u->data = data;
u->flags = flags;
u->own = own;
luaL_newmetatable(L, tname);
lua_setmetatable(L, -2);
}
bool luax_istype(lua_State * L, int idx, love::bits type)
{
if(lua_isuserdata(L, idx) == 0)
return false;
userdata * u = (userdata *)lua_touserdata(L, idx);
return ((u->flags & type) == type);
}
int luax_getfunction(lua_State * L, const char * mod, const char * fn)
{
lua_getglobal(L, "love");
if(lua_isnil(L, -1)) return luaL_error(L, "Could not find global love!");
lua_getfield(L, -1, mod);
if(lua_isnil(L, -1)) return luaL_error(L, "Could not find love.%s!", mod);
lua_getfield(L, -1, fn);
if(lua_isnil(L, -1)) return luaL_error(L, "Could not find love.%s.%s!", mod, fn);
lua_remove(L, -2); // remove mod
lua_remove(L, -2); // remove fn
return 0;
}
int luax_convobj(lua_State * L, int idx, const char * mod, const char * fn)
{
// Convert string to a file.
luax_getfunction(L, mod, fn);
lua_pushvalue(L, idx); // The initial argument.
lua_call(L, 1, 1); // Call the function, one arg, one return value.
lua_replace(L, idx); // Replace the initial argument with the new object.
return 0;
}
int luax_strtofile(lua_State * L, int idx)
{
return luax_convobj(L, idx, "filesystem", "newFile");
}
int luax_filetodata(lua_State * L, int idx)
{
return luax_convobj(L, idx, "filesystem", "read");
}
} // love
+107
View File
@@ -0,0 +1,107 @@
/**
* Copyright (c) 2006-2009 LOVE Development Team
*
* This software is provided 'as-is', without any express or implied
* warranty. In no event will the authors be held liable for any damages
* arising from the use of this software.
*
* Permission is granted to anyone to use this software for any purpose,
* including commercial applications, and to alter it and redistribute it
* freely, subject to the following restrictions:
*
* 1. The origin of this software must not be misrepresented; you must not
* claim that you wrote the original software. If you use this software
* in a product, an acknowledgment in the product documentation would be
* appreciated but is not required.
* 2. Altered source versions must be plainly marked as such, and must not be
* misrepresented as being the original software.
* 3. This notice may not be removed or altered from any source distribution.
**/
#ifndef LOVE_RUNTIME_H
#define LOVE_RUNTIME_H
#include "types.h"
#include "Module.h"
// Lua
extern "C" {
#include <lua.h>
#include <lualib.h>
#include <lauxlib.h>
}
namespace love
{
// Type used for storing constants
// in an array.
typedef struct lua_constant_entry
{
const char * name;
int value;
} lua_constant_entry;
class Module;
void luax_printstack(lua_State * L);
bool luax_toboolean(lua_State * L, int idx);
void luax_pushboolean(lua_State * L, bool b);
bool luax_optboolean(lua_State * L, int idx, bool b);
int luax_assert_argc(lua_State * L, int lower);
int luax_assert_argc(lua_State * L, int lower, int upper);
int luax_assert_function(lua_State * L, int n);
int luax_register_gc(lua_State * L, const char * mname, Module * module);
int luax_register_info(lua_State * L, const char * name,
const char * provides, const char * desc, const char * author,
lua_CFunction open);
int luax_register_module(lua_State * L, const luaL_Reg * fn, const lua_CFunction * types);
int luax_preload(lua_State * L, lua_CFunction f, const char * name);
int luax_register_type(lua_State * L, const char * tname, const luaL_Reg * fn);
int luax_register_searcher(lua_State * L, lua_CFunction f);
void luax_newtype(lua_State * L, const char * tname, bits flags, void * data, bool own = true);
bool luax_istype(lua_State * L, int idx, love::bits type);
// Gets a function love.mod.fn.
int luax_getfunction(lua_State * L, const char * mod, const char * fn);
/**
* Converts an object into another object
* by the specified function mod.fn. The function must accept
* a single file as a parameter, and return one value.
*
* Note that the initial object is converted, i.e. replaced.
**/
int luax_convobj(lua_State * L, int idx, const char * mod, const char * fn);
/**
* Converts a string into a File object. Note that the
* string is replaced by the new File object at the
* specified index, and NOT pushed onto the stack.
**/
int luax_strtofile(lua_State * L, int idx);
template <typename T>
T * luax_checktype(lua_State * L, int idx, const char * tname, love::bits type)
{
if(lua_isuserdata(L, idx) == 0)
luaL_error(L, "Incorrect parameter type: expected userdata.");
userdata * u = (userdata *)lua_touserdata(L, idx);
if((u->flags & type) != type)
luaL_error(L, "Incorrect parameter type: expected %s", tname);
return (T *)u->data;
}
} // love
#endif // LOVE_RUNTIME_H
+158
View File
@@ -0,0 +1,158 @@
/**
* Copyright (c) 2006-2009 LOVE Development Team
*
* This software is provided 'as-is', without any express or implied
* warranty. In no event will the authors be held liable for any damages
* arising from the use of this software.
*
* Permission is granted to anyone to use this software for any purpose,
* including commercial applications, and to alter it and redistribute it
* freely, subject to the following restrictions:
*
* 1. The origin of this software must not be misrepresented; you must not
* claim that you wrote the original software. If you use this software
* in a product, an acknowledgment in the product documentation would be
* appreciated but is not required.
* 2. Altered source versions must be plainly marked as such, and must not be
* misrepresented as being the original software.
* 3. This notice may not be removed or altered from any source distribution.
**/
#ifndef LOVE_TYPES_H
#define LOVE_TYPES_H
// STD
#include <bitset>
namespace love
{
enum
{
// Cross-module types.
LOVE_OBJECT_ID = 0,
LOVE_DATA_ID,
// Filesystem.
LOVE_FILESYSTEM_FILE_ID,
LOVE_FILESYSTEM_FILE_DATA_ID,
// Graphics
LOVE_GRAPHICS_DRAWABLE_ID,
LOVE_GRAPHICS_IMAGE_ID,
LOVE_GRAPHICS_FRAME_ID,
LOVE_GRAPHICS_ANIMATION_ID,
LOVE_GRAPHICS_COLOR_ID,
LOVE_GRAPHICS_FONT_ID,
LOVE_GRAPHICS_PARTICLE_SYSTEM_ID,
LOVE_GRAPHICS_SPRITE_BATCH_ID,
LOVE_GRAPHICS_VERTEX_BUFFER_ID,
// Image
LOVE_IMAGE_IMAGE_DATA_ID,
// Audio
LOVE_AUDIO_AUDIBLE_ID,
LOVE_AUDIO_SOUND_ID,
LOVE_AUDIO_MUSIC_ID,
LOVE_AUDIO_SOURCE_ID,
// Sound
LOVE_SOUND_SOUND_DATA_ID,
LOVE_SOUND_DECODER_ID,
// Physics
LOVE_PHYSICS_WORLD_ID,
LOVE_PHYSICS_CONTACT_ID,
LOVE_PHYSICS_BODY_ID,
LOVE_PHYSICS_SHAPE_ID,
LOVE_PHYSICS_CIRCLE_SHAPE_ID,
LOVE_PHYSICS_POLYGON_SHAPE_ID,
LOVE_PHYSICS_JOINT_ID,
LOVE_PHYSICS_MOUSE_JOINT_ID,
LOVE_PHYSICS_DISTANCE_JOINT_ID,
LOVE_PHYSICS_PRISMATIC_JOINT_ID,
LOVE_PHYSICS_REVOLUTE_JOINT_ID,
LOVE_PHYSICS_PULLEY_JOINT_ID,
LOVE_PHYSICS_GEAR_JOINT_ID,
// Modules.
LOVE_PHYSFS_ID,
LOVE_OPENGL_ID,
LOVE_DIRECT3D_ID,
LOVE_BOX2D_ID,
LOVE_DEVIL_ID,
LOVE_SDLSOUND_ID,
LOVE_OPENAL_ID,
// Count the number of bits needed.
LOVE_BIT_SIZE
};
typedef std::bitset<LOVE_BIT_SIZE> bits;
const bits LOVE_OBJECT_BITS = bits(1) << LOVE_OBJECT_ID;
const bits LOVE_DATA_BITS = (bits(1) << LOVE_DATA_ID) | LOVE_OBJECT_BITS;
// Filesystem.
const bits LOVE_FILESYSTEM_FILE_BITS = (bits(1) << LOVE_FILESYSTEM_FILE_ID) | LOVE_OBJECT_BITS;
const bits LOVE_FILESYSTEM_FILE_DATA_BITS = (bits(1) << LOVE_FILESYSTEM_FILE_DATA_ID) | LOVE_DATA_BITS;
// Graphics.
const bits LOVE_GRAPHICS_DRAWABLE_BITS = (bits(1) << LOVE_GRAPHICS_DRAWABLE_ID) | LOVE_OBJECT_BITS;
const bits LOVE_GRAPHICS_IMAGE_BITS = (bits(1) << LOVE_GRAPHICS_IMAGE_ID) | LOVE_GRAPHICS_DRAWABLE_BITS;
const bits LOVE_GRAPHICS_FRAME_BITS = (bits(1) << LOVE_GRAPHICS_FRAME_ID);
const bits LOVE_GRAPHICS_ANIMATION_BITS = (bits(1) << LOVE_GRAPHICS_ANIMATION_ID) | LOVE_GRAPHICS_DRAWABLE_BITS;
const bits LOVE_GRAPHICS_COLOR_BITS = (bits(1) << LOVE_GRAPHICS_COLOR_ID) | LOVE_OBJECT_BITS;
const bits LOVE_GRAPHICS_FONT_BITS = (bits(1) << LOVE_GRAPHICS_FONT_ID) | LOVE_OBJECT_BITS;
const bits LOVE_GRAPHICS_PARTICLE_SYSTEM_BITS = (bits(1) << LOVE_GRAPHICS_PARTICLE_SYSTEM_ID) | LOVE_GRAPHICS_DRAWABLE_BITS;
const bits LOVE_GRAPHICS_SPRITE_BATCH_BITS = (bits(1) << LOVE_GRAPHICS_SPRITE_BATCH_ID) | LOVE_GRAPHICS_DRAWABLE_BITS;
const bits LOVE_GRAPHICS_VERTEX_BUFFER_BITS = (bits(1) << LOVE_GRAPHICS_VERTEX_BUFFER_ID) | LOVE_GRAPHICS_DRAWABLE_BITS;
// Image.
const bits LOVE_IMAGE_IMAGE_DATA_BITS = (bits(1) << LOVE_IMAGE_IMAGE_DATA_ID) | LOVE_DATA_BITS;
// Audio.
const bits LOVE_AUDIO_AUDIBLE_BITS = (bits(1) << LOVE_AUDIO_AUDIBLE_ID) | LOVE_OBJECT_BITS;
const bits LOVE_AUDIO_SOUND_BITS = (bits(1) << LOVE_AUDIO_SOUND_ID) | LOVE_AUDIO_AUDIBLE_BITS;
const bits LOVE_AUDIO_MUSIC_BITS = (bits(1) << LOVE_AUDIO_MUSIC_ID) | LOVE_AUDIO_AUDIBLE_BITS;
const bits LOVE_AUDIO_SOURCE_BITS = (bits(1) << LOVE_AUDIO_SOURCE_ID) | LOVE_OBJECT_BITS;
// Sound.
const bits LOVE_SOUND_SOUND_DATA_BITS = (bits(1) << LOVE_SOUND_SOUND_DATA_ID) | LOVE_DATA_BITS;
const bits LOVE_SOUND_DECODER_BITS = bits(1) << LOVE_SOUND_DECODER_ID;
// Physics.
const bits LOVE_PHYSICS_WORLD_BITS = (bits(1) << LOVE_PHYSICS_WORLD_ID) | LOVE_OBJECT_BITS;
const bits LOVE_PHYSICS_CONTACT_BITS = (bits(1) << LOVE_PHYSICS_CONTACT_ID) | LOVE_OBJECT_BITS;
const bits LOVE_PHYSICS_BODY_BITS = (bits(1) << LOVE_PHYSICS_BODY_ID) | LOVE_OBJECT_BITS;
const bits LOVE_PHYSICS_SHAPE_BITS = (bits(1) << LOVE_PHYSICS_SHAPE_ID) | LOVE_OBJECT_BITS;
const bits LOVE_PHYSICS_CIRCLE_SHAPE_BITS = (bits(1) << LOVE_PHYSICS_CIRCLE_SHAPE_ID) | LOVE_PHYSICS_SHAPE_BITS;
const bits LOVE_PHYSICS_POLYGON_SHAPE_BITS = (bits(1) << LOVE_PHYSICS_POLYGON_SHAPE_ID) | LOVE_PHYSICS_SHAPE_BITS;
const bits LOVE_PHYSICS_JOINT_BITS = (bits(1) << LOVE_PHYSICS_JOINT_ID) | LOVE_OBJECT_BITS;
const bits LOVE_PHYSICS_MOUSE_JOINT_BITS = (bits(1) << LOVE_PHYSICS_MOUSE_JOINT_ID) | LOVE_PHYSICS_JOINT_BITS;
const bits LOVE_PHYSICS_DISTANCE_JOINT_BITS = (bits(1) << LOVE_PHYSICS_DISTANCE_JOINT_ID) | LOVE_PHYSICS_JOINT_BITS;
const bits LOVE_PHYSICS_PRISMATIC_JOINT_BITS = (bits(1) << LOVE_PHYSICS_PRISMATIC_JOINT_ID) | LOVE_PHYSICS_JOINT_BITS;
const bits LOVE_PHYSICS_REVOLUTE_JOINT_BITS = (bits(1) << LOVE_PHYSICS_REVOLUTE_JOINT_ID) | LOVE_PHYSICS_JOINT_BITS;
const bits LOVE_PHYSICS_PULLEY_JOINT_BITS = (bits(1) << LOVE_PHYSICS_PULLEY_JOINT_ID) | LOVE_PHYSICS_JOINT_BITS;
const bits LOVE_PHYSICS_GEAR_JOINT_BITS = (bits(1) << LOVE_PHYSICS_GEAR_JOINT_ID) | LOVE_PHYSICS_JOINT_BITS;
// Modules.
const bits LOVE_PHYSFS_BITS = bits(1) << LOVE_PHYSFS_ID;
const bits LOVE_OPENGL_BITS = bits(1) << LOVE_OPENGL_ID;
const bits LOVE_DIRECT3D_BITS = bits(1) << LOVE_DIRECT3D_ID;
const bits LOVE_BOX2D_BITS = bits(1) << LOVE_BOX2D_ID;
const bits LOVE_DEVIL_BITS = bits(1) << LOVE_DEVIL_ID;
const bits LOVE_SDLSOUND_BITS = bits(1) << LOVE_SDLSOUND_ID;
const bits LOVE_OPENAL_BITS = bits(1) << LOVE_OPENAL_ID;
// Wraps all userdata pointers.
struct userdata
{
bits flags; // Holds type information.
void * data;
bool own; // True if Lua should delete on GC.
};
} // love
#endif // LOVE_TYPES_H
+56
View File
@@ -0,0 +1,56 @@
/**
* Copyright (c) 2006-2009 LOVE Development Team
*
* This software is provided 'as-is', without any express or implied
* warranty. In no event will the authors be held liable for any damages
* arising from the use of this software.
*
* Permission is granted to anyone to use this software for any purpose,
* including commercial applications, and to alter it and redistribute it
* freely, subject to the following restrictions:
*
* 1. The origin of this software must not be misrepresented; you must not
* claim that you wrote the original software. If you use this software
* in a product, an acknowledgment in the product documentation would be
* appreciated but is not required.
* 2. Altered source versions must be plainly marked as such, and must not be
* misrepresented as being the original software.
* 3. This notice may not be removed or altered from any source distribution.
**/
#include "wrap_Data.h"
namespace love
{
Data * luax_checkdata(lua_State * L, int idx)
{
return luax_checktype<Data>(L, idx, "Data", LOVE_DATA_BITS);
}
int _wrap_Data_getPointer(lua_State * L)
{
Data * t = luax_checkdata(L, 1);
lua_pushlightuserdata(L, t->getData());
return 1;
}
int _wrap_Data_getSize(lua_State * L)
{
Data * t = luax_checkdata(L, 1);
lua_pushinteger(L, t->getSize());
return 1;
}
const luaL_Reg wrap_Data_functions[] = {
{ "getPointer", _wrap_Data_getPointer },
{ "getSize", _wrap_Data_getSize },
{ 0, 0 }
};
int wrap_Data_open(lua_State * L)
{
luax_register_type(L, "Data", wrap_Data_functions);
return 0;
}
} // love
+37
View File
@@ -0,0 +1,37 @@
/**
* Copyright (c) 2006-2009 LOVE Development Team
*
* This software is provided 'as-is', without any express or implied
* warranty. In no event will the authors be held liable for any damages
* arising from the use of this software.
*
* Permission is granted to anyone to use this software for any purpose,
* including commercial applications, and to alter it and redistribute it
* freely, subject to the following restrictions:
*
* 1. The origin of this software must not be misrepresented; you must not
* claim that you wrote the original software. If you use this software
* in a product, an acknowledgment in the product documentation would be
* appreciated but is not required.
* 2. Altered source versions must be plainly marked as such, and must not be
* misrepresented as being the original software.
* 3. This notice may not be removed or altered from any source distribution.
**/
#ifndef LOVE_WRAP_DATA_H
#define LOVE_WRAP_DATA_H
// LOVE
#include "runtime.h"
#include "Data.h"
namespace love
{
Data * luax_checkdata(lua_State * L, int idx);
int _wrap_Data_getPointer(lua_State * L);
int _wrap_Data_getSize(lua_State * L);
int wrap_Data_open(lua_State * L);
} // love
#endif // LOVE_WRAP_DATA_H
+50
View File
@@ -0,0 +1,50 @@
/**
* Copyright (c) 2006-2009 LOVE Development Team
*
* This software is provided 'as-is', without any express or implied
* warranty. In no event will the authors be held liable for any damages
* arising from the use of this software.
*
* Permission is granted to anyone to use this software for any purpose,
* including commercial applications, and to alter it and redistribute it
* freely, subject to the following restrictions:
*
* 1. The origin of this software must not be misrepresented; you must not
* claim that you wrote the original software. If you use this software
* in a product, an acknowledgment in the product documentation would be
* appreciated but is not required.
* 2. Altered source versions must be plainly marked as such, and must not be
* misrepresented as being the original software.
* 3. This notice may not be removed or altered from any source distribution.
**/
#include "lanes.h"
// Lanes open function.
extern "C"
{
int luaopen_lanes( lua_State *L );
}
namespace love
{
namespace lanes
{
// Opens the lanes.lua file.
static int open_lanes(lua_State * L)
{
#include "lanes/lanes.lua.h"
lua_getglobal(L, "lanes");
return 1;
}
int open(lua_State * L)
{
luax_preload(L, open_lanes, "lanes");
luax_preload(L, luaopen_lanes, "lua51-lanes");
return 0;
}
} // lanes
} // love
+36
View File
@@ -0,0 +1,36 @@
/**
* Copyright (c) 2006-2009 LOVE Development Team
*
* This software is provided 'as-is', without any express or implied
* warranty. In no event will the authors be held liable for any damages
* arising from the use of this software.
*
* Permission is granted to anyone to use this software for any purpose,
* including commercial applications, and to alter it and redistribute it
* freely, subject to the following restrictions:
*
* 1. The origin of this software must not be misrepresented; you must not
* claim that you wrote the original software. If you use this software
* in a product, an acknowledgment in the product documentation would be
* appreciated but is not required.
* 2. Altered source versions must be plainly marked as such, and must not be
* misrepresented as being the original software.
* 3. This notice may not be removed or altered from any source distribution.
**/
#ifndef LOVE_LANES_LANES_H
#define LOVE_LANES_LANES_H
// LOVE
#include <common/runtime.h>
namespace love
{
namespace lanes
{
int open(lua_State * L);
} // lanes
} // love
#endif // LOVE_LANES_LANES_H
+214
View File
@@ -0,0 +1,214 @@
/* bin2c.lua generated code -- DO NOT EDIT
*
* To use from C source:
* char my_chunk[]=
* #include "my.lch"
*/
{
27, 76,117, 97, 81, 0, 1, 4, 4, 4, 8, 0, 12, 0, 0, 0, 64,107,101,101,
112,101,114, 46,108,117, 97, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 9,
45, 0, 0, 0, 5, 0, 0, 0, 69, 64, 0, 0, 28, 64, 0, 1, 5, 0, 0, 0,
69,128, 0, 0, 70,192,192, 0, 28,128, 0, 1, 69, 0, 0, 0,133,128, 0, 0,
134, 0, 65, 1, 92,128, 0, 1,164, 0, 0, 0, 0, 0,128, 0,202, 0, 0, 0,
10, 1, 0, 0, 74, 1, 0, 0,164, 65, 0, 0, 0, 0,128, 1, 0, 0, 0, 2,
0, 0,128, 2,228,129, 0, 0, 0, 0, 0, 3, 0, 0, 0, 1, 36,194, 0, 0,
0, 0, 0, 3, 7, 66, 1, 0, 36, 2, 1, 0, 0, 0, 0, 3, 0, 0, 0, 0,
7,130, 1, 0, 36, 66, 1, 0, 0, 0, 0, 3, 7,194, 1, 0, 36,130, 1, 0,
0, 0, 0, 3, 7, 2, 2, 0, 36,194, 1, 0, 0, 0, 0, 3, 7, 66, 2, 0,
36, 2, 2, 0, 0, 0,128, 1, 0, 0, 0, 2, 0, 0,128, 2, 7,130, 2, 0,
30, 0,128, 0, 11, 0, 0, 0, 4, 7, 0, 0, 0, 97,115,115,101,114,116, 0,
4, 13, 0, 0, 0,110,105,108, 95,115,101,110,116,105,110,101,108, 0, 4, 6,
0, 0, 0,116, 97, 98,108,101, 0, 4, 7, 0, 0, 0,114,101,109,111,118,101,
0, 4, 7, 0, 0, 0, 99,111,110, 99, 97,116, 0, 4, 5, 0, 0, 0,115,101,
110,100, 0, 4, 8, 0, 0, 0,114,101, 99,101,105,118,101, 0, 4, 6, 0, 0,
0,108,105,109,105,116, 0, 4, 4, 0, 0, 0,115,101,116, 0, 4, 4, 0, 0,
0,103,101,116, 0, 4, 6, 0, 0, 0, 99,108,101, 97,114, 0, 9, 0, 0, 0,
0, 0, 0, 0, 46, 0, 0, 0, 50, 0, 0, 0, 1, 0, 3, 6, 16, 0, 0, 0,
69, 0, 0, 0, 90, 0, 0, 0, 22,192, 2,128, 69, 0, 0, 0, 70, 64,192, 0,
75,128,192, 0,196, 0, 0, 0, 10, 1, 0, 0,101, 1, 0, 0, 34, 65, 0, 0,
65,193, 0, 0,220,128,128, 1, 1, 1, 1, 0,213, 0,129, 1, 92, 64,128, 1,
30, 0,128, 0, 5, 0, 0, 0, 4, 3, 0, 0, 0,105,111, 0, 4, 7, 0, 0,
0,115,116,100,101,114,114, 0, 4, 6, 0, 0, 0,119,114,105,116,101, 0, 4,
2, 0, 0, 0, 9, 0, 4, 2, 0, 0, 0, 10, 0, 0, 0, 0, 0, 16, 0, 0,
0, 47, 0, 0, 0, 47, 0, 0, 0, 47, 0, 0, 0, 48, 0, 0, 0, 48, 0, 0,
0, 48, 0, 0, 0, 48, 0, 0, 0, 48, 0, 0, 0, 48, 0, 0, 0, 48, 0, 0,
0, 48, 0, 0, 0, 48, 0, 0, 0, 48, 0, 0, 0, 48, 0, 0, 0, 48, 0, 0,
0, 50, 0, 0, 0, 1, 0, 0, 0, 4, 0, 0, 0, 97,114,103, 0, 0, 0, 0,
0, 15, 0, 0, 0, 1, 0, 0, 0, 13, 0, 0, 0,116, 97, 98,108,101, 95, 99,
111,110, 99, 97,116, 0, 0, 0, 0, 0, 84, 0, 0, 0, 93, 0, 0, 0, 3, 1,
0, 4, 21, 0, 0, 0, 68, 0, 0, 0, 70, 0,128, 0, 90, 64, 0, 0, 22, 0,
2,128, 68, 0, 0, 0,138, 0, 0, 0, 73,128, 0, 0, 68, 0,128, 0,138, 0,
0, 0, 73,128, 0, 0, 68, 0, 0, 1,138, 0, 0, 0, 73,128, 0, 0, 68, 0,
0, 0, 70, 0,128, 0,132, 0,128, 0,134, 0, 0, 1,196, 0, 0, 1,198, 0,
128, 1, 94, 0, 0, 2, 30, 0,128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 21, 0,
0, 0, 87, 0, 0, 0, 87, 0, 0, 0, 87, 0, 0, 0, 87, 0, 0, 0, 88, 0,
0, 0, 88, 0, 0, 0, 88, 0, 0, 0, 89, 0, 0, 0, 89, 0, 0, 0, 89, 0,
0, 0, 90, 0, 0, 0, 90, 0, 0, 0, 90, 0, 0, 0, 92, 0, 0, 0, 92, 0,
0, 0, 92, 0, 0, 0, 92, 0, 0, 0, 92, 0, 0, 0, 92, 0, 0, 0, 92, 0,
0, 0, 93, 0, 0, 0, 1, 0, 0, 0, 3, 0, 0, 0,117,100, 0, 0, 0, 0,
0, 20, 0, 0, 0, 3, 0, 0, 0, 6, 0, 0, 0, 95,100, 97,116, 97, 0, 10,
0, 0, 0, 95,105,110, 99,111,109,105,110,103, 0, 8, 0, 0, 0, 95,108,105,
109,105,116,115, 0, 0, 0, 0, 0, 96, 0, 0, 0,106, 0, 0, 0, 2, 3, 0,
16, 40, 0, 0, 0,197, 0, 0, 0, 27, 1, 0, 0, 22,128, 0,128, 27, 1,128,
0, 22, 0, 0,128, 0, 1, 0, 1,220, 64, 0, 1,196, 0, 0, 0, 0, 1,128,
0,220, 0, 1, 1,133, 65, 0, 0,198,129,128, 1,156,129, 0, 1,197,129, 0,
0, 6,130, 0, 2, 26, 66, 0, 0, 22, 0, 0,128, 10, 2, 0, 0,220, 1, 1,
1, 22, 64, 1,128, 0, 3, 0, 3, 65,195, 0, 0,133, 67, 0, 0,192, 3,128,
5,156,131, 0, 1,149,129, 3, 6,225,129, 0, 0, 22,192,253,127,196, 1,128,
0, 1, 2, 1, 0, 64, 2, 0, 0,129, 66, 1, 0,197, 66, 0, 0, 0, 3, 0,
1,220,130, 0, 1, 1,131, 1, 0, 21, 2, 3, 4, 64, 2, 0, 3,220, 65,128,
1, 30, 0,128, 0, 7, 0, 0, 0, 4, 7, 0, 0, 0, 97,115,115,101,114,116,
0, 4, 9, 0, 0, 0,116,111,115,116,114,105,110,103, 0, 4, 7, 0, 0, 0,
105,112, 97,105,114,115, 0, 4, 3, 0, 0, 0, 44, 32, 0, 4, 5, 0, 0, 0,
42, 42, 42, 32, 0, 4, 3, 0, 0, 0, 32, 40, 0, 4, 4, 0, 0, 0, 41, 58,
32, 0, 0, 0, 0, 0, 40, 0, 0, 0, 97, 0, 0, 0, 97, 0, 0, 0, 97, 0,
0, 0, 97, 0, 0, 0, 97, 0, 0, 0, 97, 0, 0, 0, 97, 0, 0, 0, 99, 0,
0, 0, 99, 0, 0, 0, 99, 0, 0, 0,101, 0, 0, 0,101, 0, 0, 0,101, 0,
0, 0,102, 0, 0, 0,102, 0, 0, 0,102, 0, 0, 0,102, 0, 0, 0,102, 0,
0, 0,102, 0, 0, 0,102, 0, 0, 0,103, 0, 0, 0,103, 0, 0, 0,103, 0,
0, 0,103, 0, 0, 0,103, 0, 0, 0,103, 0, 0, 0,102, 0, 0, 0,103, 0,
0, 0,105, 0, 0, 0,105, 0, 0, 0,105, 0, 0, 0,105, 0, 0, 0,105, 0,
0, 0,105, 0, 0, 0,105, 0, 0, 0,105, 0, 0, 0,105, 0, 0, 0,105, 0,
0, 0,105, 0, 0, 0,106, 0, 0, 0, 12, 0, 0, 0, 6, 0, 0, 0,116,105,
116,108,101, 0, 0, 0, 0, 0, 39, 0, 0, 0, 3, 0, 0, 0,117,100, 0, 0,
0, 0, 0, 39, 0, 0, 0, 4, 0, 0, 0,107,101,121, 0, 0, 0, 0, 0, 39,
0, 0, 0, 5, 0, 0, 0,100, 97,116, 97, 0, 10, 0, 0, 0, 39, 0, 0, 0,
9, 0, 0, 0,105,110, 99,111,109,105,110,103, 0, 10, 0, 0, 0, 39, 0, 0,
0, 2, 0, 0, 0, 95, 0, 10, 0, 0, 0, 39, 0, 0, 0, 2, 0, 0, 0,115,
0, 13, 0, 0, 0, 39, 0, 0, 0, 16, 0, 0, 0, 40,102,111,114, 32,103,101,
110,101,114, 97,116,111,114, 41, 0, 19, 0, 0, 0, 28, 0, 0, 0, 12, 0, 0,
0, 40,102,111,114, 32,115,116, 97,116,101, 41, 0, 19, 0, 0, 0, 28, 0, 0,
0, 14, 0, 0, 0, 40,102,111,114, 32, 99,111,110,116,114,111,108, 41, 0, 19,
0, 0, 0, 28, 0, 0, 0, 2, 0, 0, 0, 95, 0, 20, 0, 0, 0, 26, 0, 0,
0, 2, 0, 0, 0,118, 0, 20, 0, 0, 0, 26, 0, 0, 0, 2, 0, 0, 0, 7,
0, 0, 0,116, 97, 98,108,101,115, 0, 3, 0, 0, 0, 87, 82, 0, 0, 0, 0,
0,121, 0, 0, 0,158, 0, 0, 0, 1, 2, 3, 16, 56, 0, 0, 0,196, 0, 0,
0, 0, 1, 0, 0,220, 0, 1, 1,133, 1, 0, 0,193, 65, 0, 0, 37, 2, 0,
0,156,129, 0, 0, 23,128, 64, 3, 22, 64, 0,128,194, 1,128, 0,222, 1, 0,
1,198, 65, 0, 2, 23,192,192, 3, 22, 64, 0,128,202, 1, 0, 0, 9,193,129,
0,198, 65,128, 1,218, 1, 0, 0, 22, 0, 1,128,198, 65, 0, 2,212, 1,128,
3,204,193, 1,130,218, 65, 0, 0, 22, 0, 0,128,193,129, 0, 0, 6, 66,128,
2, 26, 2, 0, 0, 22, 0, 1,128, 76,130,129, 3, 24, 64, 2, 4, 22, 64, 0,
128, 66, 2, 0, 0, 94, 2, 0, 1, 65, 2, 1, 0,128, 2, 0, 3,193, 2, 1,
0, 96,130, 3,128, 69, 3, 0, 0,128, 3, 0, 6,229, 3, 0, 0, 92,131, 0,
0, 23,192,192, 6, 22, 0, 0,128, 69, 67, 1, 0, 23,128,192, 3, 22,128, 0,
128,201, 64,131, 0,193, 1, 1, 0, 22,128, 0,128,134, 67, 0, 2,137, 67,131,
3,204, 1,193, 3, 95,194,251,127, 66, 2,128, 0, 94, 2, 0, 1, 30, 0,128,
0, 6, 0, 0, 0, 4, 7, 0, 0, 0,115,101,108,101, 99,116, 0, 4, 2, 0,
0, 0, 35, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0,
0,240, 63, 4, 13, 0, 0, 0,110,105,108, 95,115,101,110,116,105,110,101,108,
0, 0, 0, 0, 0, 56, 0, 0, 0,123, 0, 0, 0,123, 0, 0, 0,123, 0, 0,
0,125, 0, 0, 0,125, 0, 0, 0,125, 0, 0, 0,125, 0, 0, 0,126, 0, 0,
0,126, 0, 0, 0,126, 0, 0, 0,126, 0, 0, 0,130, 0, 0, 0,130, 0, 0,
0,130, 0, 0, 0,131, 0, 0, 0,131, 0, 0, 0,134, 0, 0, 0,134, 0, 0,
0,134, 0, 0, 0,134, 0, 0, 0,134, 0, 0, 0,134, 0, 0, 0,134, 0, 0,
0,134, 0, 0, 0,134, 0, 0, 0,135, 0, 0, 0,137, 0, 0, 0,137, 0, 0,
0,137, 0, 0, 0,137, 0, 0, 0,137, 0, 0, 0,138, 0, 0, 0,138, 0, 0,
0,141, 0, 0, 0,141, 0, 0, 0,141, 0, 0, 0,141, 0, 0, 0,142, 0, 0,
0,142, 0, 0, 0,142, 0, 0, 0,142, 0, 0, 0,145, 0, 0, 0,145, 0, 0,
0,146, 0, 0, 0,149, 0, 0, 0,149, 0, 0, 0,150, 0, 0, 0,151, 0, 0,
0,151, 0, 0, 0,153, 0, 0, 0,153, 0, 0, 0,154, 0, 0, 0,141, 0, 0,
0,157, 0, 0, 0,157, 0, 0, 0,158, 0, 0, 0, 14, 0, 0, 0, 3, 0, 0,
0,117,100, 0, 0, 0, 0, 0, 55, 0, 0, 0, 4, 0, 0, 0,107,101,121, 0,
0, 0, 0, 0, 55, 0, 0, 0, 4, 0, 0, 0, 97,114,103, 0, 0, 0, 0, 0,
55, 0, 0, 0, 5, 0, 0, 0,100, 97,116, 97, 0, 3, 0, 0, 0, 55, 0, 0,
0, 9, 0, 0, 0,105,110, 99,111,109,105,110,103, 0, 3, 0, 0, 0, 55, 0,
0, 0, 7, 0, 0, 0,108,105,109,105,116,115, 0, 3, 0, 0, 0, 55, 0, 0,
0, 2, 0, 0, 0,110, 0, 7, 0, 0, 0, 55, 0, 0, 0, 4, 0, 0, 0,108,
101,110, 0, 25, 0, 0, 0, 55, 0, 0, 0, 2, 0, 0, 0,109, 0, 26, 0, 0,
0, 55, 0, 0, 0, 12, 0, 0, 0, 40,102,111,114, 32,105,110,100,101,120, 41,
0, 36, 0, 0, 0, 53, 0, 0, 0, 12, 0, 0, 0, 40,102,111,114, 32,108,105,
109,105,116, 41, 0, 36, 0, 0, 0, 53, 0, 0, 0, 11, 0, 0, 0, 40,102,111,
114, 32,115,116,101,112, 41, 0, 36, 0, 0, 0, 53, 0, 0, 0, 2, 0, 0, 0,
105, 0, 37, 0, 0, 0, 52, 0, 0, 0, 4, 0, 0, 0,118, 97,108, 0, 41, 0,
0, 0, 52, 0, 0, 0, 1, 0, 0, 0, 7, 0, 0, 0,116, 97, 98,108,101,115,
0, 0, 0, 0, 0,167, 0, 0, 0,189, 0, 0, 0, 2, 1, 3, 14, 40, 0, 0,
0,132, 0, 0, 0,192, 0, 0, 0,156, 0, 1, 1, 65, 1, 0, 0,133, 65, 0,
0,193,129, 0, 0, 37, 2, 0, 0,156,129, 0, 0,193, 1, 0, 0, 96,193, 6,
128, 69, 66, 0, 0,128, 2, 0, 4,229, 2, 0, 0, 92,130, 0, 0,134, 66, 2,
1, 87,192, 64, 5, 22, 0, 5,128,198, 66,130, 1,218, 2, 0, 0, 22, 64, 2,
128,198, 66,130, 1,198, 2,192, 5, 87,192,192, 5, 22, 64, 1,128,196, 2,128,
0, 6, 67,130, 1, 65, 3, 0, 0,220,130,128, 1,137,192,130, 4, 22, 0, 0,
128,137,192,192, 4,197, 2, 1, 0, 23,192, 2, 5, 22, 0, 0,128,131, 2, 0,
5,192, 2, 0, 5, 0, 3,128, 4,222, 2,128, 1, 95,129,248,127, 30, 0,128,
0, 5, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0,240, 63, 4, 7, 0, 0, 0,115,
101,108,101, 99,116, 0, 4, 2, 0, 0, 0, 35, 0, 0, 4, 13, 0, 0, 0,110,
105,108, 95,115,101,110,116,105,110,101,108, 0, 0, 0, 0, 0, 40, 0, 0, 0,
169, 0, 0, 0,169, 0, 0, 0,169, 0, 0, 0,171, 0, 0, 0,171, 0, 0, 0,
171, 0, 0, 0,171, 0, 0, 0,171, 0, 0, 0,171, 0, 0, 0,171, 0, 0, 0,
172, 0, 0, 0,172, 0, 0, 0,172, 0, 0, 0,172, 0, 0, 0,173, 0, 0, 0,
175, 0, 0, 0,175, 0, 0, 0,176, 0, 0, 0,176, 0, 0, 0,176, 0, 0, 0,
176, 0, 0, 0,176, 0, 0, 0,176, 0, 0, 0,176, 0, 0, 0,178, 0, 0, 0,
178, 0, 0, 0,178, 0, 0, 0,178, 0, 0, 0,178, 0, 0, 0,178, 0, 0, 0,
180, 0, 0, 0,182, 0, 0, 0,182, 0, 0, 0,182, 0, 0, 0,183, 0, 0, 0,
185, 0, 0, 0,185, 0, 0, 0,185, 0, 0, 0,171, 0, 0, 0,189, 0, 0, 0,
11, 0, 0, 0, 3, 0, 0, 0,117,100, 0, 0, 0, 0, 0, 39, 0, 0, 0, 4,
0, 0, 0, 97,114,103, 0, 0, 0, 0, 0, 39, 0, 0, 0, 5, 0, 0, 0,100,
97,116, 97, 0, 3, 0, 0, 0, 39, 0, 0, 0, 9, 0, 0, 0,105,110, 99,111,
109,105,110,103, 0, 3, 0, 0, 0, 39, 0, 0, 0, 2, 0, 0, 0, 95, 0, 3,
0, 0, 0, 39, 0, 0, 0, 12, 0, 0, 0, 40,102,111,114, 32,105,110,100,101,
120, 41, 0, 9, 0, 0, 0, 39, 0, 0, 0, 12, 0, 0, 0, 40,102,111,114, 32,
108,105,109,105,116, 41, 0, 9, 0, 0, 0, 39, 0, 0, 0, 11, 0, 0, 0, 40,
102,111,114, 32,115,116,101,112, 41, 0, 9, 0, 0, 0, 39, 0, 0, 0, 2, 0,
0, 0,105, 0, 10, 0, 0, 0, 38, 0, 0, 0, 4, 0, 0, 0,107,101,121, 0,
14, 0, 0, 0, 38, 0, 0, 0, 4, 0, 0, 0,118, 97,108, 0, 15, 0, 0, 0,
38, 0, 0, 0, 2, 0, 0, 0, 7, 0, 0, 0,116, 97, 98,108,101,115, 0, 13,
0, 0, 0,116, 97, 98,108,101, 95,114,101,109,111,118,101, 0, 0, 0, 0, 0,
195, 0, 0, 0,200, 0, 0, 0, 1, 3, 0, 6, 5, 0, 0, 0,196, 0, 0, 0,
0, 1, 0, 0,220, 0, 1, 1, 73,129,128, 0, 30, 0,128, 0, 0, 0, 0, 0,
0, 0, 0, 0, 5, 0, 0, 0,197, 0, 0, 0,197, 0, 0, 0,197, 0, 0, 0,
199, 0, 0, 0,200, 0, 0, 0, 6, 0, 0, 0, 3, 0, 0, 0,117,100, 0, 0,
0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0,107,101,121, 0, 0, 0, 0, 0, 4,
0, 0, 0, 2, 0, 0, 0,110, 0, 0, 0, 0, 0, 4, 0, 0, 0, 2, 0, 0,
0, 95, 0, 3, 0, 0, 0, 4, 0, 0, 0, 2, 0, 0, 0, 95, 0, 3, 0, 0,
0, 4, 0, 0, 0, 7, 0, 0, 0,108,105,109,105,116,115, 0, 3, 0, 0, 0,
4, 0, 0, 0, 1, 0, 0, 0, 7, 0, 0, 0,116, 97, 98,108,101,115, 0, 0,
0, 0, 0,206, 0, 0, 0,214, 0, 0, 0, 1, 3, 0, 6, 6, 0, 0, 0,196,
0, 0, 0, 0, 1, 0, 0,220, 0, 1, 1,201,128,128, 0, 9, 1,192, 0, 30,
0,128, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 0,208, 0, 0, 0,
208, 0, 0, 0,208, 0, 0, 0,212, 0, 0, 0,213, 0, 0, 0,214, 0, 0, 0,
6, 0, 0, 0, 3, 0, 0, 0,117,100, 0, 0, 0, 0, 0, 5, 0, 0, 0, 4,
0, 0, 0,107,101,121, 0, 0, 0, 0, 0, 5, 0, 0, 0, 4, 0, 0, 0,118,
97,108, 0, 0, 0, 0, 0, 5, 0, 0, 0, 5, 0, 0, 0,100, 97,116, 97, 0,
3, 0, 0, 0, 5, 0, 0, 0, 9, 0, 0, 0,105,110, 99,111,109,105,110,103,
0, 3, 0, 0, 0, 5, 0, 0, 0, 2, 0, 0, 0, 95, 0, 3, 0, 0, 0, 5,
0, 0, 0, 1, 0, 0, 0, 7, 0, 0, 0,116, 97, 98,108,101,115, 0, 0, 0,
0, 0,220, 0, 0, 0,229, 0, 0, 0, 1, 2, 0, 7, 10, 0, 0, 0,132, 0,
0, 0,192, 0, 0, 0,156, 0, 1, 1, 70, 65, 0, 1,133, 1, 0, 0, 23,128,
129, 2, 22, 0, 0,128, 67, 1,128, 2, 94, 1, 0, 1, 30, 0,128, 0, 1, 0,
0, 0, 4, 13, 0, 0, 0,110,105,108, 95,115,101,110,116,105,110,101,108, 0,
0, 0, 0, 0, 10, 0, 0, 0,222, 0, 0, 0,222, 0, 0, 0,222, 0, 0, 0,
224, 0, 0, 0,225, 0, 0, 0,225, 0, 0, 0,225, 0, 0, 0,226, 0, 0, 0,
228, 0, 0, 0,229, 0, 0, 0, 6, 0, 0, 0, 3, 0, 0, 0,117,100, 0, 0,
0, 0, 0, 9, 0, 0, 0, 4, 0, 0, 0,107,101,121, 0, 0, 0, 0, 0, 9,
0, 0, 0, 5, 0, 0, 0,100, 97,116, 97, 0, 3, 0, 0, 0, 9, 0, 0, 0,
2, 0, 0, 0, 95, 0, 3, 0, 0, 0, 9, 0, 0, 0, 2, 0, 0, 0, 95, 0,
3, 0, 0, 0, 9, 0, 0, 0, 4, 0, 0, 0,118, 97,108, 0, 4, 0, 0, 0,
9, 0, 0, 0, 1, 0, 0, 0, 7, 0, 0, 0,116, 97, 98,108,101,115, 0, 0,
0, 0, 0,237, 0, 0, 0,242, 0, 0, 0, 3, 1, 0, 2, 7, 0, 0, 0, 68,
0, 0, 0, 73, 0, 64, 0, 68, 0,128, 0, 73, 0, 64, 0, 68, 0, 0, 1, 73,
0, 64, 0, 30, 0,128, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0,
239, 0, 0, 0,239, 0, 0, 0,240, 0, 0, 0,240, 0, 0, 0,241, 0, 0, 0,
241, 0, 0, 0,242, 0, 0, 0, 1, 0, 0, 0, 3, 0, 0, 0,117,100, 0, 0,
0, 0, 0, 6, 0, 0, 0, 3, 0, 0, 0, 6, 0, 0, 0, 95,100, 97,116, 97,
0, 10, 0, 0, 0, 95,105,110, 99,111,109,105,110,103, 0, 8, 0, 0, 0, 95,
108,105,109,105,116,115, 0, 45, 0, 0, 0, 39, 0, 0, 0, 39, 0, 0, 0, 39,
0, 0, 0, 43, 0, 0, 0, 43, 0, 0, 0, 43, 0, 0, 0, 43, 0, 0, 0, 44,
0, 0, 0, 44, 0, 0, 0, 44, 0, 0, 0, 44, 0, 0, 0, 50, 0, 0, 0, 50,
0, 0, 0, 59, 0, 0, 0, 68, 0, 0, 0, 77, 0, 0, 0, 93, 0, 0, 0, 93,
0, 0, 0, 93, 0, 0, 0, 93, 0, 0, 0,106, 0, 0, 0,106, 0, 0, 0,106,
0, 0, 0,158, 0, 0, 0,158, 0, 0, 0,121, 0, 0, 0,189, 0, 0, 0,189,
0, 0, 0,189, 0, 0, 0,167, 0, 0, 0,200, 0, 0, 0,200, 0, 0, 0,195,
0, 0, 0,214, 0, 0, 0,214, 0, 0, 0,206, 0, 0, 0,229, 0, 0, 0,229,
0, 0, 0,220, 0, 0, 0,242, 0, 0, 0,242, 0, 0, 0,242, 0, 0, 0,242,
0, 0, 0,237, 0, 0, 0,242, 0, 0, 0, 8, 0, 0, 0, 13, 0, 0, 0,116,
97, 98,108,101, 95,114,101,109,111,118,101, 0, 7, 0, 0, 0, 44, 0, 0, 0,
13, 0, 0, 0,116, 97, 98,108,101, 95, 99,111,110, 99, 97,116, 0, 11, 0, 0,
0, 44, 0, 0, 0, 3, 0, 0, 0, 87, 82, 0, 13, 0, 0, 0, 44, 0, 0, 0,
6, 0, 0, 0, 95,100, 97,116, 97, 0, 14, 0, 0, 0, 44, 0, 0, 0, 10, 0,
0, 0, 95,105,110, 99,111,109,105,110,103, 0, 15, 0, 0, 0, 44, 0, 0, 0,
8, 0, 0, 0, 95,108,105,109,105,116,115, 0, 16, 0, 0, 0, 44, 0, 0, 0,
7, 0, 0, 0,116, 97, 98,108,101,115, 0, 20, 0, 0, 0, 44, 0, 0, 0, 6,
0, 0, 0, 68, 69, 66, 85, 71, 0, 23, 0, 0, 0, 44, 0, 0, 0, 0, 0, 0,
0,};
+244
View File
@@ -0,0 +1,244 @@
--
-- KEEPER.LUA
--
-- Keeper state logic
--
-- This code is read in for each "keeper state", which are the hidden, inter-
-- mediate data stores used by Lanes inter-state communication objects.
--
-- Author: Asko Kauppi <akauppi@gmail.com>
--
--[[
===============================================================================
Copyright (C) 2008 Asko Kauppi <akauppi@gmail.com>
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
===============================================================================
]]--
-- unique key instead of 'nil' in queues
--
assert( nil_sentinel )
-- We only need to have base and table libraries (and io for debugging)
--
local table_remove= assert( table.remove )
local table_concat= assert( table.concat )
local function WR(...)
if io then
io.stderr:write( table_concat({...},'\t').."\n" )
end
end
-----
-- Actual data store
--
-- { [linda_deep_ud]= { key= val [, ...] }
-- ...
-- }
--
local _data= {}
-----
-- Entries queued for use when the existing 'data[ud][key]' entry is consumed.
--
-- { [linda_deep_ud]= { key= { val [, ... } [, ...] }
-- ...
-- }
--
local _incoming= {}
-----
-- Length limits (if any) for queues
--
-- 0: don't queue values at all; ':send()' waits if the slot is not vacant
-- N: allow N values to be queued (slot itself + N-1); wait if full
-- nil: no limits, '_incoming' may grow endlessly
--
local _limits= {}
-----
-- data_tbl, incoming_tbl, limits_tbl = tables( linda_deep_ud )
--
-- Gives appropriate tables for a certain Linda (creates them if needed)
--
local function tables( ud )
-- tables are created either all or nothing
--
if not _data[ud] then
_data[ud]= {}
_incoming[ud]= {}
_limits[ud]= {}
end
return _data[ud], _incoming[ud], _limits[ud]
end
local function DEBUG(title,ud,key)
assert( title and ud and key )
local data,incoming,_= tables(ud)
local s= tostring(data[key])
for _,v in ipairs( incoming[key] or {} ) do
s= s..", "..tostring(v)
end
WR( "*** "..title.." ("..tostring(key).."): ", s )
end
-----
-- bool= send( linda_deep_ud, key, ... )
--
-- Send new data (1..N) to 'key' slot. This send is atomic; all the values
-- end up one after each other (this is why having possibility for sending
-- multiple values in one call is deemed important).
--
-- If the queue has a limit, values are sent only if all of them fit in.
--
-- Returns: 'true' if all the values were placed
-- 'false' if sending would exceed the queue limit (wait & retry)
--
function send( ud, key, ... )
local data,incoming,limits= tables(ud)
local n= select('#',...)
if n==0 then return true end -- nothing to send
-- Initialize queue for all keys that have been used with ':send()'
--
if incoming[key]==nil then
incoming[key]= {}
end
local len= data[key] and 1+#incoming[key] or 0
local m= limits[key]
if m and len+n > m then
return false -- would exceed the limit; try again later
end
for i=1,n do
local val= select(i,...)
-- 'nil' in the data replaced by sentinel
if val==nil then
val= nil_sentinel
end
if len==0 then
data[key]= val
len= 1
else
incoming[key][len]= val
len= len+1
end
end
return true
end
-----
-- [val, key]= receive( linda_deep_ud, key [, ...] )
--
-- Read any of the given keys, consuming the data found. Keys are read in
-- order.
--
function receive( ud, ... )
local data,incoming,_= tables(ud)
for i=1,select('#',...) do
local key= select(i,...)
local val= data[key]
if val~=nil then
if incoming[key] and incoming[key][1]~=nil then
-- pop [1] from 'incoming[key]' into the actual slot
data[key]= table_remove( incoming[key], 1 )
else
data[key]= nil -- empty the slot
end
if val==nil_sentinel then
val= nil
end
return val, key
end
end
--return nil
end
-----
-- = limit( linda_deep_ud, key, uint )
--
function limit( ud, key, n )
local _,_,limits= tables(ud)
limits[key]= n
end
-----
-- void= set( linda_deep_ud, key, [val] )
--
function set( ud, key, val )
local data,incoming,_= tables(ud)
-- Setting a key to 'nil' really clears it; only queing uses sentinels.
--
data[key]= val
incoming[key]= nil
end
-----
-- [val]= get( linda_deep_ud, key )
--
function get( ud, key )
local data,_,_= tables(ud)
local val= data[key]
if val==nil_sentinel then
val= nil
end
return val
end
-----
-- void= clear( linda_deep_ud )
--
-- Clear the data structures used for a Linda (at its destructor)
--
function clear( ud )
_data[ud]= nil
_incoming[ud]= nil
_limits[ud]= nil
end
File diff suppressed because it is too large Load Diff
+611
View File
@@ -0,0 +1,611 @@
--
-- LANES.LUA
--
-- Multithreading and -core support for Lua
--
-- Author: Asko Kauppi <akauppi@gmail.com>
--
-- History:
-- Jun-08 AKa: major revise
-- 15-May-07 AKa: pthread_join():less version, some speedup & ability to
-- handle more threads (~ 8000-9000, up from ~ 5000)
-- 26-Feb-07 AKa: serialization working (C side)
-- 17-Sep-06 AKa: started the module (serialization)
--
--[[
===============================================================================
Copyright (C) 2007-08 Asko Kauppi <akauppi@gmail.com>
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
===============================================================================
]]--
module( "lanes", package.seeall )
require "lua51-lanes"
assert( type(lanes)=="table" )
local mm= lanes
local linda_id= assert( mm.linda_id )
local thread_new= assert(mm.thread_new)
local thread_status= assert(mm.thread_status)
local thread_join= assert(mm.thread_join)
local thread_cancel= assert(mm.thread_cancel)
local _single= assert(mm._single)
local _version= assert(mm._version)
local _deep_userdata= assert(mm._deep_userdata)
local now_secs= assert( mm.now_secs )
local wakeup_conv= assert( mm.wakeup_conv )
local timer_gateway= assert( mm.timer_gateway )
local max_prio= assert( mm.max_prio )
-- This check is for sublanes requiring Lanes
--
-- TBD: We could also have the C level expose 'string.gmatch' for us. But this is simpler.
--
if not string then
error( "To use 'lanes', you will also need to have 'string' available.", 2 )
end
--
-- Cache globals for code that might run under sandboxing
--
local assert= assert
local string_gmatch= assert( string.gmatch )
local select= assert( select )
local type= assert( type )
local pairs= assert( pairs )
local tostring= assert( tostring )
local error= assert( error )
local setmetatable= assert( setmetatable )
local rawget= assert( rawget )
ABOUT=
{
author= "Asko Kauppi <akauppi@gmail.com>",
description= "Running multiple Lua states in parallel",
license= "MIT/X11",
copyright= "Copyright (c) 2007-08, Asko Kauppi",
version= _version,
}
-- Making copies of necessary system libs will pass them on as upvalues;
-- only the first state doing "require 'lanes'" will need to have 'string'
-- and 'table' visible.
--
local function WR(str)
io.stderr:write( str.."\n" )
end
local function DUMP( tbl )
if not tbl then return end
local str=""
for k,v in pairs(tbl) do
str= str..k.."="..tostring(v).."\n"
end
WR(str)
end
---=== Laning ===---
-- lane_h[1..n]: lane results, same as via 'lane_h:join()'
-- lane_h[0]: can be read to make sure a thread has finished (always gives 'true')
-- lane_h[-1]: error message, without propagating the error
--
-- Reading a Lane result (or [0]) propagates a possible error in the lane
-- (and execution does not return). Cancelled lanes give 'nil' values.
--
-- lane_h.state: "pending"/"running"/"waiting"/"done"/"error"/"cancelled"
--
local lane_mt= {
__index= function( me, k )
if type(k) == "number" then
-- 'me[0]=true' marks we've already taken in the results
--
if not rawget( me, 0 ) then
-- Wait indefinately; either propagates an error or
-- returns the return values
--
me[0]= true -- marker, even on errors
local t= { thread_join(me._ud) } -- wait indefinate
--
-- { ... } "done": regular return, 0..N results
-- { } "cancelled"
-- { nil, err_str, stack_tbl } "error"
local st= thread_status(me._ud)
if st=="done" then
-- Use 'pairs' and not 'ipairs' so that nil holes in
-- the returned values are tolerated.
--
for i,v in pairs(t) do
me[i]= v
end
elseif st=="error" then
assert( t[1]==nil and t[2] and type(t[3])=="table" )
me[-1]= t[2]
-- me[-2] could carry the stack table, but even
-- me[-1] is rather unnecessary (and undocumented);
-- use ':join()' instead. --AKa 22-Jan-2009
elseif st=="cancelled" then
-- do nothing
else
error( "Unexpected status: "..st )
end
end
-- Check errors even if we'd first peeked them via [-1]
-- and then came for the actual results.
--
local err= rawget(me, -1)
if err~=nil and k~=-1 then
-- Note: Lua 5.1 interpreter is not prepared to show
-- non-string errors, so we use 'tostring()' here
-- to get meaningful output. --AKa 22-Jan-2009
--
-- Also, the stack dump we get is no good; it only
-- lists our internal Lanes functions. There seems
-- to be no way to switch it off, though.
-- Level 3 should show the line where 'h[x]' was read
-- but this only seems to work for string messages
-- (Lua 5.1.4). No idea, why. --AKa 22-Jan-2009
--
error( tostring(err), 3 ) -- level 3 should show the line where 'h[x]' was read
end
return rawget( me, k )
--
elseif k=="status" then -- me.status
return thread_status(me._ud)
--
else
error( "Unknown key: "..k )
end
end
}
-----
-- h= lanes.gen( [libs_str|opt_tbl [, ...],] lane_func ) ( [...] )
--
-- 'libs': nil: no libraries available (default)
-- "": only base library ('assert', 'print', 'unpack' etc.)
-- "math,os": math + os + base libraries (named ones + base)
-- "*": all standard libraries available
--
-- 'opt': .priority: int (-2..+2) smaller is lower priority (0 = default)
--
-- .cancelstep: bool | uint
-- false: cancellation check only at pending Linda operations
-- (send/receive) so no runtime performance penalty (default)
-- true: adequate cancellation check (same as 100)
-- >0: cancellation check every x Lua lines (small number= faster
-- reaction but more performance overhead)
--
-- .globals: table of globals to set for a new thread (passed by value)
--
-- ... (more options may be introduced later) ...
--
-- Calling with a function parameter ('lane_func') ends the string/table
-- modifiers, and prepares a lane generator. One can either finish here,
-- and call the generator later (maybe multiple times, with different parameters)
-- or add on actual thread arguments to also ignite the thread on the same call.
--
local lane_proxy
local valid_libs= {
["package"]= true,
["table"]= true,
["io"]= true,
["os"]= true,
["string"]= true,
["math"]= true,
["debug"]= true,
--
["base"]= true,
["coroutine"]= true,
["*"]= true
}
function gen( ... )
local opt= {}
local libs= nil
local lev= 2 -- level for errors
local n= select('#',...)
if n==0 then
error( "No parameters!" )
end
for i=1,n-1 do
local v= select(i,...)
if type(v)=="string" then
libs= libs and libs..","..v or v
elseif type(v)=="table" then
for k,vv in pairs(v) do
opt[k]= vv
end
elseif v==nil then
-- skip
else
error( "Bad parameter: "..tostring(v) )
end
end
local func= select(n,...)
if type(func)~="function" then
error( "Last parameter not function: "..tostring(func) )
end
-- Check 'libs' already here, so the error goes in the right place
-- (otherwise will be noticed only once the generator is called)
--
if libs then
for s in string_gmatch(libs, "[%a*]+") do
if not valid_libs[s] then
error( "Bad library name: "..s )
end
end
end
local prio, cs, g_tbl
for k,v in pairs(opt) do
if k=="priority" then prio= v
elseif k=="cancelstep" then cs= (v==true) and 100 or
(v==false) and 0 or
type(v)=="number" and v or
error( "Bad cancelstep: "..tostring(v), lev )
elseif k=="globals" then g_tbl= v
--..
elseif k==1 then error( "unkeyed option: ".. tostring(v), lev )
else error( "Bad option: ".. tostring(k), lev )
end
end
-- Lane generator
--
return function(...)
return lane_proxy( thread_new( func, libs, cs, prio, g_tbl,
... ) ) -- args
end
end
lane_proxy= function( ud )
local proxy= {
_ud= ud,
-- void= me:cancel()
--
cancel= function(me) thread_cancel(me._ud) end,
-- [...] | [nil,err,stack_tbl]= me:join( [wait_secs=-1] )
--
join= function( me, wait )
return thread_join( me._ud, wait )
end,
}
assert( proxy._ud )
setmetatable( proxy, lane_mt )
return proxy
end
---=== Lindas ===---
-- We let the C code attach methods to userdata directly
-----
-- linda_ud= lanes.linda()
--
function linda()
local proxy= _deep_userdata( linda_id )
assert( (type(proxy) == "userdata") and getmetatable(proxy) )
return proxy
end
---=== Timers ===---
--
-- On first 'require "lanes"', a timer lane is spawned that will maintain
-- timer tables and sleep in between the timer events. All interaction with
-- the timer lane happens via a 'timer_gateway' Linda, which is common to
-- all that 'require "lanes"'.
--
-- Linda protocol to timer lane:
--
-- TGW_KEY: linda_h, key, [wakeup_at_secs], [repeat_secs]
--
local TGW_KEY= "(timer control)" -- the key does not matter, a 'weird' key may help debugging
local first_time_key= "first time"
local first_time= timer_gateway:get(first_time_key) == nil
timer_gateway:set(first_time_key,true)
--
-- Timer lane; initialize only on the first 'require "lanes"' instance (which naturally
-- has 'table' always declared)
--
if first_time then
local table_remove= assert( table.remove )
local table_insert= assert( table.insert )
--
-- { [deep_linda_lightuserdata]= { [deep_linda_lightuserdata]=linda_h,
-- [key]= { wakeup_secs [,period_secs] } [, ...] },
-- }
--
-- Collection of all running timers, indexed with linda's & key.
--
-- Note that we need to use the deep lightuserdata identifiers, instead
-- of 'linda_h' themselves as table indices. Otherwise, we'd get multiple
-- entries for the same timer.
--
-- The 'hidden' reference to Linda proxy is used in 'check_timers()' but
-- also important to keep the Linda alive, even if all outside world threw
-- away pointers to it (which would ruin uniqueness of the deep pointer).
-- Now we're safe.
--
local collection= {}
--
-- set_timer( linda_h, key [,wakeup_at_secs [,period_secs]] )
--
local function set_timer( linda, key, wakeup_at, period )
assert( wakeup_at==nil or wakeup_at>0.0 )
assert( period==nil or period>0.0 )
local linda_deep= linda:deep()
assert( linda_deep )
-- Find or make a lookup for this timer
--
local t1= collection[linda_deep]
if not t1 then
t1= { [linda_deep]= linda } -- proxy to use the Linda
collection[linda_deep]= t1
end
if wakeup_at==nil then
-- Clear the timer
--
t1[key]= nil
-- Remove empty tables from collection; speeds timer checks and
-- lets our 'safety reference' proxy be gc:ed as well.
--
local empty= true
for k,_ in pairs(t1) do
if k~= linda_deep then
empty= false; break
end
end
if empty then
collection[linda_deep]= nil
end
-- Note: any unread timer value is left at 'linda[key]' intensionally;
-- clearing a timer just stops it.
else
-- New timer or changing the timings
--
local t2= t1[key]
if not t2 then
t2= {}; t1[key]= t2
end
t2[1]= wakeup_at
t2[2]= period -- can be 'nil'
end
end
-----
-- [next_wakeup_at]= check_timers()
--
-- Check timers, and wake up the ones expired (if any)
--
-- Returns the closest upcoming (remaining) wakeup time (or 'nil' if none).
--
local function check_timers()
local now= now_secs()
local next_wakeup
for linda_deep,t1 in pairs(collection) do
for key,t2 in pairs(t1) do
--
if key==linda_deep then
-- no 'continue' in Lua :/
else
-- 't2': { wakeup_at_secs [,period_secs] }
--
local wakeup_at= t2[1]
local period= t2[2] -- may be 'nil'
if wakeup_at <= now then
local linda= t1[linda_deep]
assert(linda)
linda:set( key, now )
-- 'pairs()' allows the values to be modified (and even
-- removed) as far as keys are not touched
if not period then
-- one-time timer; gone
--
t1[key]= nil
wakeup_at= nil -- no 'continue' in Lua :/
else
-- repeating timer; find next wakeup (may jump multiple repeats)
--
repeat
wakeup_at= wakeup_at+period
until wakeup_at > now
t2[1]= wakeup_at
end
end
if wakeup_at and ((not next_wakeup) or (wakeup_at < next_wakeup)) then
next_wakeup= wakeup_at
end
end
end -- t2 loop
end -- t1 loop
return next_wakeup -- may be 'nil'
end
-----
-- Snore loop (run as a lane on the background)
--
-- High priority, to get trustworthy timings.
--
-- We let the timer lane be a "free running" thread; no handle to it
-- remains.
--
gen( "io", { priority=max_prio }, function()
while true do
local next_wakeup= check_timers()
-- Sleep until next timer to wake up, or a set/clear command
--
local secs= next_wakeup and (next_wakeup - now_secs()) or nil
local linda= timer_gateway:receive( secs, TGW_KEY )
if linda then
local key= timer_gateway:receive( 0.0, TGW_KEY )
local wakeup_at= timer_gateway:receive( 0.0, TGW_KEY )
local period= timer_gateway:receive( 0.0, TGW_KEY )
assert( key and wakeup_at and period )
set_timer( linda, key, wakeup_at, period>0 and period or nil )
end
end
end )()
end
-----
-- = timer( linda_h, key_val, date_tbl|first_secs [,period_secs] )
--
function timer( linda, key, a, period )
if a==0.0 then
-- Caller expects to get current time stamp in Linda, on return
-- (like the timer had expired instantly); it would be good to set this
-- as late as possible (to give most current time) but also we want it
-- to precede any possible timers that might start striking.
--
linda:set( key, now_secs() )
if not period or period==0.0 then
timer_gateway:send( TGW_KEY, linda, key, nil, nil ) -- clear the timer
return -- nothing more to do
end
a= period
end
local wakeup_at= type(a)=="table" and wakeup_conv(a) -- given point of time
or now_secs()+a
-- queue to timer
--
timer_gateway:send( TGW_KEY, linda, key, wakeup_at, period )
end
---=== Lock & atomic generators ===---
-- These functions are just surface sugar, but make solutions easier to read.
-- Not many applications should even need explicit locks or atomic counters.
--
-- lock_f= lanes.genlock( linda_h, key [,N_uint=1] )
--
-- = lock_f( +M ) -- acquire M
-- ...locked...
-- = lock_f( -M ) -- release M
--
-- Returns an access function that allows 'N' simultaneous entries between
-- acquire (+M) and release (-M). For binary locks, use M==1.
--
function genlock( linda, key, N )
linda:limit(key,N)
linda:set(key,nil) -- clears existing data
--
-- [true [, ...]= trues(uint)
--
local function trues(n)
if n>0 then return true,trues(n-1) end
end
return
function(M)
if M>0 then
-- 'nil' timeout allows 'key' to be numeric
linda:send( nil, key, trues(M) ) -- suspends until been able to push them
else
for i=1,-M do
linda:receive( key )
end
end
end
end
--
-- atomic_f= lanes.genatomic( linda_h, key [,initial_num=0.0] )
--
-- int= atomic_f( [diff_num=1.0] )
--
-- Returns an access function that allows atomic increment/decrement of the
-- number in 'key'.
--
function genatomic( linda, key, initial_val )
linda:limit(key,2) -- value [,true]
linda:set(key,initial_val or 0.0) -- clears existing data (also queue)
return
function(diff)
-- 'nil' allows 'key' to be numeric
linda:send( nil, key, true ) -- suspends until our 'true' is in
local val= linda:get(key) + (diff or 1.0)
linda:set( key, val ) -- releases the lock, by emptying queue
return val
end
end
--the end
File diff suppressed because it is too large Load Diff
+721
View File
@@ -0,0 +1,721 @@
/*
* THREADING.C Copyright (c) 2007-08, Asko Kauppi
*
* Lua Lanes OS threading specific code.
*
* References:
* <http://www.cse.wustl.edu/~schmidt/win32-cv-1.html>
*/
/*
===============================================================================
Copyright (C) 2007-08 Asko Kauppi <akauppi@gmail.com>
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
===============================================================================
*/
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include <errno.h>
#include <math.h>
#include "threading.h"
#include "lua.h"
#if !((defined PLATFORM_WIN32) || (defined PLATFORM_POCKETPC))
# include <sys/time.h>
#endif
#if defined(PLATFORM_LINUX) || defined(PLATFORM_CYGWIN)
# include <sys/types.h>
# include <unistd.h>
#endif
/* Linux needs to check, whether it's been run as root
*/
#ifdef PLATFORM_LINUX
volatile bool_t sudo;
#endif
#ifdef _MSC_VER
// ".. selected for automatic inline expansion" (/O2 option)
# pragma warning( disable : 4711 )
// ".. type cast from function pointer ... to data pointer"
# pragma warning( disable : 4054 )
#endif
//#define THREAD_CREATE_RETRIES_MAX 20
// loops (maybe retry forever?)
/*
* FAIL is for unexpected API return values - essentially programming
* error in _this_ code.
*/
#if (defined PLATFORM_WIN32) || (defined PLATFORM_POCKETPC)
static void FAIL( const char *funcname, int rc ) {
fprintf( stderr, "%s() failed! (%d)\n", funcname, rc );
abort();
}
#endif
/*
* Returns millisecond timing (in seconds) for the current time.
*
* Note: This function should be called once in single-threaded mode in Win32,
* to get it initialized.
*/
time_d now_secs(void) {
#if (defined PLATFORM_WIN32) || (defined PLATFORM_POCKETPC)
/*
* Windows FILETIME values are "100-nanosecond intervals since
* January 1, 1601 (UTC)" (MSDN). Well, we'd want Unix Epoch as
* the offset and it seems, so would they:
*
* <http://msdn.microsoft.com/en-us/library/ms724928(VS.85).aspx>
*/
SYSTEMTIME st;
FILETIME ft;
ULARGE_INTEGER uli;
static ULARGE_INTEGER uli_epoch; // Jan 1st 1970 0:0:0
if (uli_epoch.HighPart==0) {
st.wYear= 1970;
st.wMonth= 1; // Jan
st.wDay= 1;
st.wHour= st.wMinute= st.wSecond= st.wMilliseconds= 0;
if (!SystemTimeToFileTime( &st, &ft ))
FAIL( "SystemTimeToFileTime", GetLastError() );
uli_epoch.LowPart= ft.dwLowDateTime;
uli_epoch.HighPart= ft.dwHighDateTime;
}
GetSystemTime( &st ); // current system date/time in UTC
if (!SystemTimeToFileTime( &st, &ft ))
FAIL( "SystemTimeToFileTime", GetLastError() );
uli.LowPart= ft.dwLowDateTime;
uli.HighPart= ft.dwHighDateTime;
/* 'double' has less accuracy than 64-bit int, but if it were to degrade,
* it would do so gracefully. In practise, the integer accuracy is not
* of the 100ns class but just 1ms (Windows XP).
*/
# if 1
// >= 2.0.3 code
return (double) ((uli.QuadPart - uli_epoch.QuadPart)/10000) / 1000.0;
# elif 0
// fix from Kriss Daniels, see:
// <http://luaforge.net/forum/forum.php?thread_id=22704&forum_id=1781>
//
// "seem to be getting negative numbers from the old version, probably number
// conversion clipping, this fixes it and maintains ms resolution"
//
// This was a bad fix, and caused timer test 5 sec timers to disappear.
// --AKa 25-Jan-2009
//
return ((double)((signed)((uli.QuadPart/10000) - (uli_epoch.QuadPart/10000)))) / 1000.0;
# else
// <= 2.0.2 code
return (double)(uli.QuadPart - uli_epoch.QuadPart) / 10000000.0;
# endif
#else
struct timeval tv;
// {
// time_t tv_sec; /* seconds since Jan. 1, 1970 */
// suseconds_t tv_usec; /* and microseconds */
// };
int rc= gettimeofday( &tv, NULL /*time zone not used any more (in Linux)*/ );
assert( rc==0 );
return ((double)tv.tv_sec) + ((tv.tv_usec)/1000) / 1000.0;
#endif
}
/*
*/
time_d SIGNAL_TIMEOUT_PREPARE( double secs ) {
if (secs<=0.0) return secs;
else return now_secs() + secs;
}
#if !((defined PLATFORM_WIN32) || (defined PLATFORM_POCKETPC))
/*
* Prepare 'abs_secs' kind of timeout to 'timespec' format
*/
static void prepare_timeout( struct timespec *ts, time_d abs_secs ) {
assert(ts);
assert( abs_secs >= 0.0 );
if (abs_secs==0.0)
abs_secs= now_secs();
ts->tv_sec= floor( abs_secs );
ts->tv_nsec= ((long)((abs_secs - ts->tv_sec) * 1000.0 +0.5)) * 1000000UL; // 1ms = 1000000ns
}
#endif
/*---=== Threading ===---*/
//---
// It may be meaningful to explicitly limit the new threads' C stack size.
// We should know how much Lua needs in the C stack, all Lua side allocations
// are done in heap so they don't count.
//
// Consequence of _not_ limiting the stack is running out of virtual memory
// with 1000-5000 threads on 32-bit systems.
//
// Note: using external C modules may be affected by the stack size check.
// if having problems, set back to '0' (default stack size of the system).
//
// Win32: 64K (?)
// Win64: xxx
//
// Linux x86: 2MB Ubuntu 7.04 via 'pthread_getstacksize()'
// Linux x64: xxx
// Linux ARM: xxx
//
// OS X 10.4.9: 512K <http://developer.apple.com/qa/qa2005/qa1419.html>
// valid values N * 4KB
//
#ifndef _THREAD_STACK_SIZE
# if (defined PLATFORM_WIN32) || (defined PLATFORM_POCKETPC) || (defined PLATFORM_CYGWIN)
# define _THREAD_STACK_SIZE 0
// Win32: does it work with less?
# elif (defined PLATFORM_OSX)
# define _THREAD_STACK_SIZE (524288/2) // 262144
// OS X: "make test" works on 65536 and even below
// "make perftest" works on >= 4*65536 == 262144 (not 3*65536)
# elif (defined PLATFORM_LINUX) && (defined __i386)
# define _THREAD_STACK_SIZE (2097152/16) // 131072
// Linux x86 (Ubuntu 7.04): "make perftest" works on /16 (not on /32)
# elif (defined PLATFORM_BSD) && (defined __i386)
# define _THREAD_STACK_SIZE (1048576/8) // 131072
// FreeBSD 6.2 SMP i386: ("gmake perftest" works on /8 (not on /16)
# endif
#endif
#if (defined PLATFORM_WIN32) || (defined PLATFORM_POCKETPC)
//
void MUTEX_INIT( MUTEX_T *ref ) {
*ref= CreateMutex( NULL /*security attr*/, FALSE /*not locked*/, NULL );
if (!ref) FAIL( "CreateMutex", GetLastError() );
}
void MUTEX_FREE( MUTEX_T *ref ) {
if (!CloseHandle(*ref)) FAIL( "CloseHandle (mutex)", GetLastError() );
*ref= NULL;
}
void MUTEX_LOCK( MUTEX_T *ref ) {
DWORD rc= WaitForSingleObject(*ref,INFINITE);
if (rc!=0) FAIL( "WaitForSingleObject", rc==WAIT_FAILED ? GetLastError() : rc );
}
void MUTEX_UNLOCK( MUTEX_T *ref ) {
if (!ReleaseMutex(*ref))
FAIL( "ReleaseMutex", GetLastError() );
}
/* MSDN: "If you would like to use the CRT in ThreadProc, use the
_beginthreadex function instead (of CreateThread)."
MSDN: "you can create at most 2028 threads"
*/
void
THREAD_CREATE( THREAD_T *ref,
THREAD_RETURN_T (__stdcall *func)( void * ),
// Note: Visual C++ requires '__stdcall' where it is
void *data, int prio /* -3..+3 */ ) {
HANDLE h= (HANDLE)_beginthreadex( NULL, // security
_THREAD_STACK_SIZE,
func,
data,
0, // flags (0/CREATE_SUSPENDED)
NULL // thread id (not used)
);
if (h == INVALID_HANDLE_VALUE) FAIL( "CreateThread", GetLastError() );
if (prio!= 0) {
int win_prio= (prio == +3) ? THREAD_PRIORITY_TIME_CRITICAL :
(prio == +2) ? THREAD_PRIORITY_HIGHEST :
(prio == +1) ? THREAD_PRIORITY_ABOVE_NORMAL :
(prio == -1) ? THREAD_PRIORITY_BELOW_NORMAL :
(prio == -2) ? THREAD_PRIORITY_LOWEST :
THREAD_PRIORITY_IDLE; // -3
if (!SetThreadPriority( h, win_prio ))
FAIL( "SetThreadPriority", GetLastError() );
}
*ref= h;
}
//
bool_t THREAD_WAIT( THREAD_T *ref, double secs ) {
long ms= (long)((secs*1000.0)+0.5);
DWORD rc= WaitForSingleObject( *ref, ms<0 ? INFINITE:ms /*timeout*/ );
//
// (WAIT_ABANDONED)
// WAIT_OBJECT_0 success (0)
// WAIT_TIMEOUT
// WAIT_FAILED more info via GetLastError()
if (rc == WAIT_TIMEOUT) return FALSE;
if (rc != 0) FAIL( "WaitForSingleObject", rc );
*ref= NULL; // thread no longer usable
return TRUE;
}
//
void THREAD_KILL( THREAD_T *ref ) {
if (!TerminateThread( *ref, 0 )) FAIL("TerminateThread", GetLastError());
*ref= NULL;
}
//
void SIGNAL_INIT( SIGNAL_T *ref ) {
// 'manual reset' event type selected, to be able to wake up all the
// waiting threads.
//
HANDLE h= CreateEvent( NULL, // security attributes
TRUE, // TRUE: manual event
FALSE, // Initial state
NULL ); // name
if (h == NULL) FAIL( "CreateEvent", GetLastError() );
*ref= h;
}
void SIGNAL_FREE( SIGNAL_T *ref ) {
if (!CloseHandle(*ref)) FAIL( "CloseHandle (event)", GetLastError() );
*ref= NULL;
}
//
bool_t SIGNAL_WAIT( SIGNAL_T *ref, MUTEX_T *mu_ref, time_d abs_secs ) {
DWORD rc;
long ms;
if (abs_secs<0.0)
ms= INFINITE;
else if (abs_secs==0.0)
ms= 0;
else {
ms= (long) ((abs_secs - now_secs())*1000.0 + 0.5);
// If the time already passed, still try once (ms==0). A short timeout
// may have turned negative or 0 because of the two time samples done.
//
if (ms<0) ms= 0;
}
// Unlock and start a wait, atomically (like condition variables do)
//
rc= SignalObjectAndWait( *mu_ref, // "object to signal" (unlock)
*ref, // "object to wait on"
ms,
FALSE ); // not alertable
// All waiting locks are woken here; each competes for the lock in turn.
//
// Note: We must get the lock even if we've timed out; it makes upper
// level code equivalent to how PThread does it.
//
MUTEX_LOCK(mu_ref);
if (rc==WAIT_TIMEOUT) return FALSE;
if (rc!=0) FAIL( "SignalObjectAndWait", rc );
return TRUE;
}
void SIGNAL_ALL( SIGNAL_T *ref ) {
/*
* MSDN tries to scare that 'PulseEvent' is bad, unreliable and should not be
* used. Use condition variables instead (wow, they have that!?!); which will
* ONLY WORK on Vista and 2008 Server, it seems... so MS, isn't it.
*
* I refuse to believe that; using 'PulseEvent' is probably just as good as
* using Windows (XP) in the first place. Just don't use APC's (asynchronous
* process calls) in your C side coding.
*/
// PulseEvent on manual event:
//
// Release ALL threads waiting for it (and go instantly back to unsignalled
// status = future threads to start a wait will wait)
//
if (!PulseEvent( *ref ))
FAIL( "PulseEvent", GetLastError() );
}
#else
// PThread (Linux, OS X, ...)
//
// On OS X, user processes seem to be able to change priorities.
// On Linux, SCHED_RR and su privileges are required.. !-(
//
#include <errno.h>
#include <sys/time.h>
//
static void _PT_FAIL( int rc, const char *name, const char *file, uint_t line ) {
const char *why= (rc==EINVAL) ? "EINVAL" :
(rc==EBUSY) ? "EBUSY" :
(rc==EPERM) ? "EPERM" :
(rc==ENOMEM) ? "ENOMEM" :
(rc==ESRCH) ? "ESRCH" :
//...
"";
fprintf( stderr, "%s %d: %s failed, %d %s\n", file, line, name, rc, why );
abort();
}
#define PT_CALL( call ) { int rc= call; if (rc!=0) _PT_FAIL( rc, #call, __FILE__, __LINE__ ); }
//
void SIGNAL_INIT( SIGNAL_T *ref ) {
PT_CALL( pthread_cond_init(ref,NULL /*attr*/) );
}
void SIGNAL_FREE( SIGNAL_T *ref ) {
PT_CALL( pthread_cond_destroy(ref) );
}
//
/*
* Timeout is given as absolute since we may have fake wakeups during
* a timed out sleep. A Linda with some other key read, or just because
* PThread cond vars can wake up unwantedly.
*/
bool_t SIGNAL_WAIT( SIGNAL_T *ref, pthread_mutex_t *mu, time_d abs_secs ) {
if (abs_secs<0.0) {
PT_CALL( pthread_cond_wait( ref, mu ) ); // infinite
} else {
int rc;
struct timespec ts;
assert( abs_secs != 0.0 );
prepare_timeout( &ts, abs_secs );
rc= pthread_cond_timedwait( ref, mu, &ts );
if (rc==ETIMEDOUT) return FALSE;
if (rc) { _PT_FAIL( rc, "pthread_cond_timedwait()", __FILE__, __LINE__ ); }
}
return TRUE;
}
//
void SIGNAL_ONE( SIGNAL_T *ref ) {
PT_CALL( pthread_cond_signal(ref) ); // wake up ONE (or no) waiting thread
}
//
void SIGNAL_ALL( SIGNAL_T *ref ) {
PT_CALL( pthread_cond_broadcast(ref) ); // wake up ALL waiting threads
}
//
void THREAD_CREATE( THREAD_T* ref,
THREAD_RETURN_T (*func)( void * ),
void *data, int prio /* -2..+2 */ ) {
pthread_attr_t _a;
pthread_attr_t *a= &_a;
struct sched_param sp;
PT_CALL( pthread_attr_init(a) );
#ifndef PTHREAD_TIMEDJOIN
// We create a NON-JOINABLE thread. This is mainly due to the lack of
// 'pthread_timedjoin()', but does offer other benefits (s.a. earlier
// freeing of the thread's resources).
//
PT_CALL( pthread_attr_setdetachstate(a,PTHREAD_CREATE_DETACHED) );
#endif
// Use this to find a system's default stack size (DEBUG)
#if 0
{ size_t n; pthread_attr_getstacksize( a, &n );
fprintf( stderr, "Getstack: %u\n", (unsigned int)n ); }
// 524288 on OS X
// 2097152 on Linux x86 (Ubuntu 7.04)
// 1048576 on FreeBSD 6.2 SMP i386
#endif
#if (defined _THREAD_STACK_SIZE) && (_THREAD_STACK_SIZE > 0)
PT_CALL( pthread_attr_setstacksize( a, _THREAD_STACK_SIZE ) );
#endif
bool_t normal=
#if defined(PLATFORM_LINUX) && defined(LINUX_SCHED_RR)
!sudo; // with sudo, even normal thread must use SCHED_RR
#else
prio == 0; // create a default thread if
#endif
if (!normal) {
// NB: PThreads priority handling is about as twisty as one can get it
// (and then some). DON*T TRUST ANYTHING YOU READ ON THE NET!!!
// "The specified scheduling parameters are only used if the scheduling
// parameter inheritance attribute is PTHREAD_EXPLICIT_SCHED."
//
PT_CALL( pthread_attr_setinheritsched( a, PTHREAD_EXPLICIT_SCHED ) );
//---
// "Select the scheduling policy for the thread: one of SCHED_OTHER
// (regular, non-real-time scheduling), SCHED_RR (real-time,
// round-robin) or SCHED_FIFO (real-time, first-in first-out)."
//
// "Using the RR policy ensures that all threads having the same
// priority level will be scheduled equally, regardless of their activity."
//
// "For SCHED_FIFO and SCHED_RR, the only required member of the
// sched_param structure is the priority sched_priority. For SCHED_OTHER,
// the affected scheduling parameters are implementation-defined."
//
// "The priority of a thread is specified as a delta which is added to
// the priority of the process."
//
// ".. priority is an integer value, in the range from 1 to 127.
// 1 is the least-favored priority, 127 is the most-favored."
//
// "Priority level 0 cannot be used: it is reserved for the system."
//
// "When you use specify a priority of -99 in a call to
// pthread_setschedparam(), the priority of the target thread is
// lowered to the lowest possible value."
//
// ...
// ** CONCLUSION **
//
// PThread priorities are _hugely_ system specific, and we need at
// least OS specific settings. Hopefully, Linuxes and OS X versions
// are uniform enough, among each other...
//
#ifdef PLATFORM_OSX
// AK 10-Apr-07 (OS X PowerPC 10.4.9):
//
// With SCHED_RR, 26 seems to be the "normal" priority, where setting
// it does not seem to affect the order of threads processed.
//
// With SCHED_OTHER, the range 25..32 is normal (maybe the same 26,
// but the difference is not so clear with OTHER).
//
// 'sched_get_priority_min()' and '..max()' give 15, 47 as the
// priority limits. This could imply, user mode applications won't
// be able to use values outside of that range.
//
#define _PRIO_MODE SCHED_OTHER
// OS X 10.4.9 (PowerPC) gives ENOTSUP for process scope
//#define _PRIO_SCOPE PTHREAD_SCOPE_PROCESS
#define _PRIO_HI 32 // seems to work (_carefully_ picked!)
#define _PRIO_0 26 // detected
#define _PRIO_LO 1 // seems to work (tested)
#elif defined(PLATFORM_LINUX)
// (based on Ubuntu Linux 2.6.15 kernel)
//
// SCHED_OTHER is the default policy, but does not allow for priorities.
// SCHED_RR allows priorities, all of which (1..99) are higher than
// a thread with SCHED_OTHER policy.
//
// <http://kerneltrap.org/node/6080>
// <http://en.wikipedia.org/wiki/Native_POSIX_Thread_Library>
// <http://www.net.in.tum.de/~gregor/docs/pthread-scheduling.html>
//
// Manuals suggest checking #ifdef _POSIX_THREAD_PRIORITY_SCHEDULING,
// but even Ubuntu does not seem to define it.
//
#define _PRIO_MODE SCHED_RR
// NTLP 2.5: only system scope allowed (being the basic reason why
// root privileges are required..)
//#define _PRIO_SCOPE PTHREAD_SCOPE_PROCESS
#define _PRIO_HI 99
#define _PRIO_0 50
#define _PRIO_LO 1
#elif defined(PLATFORM_BSD)
//
// <http://www.net.in.tum.de/~gregor/docs/pthread-scheduling.html>
//
// "When control over the thread scheduling is desired, then FreeBSD
// with the libpthread implementation is by far the best choice .."
//
#define _PRIO_MODE SCHED_OTHER
#define _PRIO_SCOPE PTHREAD_SCOPE_PROCESS
#define _PRIO_HI 31
#define _PRIO_0 15
#define _PRIO_LO 1
#elif defined(PLATFORM_CYGWIN)
//
// TBD: Find right values for Cygwin
//
#else
#error "Unknown OS: not implemented!"
#endif
#ifdef _PRIO_SCOPE
PT_CALL( pthread_attr_setscope( a, _PRIO_SCOPE ) );
#endif
PT_CALL( pthread_attr_setschedpolicy( a, _PRIO_MODE ) );
#define _PRIO_AN (_PRIO_0 + ((_PRIO_HI-_PRIO_0)/2) )
#define _PRIO_BN (_PRIO_LO + ((_PRIO_0-_PRIO_LO)/2) )
sp.sched_priority=
(prio == +2) ? _PRIO_HI :
(prio == +1) ? _PRIO_AN :
#if defined(PLATFORM_LINUX) && defined(LINUX_SCHED_RR)
(prio == 0) ? _PRIO_0 :
#endif
(prio == -1) ? _PRIO_BN : _PRIO_LO;
PT_CALL( pthread_attr_setschedparam( a, &sp ) );
}
//---
// Seems on OS X, _POSIX_THREAD_THREADS_MAX is some kind of system
// thread limit (not userland thread). Actual limit for us is way higher.
// PTHREAD_THREADS_MAX is not defined (even though man page refers to it!)
//
# ifndef THREAD_CREATE_RETRIES_MAX
// Don't bother with retries; a failure is a failure
//
{
int rc= pthread_create( ref, a, func, data );
if (rc) _PT_FAIL( rc, "pthread_create()", __FILE__, __LINE__-1 );
}
# else
# error "This code deprecated"
/*
// Wait slightly if thread creation has exchausted the system
//
{ uint_t retries;
for( retries=0; retries<THREAD_CREATE_RETRIES_MAX; retries++ ) {
int rc= pthread_create( ref, a, func, data );
//
// OS X / Linux:
// EAGAIN: ".. lacked the necessary resources to create
// another thread, or the system-imposed limit on the
// total number of threads in a process
// [PTHREAD_THREADS_MAX] would be exceeded."
// EINVAL: attr is invalid
// Linux:
// EPERM: no rights for given parameters or scheduling (no sudo)
// ENOMEM: (known to fail with this code, too - not listed in man)
if (rc==0) break; // ok!
// In practise, exhaustion seems to be coming from memory, not a
// maximum number of threads. Keep tuning... ;)
//
if (rc==EAGAIN) {
//fprintf( stderr, "Looping (retries=%d) ", retries ); // DEBUG
// Try again, later.
Yield();
} else {
_PT_FAIL( rc, "pthread_create()", __FILE__, __LINE__ );
}
}
}
*/
# endif
if (a) {
PT_CALL( pthread_attr_destroy(a) );
}
}
//
/*
* Wait for a thread to finish.
*
* 'mu_ref' is a lock we should use for the waiting; initially unlocked.
* Same lock as passed to THREAD_EXIT.
*
* Returns TRUE for succesful wait, FALSE for timed out
*/
#ifdef PTHREAD_TIMEDJOIN
bool_t THREAD_WAIT( THREAD_T *ref, double secs )
#else
bool_t THREAD_WAIT( THREAD_T *ref, SIGNAL_T *signal_ref, MUTEX_T *mu_ref, volatile enum e_status *st_ref, double secs )
#endif
{
struct timespec ts_store;
const struct timespec *timeout= NULL;
bool_t done;
// Do timeout counting before the locks
//
#ifdef PTHREAD_TIMEDJOIN
if (secs>=0.0) {
#else
if (secs>0.0) {
#endif
prepare_timeout( &ts_store, now_secs()+secs );
timeout= &ts_store;
}
#ifdef PTHREAD_TIMEDJOIN
/* Thread is joinable
*/
if (!timeout) {
PT_CALL( pthread_join( *ref, NULL /*ignore exit value*/ ));
done= TRUE;
} else {
int rc= PTHREAD_TIMEDJOIN( *ref, NULL, timeout );
if ((rc!=0) && (rc!=ETIMEDOUT)) {
_PT_FAIL( rc, "PTHREAD_TIMEDJOIN", __FILE__, __LINE__-2 );
}
done= rc==0;
}
#else
/* Since we've set the thread up as PTHREAD_CREATE_DETACHED, we cannot
* join with it. Use the cond.var.
*/
MUTEX_LOCK( mu_ref );
// 'secs'==0.0 does not need to wait, just take the current status
// within the 'mu_ref' locks
//
if (secs != 0.0) {
while( *st_ref < DONE ) {
if (!timeout) {
PT_CALL( pthread_cond_wait( signal_ref, mu_ref ));
} else {
int rc= pthread_cond_timedwait( signal_ref, mu_ref, timeout );
if (rc==ETIMEDOUT) break;
if (rc!=0) _PT_FAIL( rc, "pthread_cond_timedwait", __FILE__, __LINE__-2 );
}
}
}
done= *st_ref >= DONE; // DONE|ERROR_ST|CANCELLED
MUTEX_UNLOCK( mu_ref );
#endif
return done;
}
//
void THREAD_KILL( THREAD_T *ref ) {
pthread_cancel( *ref );
}
#endif
static const lua_Alloc alloc_f= 0;
+196
View File
@@ -0,0 +1,196 @@
/*
* THREADING.H
*/
#ifndef THREADING_H
#define THREADING_H
/* Platform detection
*/
#ifdef _WIN32_WCE
#define PLATFORM_POCKETPC
#elif (defined _WIN32)
#define PLATFORM_WIN32
#elif (defined __linux__)
#define PLATFORM_LINUX
#elif (defined __APPLE__) && (defined __MACH__)
#define PLATFORM_OSX
#elif (defined __NetBSD__) || (defined __FreeBSD__) || (defined BSD)
#define PLATFORM_BSD
#elif (defined __QNX__)
#define PLATFORM_QNX
#elif (defined __CYGWIN__)
#define PLATFORM_CYGWIN
#else
#error "Unknown platform!"
#endif
typedef int bool_t;
#ifndef FALSE
# define FALSE 0
# define TRUE 1
#endif
typedef unsigned int uint_t;
#if defined(PLATFORM_WIN32) && defined(__GNUC__)
/* MinGW with MSVCR80.DLL */
/* Do this BEFORE including time.h so that it is declaring _mktime32()
* as it would have declared mktime().
*/
# define mktime _mktime32
#endif
#include <time.h>
/* Note: ERROR is a defined entity on Win32
*/
enum e_status { PENDING, RUNNING, WAITING, DONE, ERROR_ST, CANCELLED };
/*---=== Locks & Signals ===---
*/
#if (defined PLATFORM_WIN32) || (defined PLATFORM_POCKETPC)
#define WIN32_LEAN_AND_MEAN
// 'SignalObjectAndWait' needs this (targets Windows 2000 and above)
#define _WIN32_WINNT 0x0400
#include <windows.h>
#include <process.h>
// MSDN: http://msdn2.microsoft.com/en-us/library/ms684254.aspx
//
// CRITICAL_SECTION can be used for simple code protection. Mutexes are
// needed for use with the SIGNAL system.
//
#define MUTEX_T HANDLE
void MUTEX_INIT( MUTEX_T *ref );
#define MUTEX_RECURSIVE_INIT(ref) MUTEX_INIT(ref) /* always recursive in Win32 */
void MUTEX_FREE( MUTEX_T *ref );
void MUTEX_LOCK( MUTEX_T *ref );
void MUTEX_UNLOCK( MUTEX_T *ref );
typedef unsigned THREAD_RETURN_T;
#define SIGNAL_T HANDLE
#define YIELD() Sleep(0)
#else
// PThread (Linux, OS X, ...)
//
#include <pthread.h>
#ifdef PLATFORM_LINUX
# define _MUTEX_RECURSIVE PTHREAD_MUTEX_RECURSIVE_NP
#else
/* OS X, ... */
# define _MUTEX_RECURSIVE PTHREAD_MUTEX_RECURSIVE
#endif
#define MUTEX_T pthread_mutex_t
#define MUTEX_INIT(ref) pthread_mutex_init(ref,NULL)
#define MUTEX_RECURSIVE_INIT(ref) \
{ pthread_mutexattr_t a; pthread_mutexattr_init( &a ); \
pthread_mutexattr_settype( &a, _MUTEX_RECURSIVE ); \
pthread_mutex_init(ref,&a); pthread_mutexattr_destroy( &a ); \
}
#define MUTEX_FREE(ref) pthread_mutex_destroy(ref)
#define MUTEX_LOCK(ref) pthread_mutex_lock(ref)
#define MUTEX_UNLOCK(ref) pthread_mutex_unlock(ref)
typedef void * THREAD_RETURN_T;
typedef pthread_cond_t SIGNAL_T;
void SIGNAL_ONE( SIGNAL_T *ref );
// Yield is non-portable:
//
// OS X 10.4.8/9 has pthread_yield_np()
// Linux 2.4 has pthread_yield() if _GNU_SOURCE is #defined
// FreeBSD 6.2 has pthread_yield()
// ...
//
#ifdef PLATFORM_OSX
#define YIELD() pthread_yield_np()
#else
#define YIELD() pthread_yield()
#endif
#endif
void SIGNAL_INIT( SIGNAL_T *ref );
void SIGNAL_FREE( SIGNAL_T *ref );
void SIGNAL_ALL( SIGNAL_T *ref );
/*
* 'time_d': <0.0 for no timeout
* 0.0 for instant check
* >0.0 absolute timeout in secs + ms
*/
typedef double time_d;
time_d now_secs(void);
time_d SIGNAL_TIMEOUT_PREPARE( double rel_secs );
bool_t SIGNAL_WAIT( SIGNAL_T *ref, MUTEX_T *mu, time_d timeout );
/*---=== Threading ===---
*/
#if (defined PLATFORM_WIN32) || (defined PLATFORM_POCKETPC)
typedef HANDLE THREAD_T;
//
void THREAD_CREATE( THREAD_T *ref,
THREAD_RETURN_T (__stdcall *func)( void * ),
void *data, int prio /* -3..+3 */ );
# define THREAD_PRIO_MIN (-3)
# define THREAD_PRIO_MAX (+3)
#else
/* Platforms that have a timed 'pthread_join()' can get away with a simpler
* implementation. Others will use a condition variable.
*/
# ifdef USE_PTHREAD_TIMEDJOIN
# ifdef PLATFORM_OSX
# error "No 'pthread_timedjoin()' on this system"
# else
/* Linux, ... */
# define PTHREAD_TIMEDJOIN pthread_timedjoin_np
# endif
# endif
typedef pthread_t THREAD_T;
void THREAD_CREATE( THREAD_T *ref,
THREAD_RETURN_T (*func)( void * ),
void *data, int prio /* -2..+2 */ );
# if defined(PLATFORM_LINUX)
volatile bool_t sudo;
# ifdef LINUX_SCHED_RR
# define THREAD_PRIO_MIN (sudo ? -2 : 0)
# else
# define THREAD_PRIO_MIN (0)
# endif
# define THREAD_PRIO_MAX (sudo ? +2 : 0)
# else
# define THREAD_PRIO_MIN (-2)
# define THREAD_PRIO_MAX (+2)
# endif
#endif
/*
* Win32 and PTHREAD_TIMEDJOIN allow waiting for a thread with a timeout.
* Posix without PTHREAD_TIMEDJOIN needs to use a condition variable approach.
*/
#if (defined PLATFORM_WIN32) || (defined PLATFORM_POCKETPC) || (defined PTHREAD_TIMEDJOIN)
bool_t THREAD_WAIT( THREAD_T *ref, double secs );
#else
bool_t THREAD_WAIT( THREAD_T *ref, SIGNAL_T *signal_ref, MUTEX_T *mu_ref, volatile enum e_status *st_ref, double secs );
#endif
void THREAD_KILL( THREAD_T *ref );
#endif
// THREADING_H
File diff suppressed because it is too large Load Diff
+72
View File
@@ -0,0 +1,72 @@
/*
* TOOLS.H
*/
#ifndef TOOLS_H
#define TOOLS_H
#include "lua.h"
#include "threading.h"
// MUTEX_T
#include <assert.h>
// Note: The < -10000 test is to leave registry/global/upvalue indices untouched
//
#define /*int*/ STACK_ABS(L,n) \
( ((n) >= 0 || (n) <= -10000) ? (n) : lua_gettop(L) +(n) +1 )
#ifdef NDEBUG
#define _ASSERT_L(lua,c) /*nothing*/
#define STACK_CHECK(L) /*nothing*/
#define STACK_MID(L,c) /*nothing*/
#define STACK_END(L,c) /*nothing*/
#define STACK_DUMP(L) /*nothing*/
#define DEBUG() /*nothing*/
#else
#define _ASSERT_L(lua,c) { if (!(c)) luaL_error( lua, "ASSERT failed: %s:%d '%s'", __FILE__, __LINE__, #c ); }
//
#define STACK_CHECK(L) { int _oldtop_##L = lua_gettop(L);
#define STACK_MID(L,change) { int a= lua_gettop(L)-_oldtop_##L; int b= (change); \
if (a != b) luaL_error( L, "STACK ASSERT failed (%d not %d): %s:%d", a, b, __FILE__, __LINE__ ); }
#define STACK_END(L,change) STACK_MID(L,change) }
#define STACK_DUMP(L) luaG_dump(L);
#define DEBUG() fprintf( stderr, "<<%s %d>>\n", __FILE__, __LINE__ );
#endif
#define ASSERT_L(c) _ASSERT_L(L,c)
#define STACK_GROW(L,n) { if (!lua_checkstack(L,n)) luaL_error( L, "Cannot grow stack!" ); }
#define LUAG_FUNC( func_name ) static int LG_##func_name( lua_State *L )
#define luaG_optunsigned(L,i,d) ((uint_t) luaL_optinteger(L,i,d))
#define luaG_tounsigned(L,i) ((uint_t) lua_tointeger(L,i))
#define luaG_isany(L,i) (!lua_isnil(L,i))
#define luaG_typename( L, index ) lua_typename( L, lua_type(L,index) )
void luaG_dump( lua_State* L );
const char *luaG_openlibs( lua_State *L, const char *libs );
int luaG_deep_userdata( lua_State *L );
void *luaG_todeep( lua_State *L, lua_CFunction idfunc, int index );
typedef struct {
volatile int refcount;
void *deep;
} DEEP_PRELUDE;
void luaG_push_proxy( lua_State *L, lua_CFunction idfunc, DEEP_PRELUDE *deep_userdata );
void luaG_inter_copy( lua_State *L, lua_State *L2, uint_t n );
void luaG_inter_move( lua_State *L, lua_State *L2, uint_t n );
// Lock for reference counter inc/dec locks (to be initialized by outside code)
//
extern MUTEX_T deep_lock;
extern MUTEX_T mtid_lock;
#endif
// TOOLS_H
@@ -0,0 +1,149 @@
/*=========================================================================*\
* Auxiliar routines for class hierarchy manipulation
* LuaSocket toolkit
*
* RCS ID: $Id: auxiliar.c,v 1.14 2005/10/07 04:40:59 diego Exp $
\*=========================================================================*/
#include <string.h>
#include <stdio.h>
#include "auxiliar.h"
/*=========================================================================*\
* Exported functions
\*=========================================================================*/
/*-------------------------------------------------------------------------*\
* Initializes the module
\*-------------------------------------------------------------------------*/
int auxiliar_open(lua_State *L) {
(void) L;
return 0;
}
/*-------------------------------------------------------------------------*\
* Creates a new class with given methods
* Methods whose names start with __ are passed directly to the metatable.
\*-------------------------------------------------------------------------*/
void auxiliar_newclass(lua_State *L, const char *classname, luaL_reg *func) {
luaL_newmetatable(L, classname); /* mt */
/* create __index table to place methods */
lua_pushstring(L, "__index"); /* mt,"__index" */
lua_newtable(L); /* mt,"__index",it */
/* put class name into class metatable */
lua_pushstring(L, "class"); /* mt,"__index",it,"class" */
lua_pushstring(L, classname); /* mt,"__index",it,"class",classname */
lua_rawset(L, -3); /* mt,"__index",it */
/* pass all methods that start with _ to the metatable, and all others
* to the index table */
for (; func->name; func++) { /* mt,"__index",it */
lua_pushstring(L, func->name);
lua_pushcfunction(L, func->func);
lua_rawset(L, func->name[0] == '_' ? -5: -3);
}
lua_rawset(L, -3); /* mt */
lua_pop(L, 1);
}
/*-------------------------------------------------------------------------*\
* Prints the value of a class in a nice way
\*-------------------------------------------------------------------------*/
int auxiliar_tostring(lua_State *L) {
char buf[32];
if (!lua_getmetatable(L, 1)) goto error;
lua_pushstring(L, "__index");
lua_gettable(L, -2);
if (!lua_istable(L, -1)) goto error;
lua_pushstring(L, "class");
lua_gettable(L, -2);
if (!lua_isstring(L, -1)) goto error;
sprintf(buf, "%p", lua_touserdata(L, 1));
lua_pushfstring(L, "%s: %s", lua_tostring(L, -1), buf);
return 1;
error:
lua_pushstring(L, "invalid object passed to 'auxiliar.c:__tostring'");
lua_error(L);
return 1;
}
/*-------------------------------------------------------------------------*\
* Insert class into group
\*-------------------------------------------------------------------------*/
void auxiliar_add2group(lua_State *L, const char *classname, const char *groupname) {
luaL_getmetatable(L, classname);
lua_pushstring(L, groupname);
lua_pushboolean(L, 1);
lua_rawset(L, -3);
lua_pop(L, 1);
}
/*-------------------------------------------------------------------------*\
* Make sure argument is a boolean
\*-------------------------------------------------------------------------*/
int auxiliar_checkboolean(lua_State *L, int objidx) {
if (!lua_isboolean(L, objidx))
luaL_typerror(L, objidx, lua_typename(L, LUA_TBOOLEAN));
return lua_toboolean(L, objidx);
}
/*-------------------------------------------------------------------------*\
* Return userdata pointer if object belongs to a given class, abort with
* error otherwise
\*-------------------------------------------------------------------------*/
void *auxiliar_checkclass(lua_State *L, const char *classname, int objidx) {
void *data = auxiliar_getclassudata(L, classname, objidx);
if (!data) {
char msg[45];
sprintf(msg, "%.35s expected", classname);
luaL_argerror(L, objidx, msg);
}
return data;
}
/*-------------------------------------------------------------------------*\
* Return userdata pointer if object belongs to a given group, abort with
* error otherwise
\*-------------------------------------------------------------------------*/
void *auxiliar_checkgroup(lua_State *L, const char *groupname, int objidx) {
void *data = auxiliar_getgroupudata(L, groupname, objidx);
if (!data) {
char msg[45];
sprintf(msg, "%.35s expected", groupname);
luaL_argerror(L, objidx, msg);
}
return data;
}
/*-------------------------------------------------------------------------*\
* Set object class
\*-------------------------------------------------------------------------*/
void auxiliar_setclass(lua_State *L, const char *classname, int objidx) {
luaL_getmetatable(L, classname);
if (objidx < 0) objidx--;
lua_setmetatable(L, objidx);
}
/*-------------------------------------------------------------------------*\
* Get a userdata pointer if object belongs to a given group. Return NULL
* otherwise
\*-------------------------------------------------------------------------*/
void *auxiliar_getgroupudata(lua_State *L, const char *groupname, int objidx) {
if (!lua_getmetatable(L, objidx))
return NULL;
lua_pushstring(L, groupname);
lua_rawget(L, -2);
if (lua_isnil(L, -1)) {
lua_pop(L, 2);
return NULL;
} else {
lua_pop(L, 2);
return lua_touserdata(L, objidx);
}
}
/*-------------------------------------------------------------------------*\
* Get a userdata pointer if object belongs to a given class. Return NULL
* otherwise
\*-------------------------------------------------------------------------*/
void *auxiliar_getclassudata(lua_State *L, const char *classname, int objidx) {
return luaL_checkudata(L, objidx, classname);
}
@@ -0,0 +1,48 @@
#ifndef AUXILIAR_H
#define AUXILIAR_H
/*=========================================================================*\
* Auxiliar routines for class hierarchy manipulation
* LuaSocket toolkit (but completely independent of other LuaSocket modules)
*
* A LuaSocket class is a name associated with Lua metatables. A LuaSocket
* group is a name associated with a class. A class can belong to any number
* of groups. This module provides the functionality to:
*
* - create new classes
* - add classes to groups
* - set the class of objects
* - check if an object belongs to a given class or group
* - get the userdata associated to objects
* - print objects in a pretty way
*
* LuaSocket class names follow the convention <module>{<class>}. Modules
* can define any number of classes and groups. The module tcp.c, for
* example, defines the classes tcp{master}, tcp{client} and tcp{server} and
* the groups tcp{client,server} and tcp{any}. Module functions can then
* perform type-checking on their arguments by either class or group.
*
* LuaSocket metatables define the __index metamethod as being a table. This
* table has one field for each method supported by the class, and a field
* "class" with the class name.
*
* The mapping from class name to the corresponding metatable and the
* reverse mapping are done using lauxlib.
*
* RCS ID: $Id: auxiliar.h,v 1.9 2005/10/07 04:40:59 diego Exp $
\*=========================================================================*/
#include "lua.h"
#include "lauxlib.h"
int auxiliar_open(lua_State *L);
void auxiliar_newclass(lua_State *L, const char *classname, luaL_reg *func);
void auxiliar_add2group(lua_State *L, const char *classname, const char *group);
void auxiliar_setclass(lua_State *L, const char *classname, int objidx);
void *auxiliar_checkclass(lua_State *L, const char *classname, int objidx);
void *auxiliar_checkgroup(lua_State *L, const char *groupname, int objidx);
void *auxiliar_getclassudata(lua_State *L, const char *groupname, int objidx);
void *auxiliar_getgroupudata(lua_State *L, const char *groupname, int objidx);
int auxiliar_checkboolean(lua_State *L, int objidx);
int auxiliar_tostring(lua_State *L);
#endif /* AUXILIAR_H */
@@ -0,0 +1,268 @@
/*=========================================================================*\
* Input/Output interface for Lua programs
* LuaSocket toolkit
*
* RCS ID: $Id: buffer.c,v 1.28 2007/06/11 23:44:54 diego Exp $
\*=========================================================================*/
#include "lua.h"
#include "lauxlib.h"
#include "buffer.h"
/*=========================================================================*\
* Internal function prototypes
\*=========================================================================*/
static int recvraw(p_buffer buf, size_t wanted, luaL_Buffer *b);
static int recvline(p_buffer buf, luaL_Buffer *b);
static int recvall(p_buffer buf, luaL_Buffer *b);
static int buffer_get(p_buffer buf, const char **data, size_t *count);
static void buffer_skip(p_buffer buf, size_t count);
static int sendraw(p_buffer buf, const char *data, size_t count, size_t *sent);
/* min and max macros */
#ifndef MIN
#define MIN(x, y) ((x) < (y) ? x : y)
#endif
#ifndef MAX
#define MAX(x, y) ((x) > (y) ? x : y)
#endif
/*=========================================================================*\
* Exported functions
\*=========================================================================*/
/*-------------------------------------------------------------------------*\
* Initializes module
\*-------------------------------------------------------------------------*/
int buffer_open(lua_State *L) {
(void) L;
return 0;
}
/*-------------------------------------------------------------------------*\
* Initializes C structure
\*-------------------------------------------------------------------------*/
void buffer_init(p_buffer buf, p_io io, p_timeout tm) {
buf->first = buf->last = 0;
buf->io = io;
buf->tm = tm;
buf->received = buf->sent = 0;
buf->birthday = timeout_gettime();
}
/*-------------------------------------------------------------------------*\
* object:getstats() interface
\*-------------------------------------------------------------------------*/
int buffer_meth_getstats(lua_State *L, p_buffer buf) {
lua_pushnumber(L, buf->received);
lua_pushnumber(L, buf->sent);
lua_pushnumber(L, timeout_gettime() - buf->birthday);
return 3;
}
/*-------------------------------------------------------------------------*\
* object:setstats() interface
\*-------------------------------------------------------------------------*/
int buffer_meth_setstats(lua_State *L, p_buffer buf) {
buf->received = (long) luaL_optnumber(L, 2, buf->received);
buf->sent = (long) luaL_optnumber(L, 3, buf->sent);
if (lua_isnumber(L, 4)) buf->birthday = timeout_gettime() - lua_tonumber(L, 4);
lua_pushnumber(L, 1);
return 1;
}
/*-------------------------------------------------------------------------*\
* object:send() interface
\*-------------------------------------------------------------------------*/
int buffer_meth_send(lua_State *L, p_buffer buf) {
int top = lua_gettop(L);
int err = IO_DONE;
size_t size = 0, sent = 0;
const char *data = luaL_checklstring(L, 2, &size);
long start = (long) luaL_optnumber(L, 3, 1);
long end = (long) luaL_optnumber(L, 4, -1);
p_timeout tm = timeout_markstart(buf->tm);
if (start < 0) start = (long) (size+start+1);
if (end < 0) end = (long) (size+end+1);
if (start < 1) start = (long) 1;
if (end > (long) size) end = (long) size;
if (start <= end) err = sendraw(buf, data+start-1, end-start+1, &sent);
/* check if there was an error */
if (err != IO_DONE) {
lua_pushnil(L);
lua_pushstring(L, buf->io->error(buf->io->ctx, err));
lua_pushnumber(L, sent+start-1);
} else {
lua_pushnumber(L, sent+start-1);
lua_pushnil(L);
lua_pushnil(L);
}
#ifdef LUASOCKET_DEBUG
/* push time elapsed during operation as the last return value */
lua_pushnumber(L, timeout_gettime() - timeout_getstart(tm));
#endif
return lua_gettop(L) - top;
}
/*-------------------------------------------------------------------------*\
* object:receive() interface
\*-------------------------------------------------------------------------*/
int buffer_meth_receive(lua_State *L, p_buffer buf) {
int err = IO_DONE, top = lua_gettop(L);
luaL_Buffer b;
size_t size;
const char *part = luaL_optlstring(L, 3, "", &size);
p_timeout tm = timeout_markstart(buf->tm);
/* initialize buffer with optional extra prefix
* (useful for concatenating previous partial results) */
luaL_buffinit(L, &b);
luaL_addlstring(&b, part, size);
/* receive new patterns */
if (!lua_isnumber(L, 2)) {
const char *p= luaL_optstring(L, 2, "*l");
if (p[0] == '*' && p[1] == 'l') err = recvline(buf, &b);
else if (p[0] == '*' && p[1] == 'a') err = recvall(buf, &b);
else luaL_argcheck(L, 0, 2, "invalid receive pattern");
/* get a fixed number of bytes (minus what was already partially
* received) */
} else err = recvraw(buf, (size_t) lua_tonumber(L, 2)-size, &b);
/* check if there was an error */
if (err != IO_DONE) {
/* we can't push anyting in the stack before pushing the
* contents of the buffer. this is the reason for the complication */
luaL_pushresult(&b);
lua_pushstring(L, buf->io->error(buf->io->ctx, err));
lua_pushvalue(L, -2);
lua_pushnil(L);
lua_replace(L, -4);
} else {
luaL_pushresult(&b);
lua_pushnil(L);
lua_pushnil(L);
}
#ifdef LUASOCKET_DEBUG
/* push time elapsed during operation as the last return value */
lua_pushnumber(L, timeout_gettime() - timeout_getstart(tm));
#endif
return lua_gettop(L) - top;
}
/*-------------------------------------------------------------------------*\
* Determines if there is any data in the read buffer
\*-------------------------------------------------------------------------*/
int buffer_isempty(p_buffer buf) {
return buf->first >= buf->last;
}
/*=========================================================================*\
* Internal functions
\*=========================================================================*/
/*-------------------------------------------------------------------------*\
* Sends a block of data (unbuffered)
\*-------------------------------------------------------------------------*/
#define STEPSIZE 8192
static int sendraw(p_buffer buf, const char *data, size_t count, size_t *sent) {
p_io io = buf->io;
p_timeout tm = buf->tm;
size_t total = 0;
int err = IO_DONE;
while (total < count && err == IO_DONE) {
size_t done;
size_t step = (count-total <= STEPSIZE)? count-total: STEPSIZE;
err = io->send(io->ctx, data+total, step, &done, tm);
total += done;
}
*sent = total;
buf->sent += total;
return err;
}
/*-------------------------------------------------------------------------*\
* Reads a fixed number of bytes (buffered)
\*-------------------------------------------------------------------------*/
static int recvraw(p_buffer buf, size_t wanted, luaL_Buffer *b) {
int err = IO_DONE;
size_t total = 0;
while (err == IO_DONE) {
size_t count; const char *data;
err = buffer_get(buf, &data, &count);
count = MIN(count, wanted - total);
luaL_addlstring(b, data, count);
buffer_skip(buf, count);
total += count;
if (total >= wanted) break;
}
return err;
}
/*-------------------------------------------------------------------------*\
* Reads everything until the connection is closed (buffered)
\*-------------------------------------------------------------------------*/
static int recvall(p_buffer buf, luaL_Buffer *b) {
int err = IO_DONE;
size_t total = 0;
while (err == IO_DONE) {
const char *data; size_t count;
err = buffer_get(buf, &data, &count);
total += count;
luaL_addlstring(b, data, count);
buffer_skip(buf, count);
}
if (err == IO_CLOSED) {
if (total > 0) return IO_DONE;
else return IO_CLOSED;
} else return err;
}
/*-------------------------------------------------------------------------*\
* Reads a line terminated by a CR LF pair or just by a LF. The CR and LF
* are not returned by the function and are discarded from the buffer
\*-------------------------------------------------------------------------*/
static int recvline(p_buffer buf, luaL_Buffer *b) {
int err = IO_DONE;
while (err == IO_DONE) {
size_t count, pos; const char *data;
err = buffer_get(buf, &data, &count);
pos = 0;
while (pos < count && data[pos] != '\n') {
/* we ignore all \r's */
if (data[pos] != '\r') luaL_putchar(b, data[pos]);
pos++;
}
if (pos < count) { /* found '\n' */
buffer_skip(buf, pos+1); /* skip '\n' too */
break; /* we are done */
} else /* reached the end of the buffer */
buffer_skip(buf, pos);
}
return err;
}
/*-------------------------------------------------------------------------*\
* Skips a given number of bytes from read buffer. No data is read from the
* transport layer
\*-------------------------------------------------------------------------*/
static void buffer_skip(p_buffer buf, size_t count) {
buf->received += count;
buf->first += count;
if (buffer_isempty(buf))
buf->first = buf->last = 0;
}
/*-------------------------------------------------------------------------*\
* Return any data available in buffer, or get more data from transport layer
* if buffer is empty
\*-------------------------------------------------------------------------*/
static int buffer_get(p_buffer buf, const char **data, size_t *count) {
int err = IO_DONE;
p_io io = buf->io;
p_timeout tm = buf->tm;
if (buffer_isempty(buf)) {
size_t got;
err = io->recv(io->ctx, buf->data, BUF_SIZE, &got, tm);
buf->first = 0;
buf->last = got;
}
*count = buf->last - buf->first;
*data = buf->data + buf->first;
return err;
}
@@ -0,0 +1,47 @@
#ifndef BUF_H
#define BUF_H
/*=========================================================================*\
* Input/Output interface for Lua programs
* LuaSocket toolkit
*
* Line patterns require buffering. Reading one character at a time involves
* too many system calls and is very slow. This module implements the
* LuaSocket interface for input/output on connected objects, as seen by
* Lua programs.
*
* Input is buffered. Output is *not* buffered because there was no simple
* way of making sure the buffered output data would ever be sent.
*
* The module is built on top of the I/O abstraction defined in io.h and the
* timeout management is done with the timeout.h interface.
*
* RCS ID: $Id: buffer.h,v 1.12 2005/10/07 04:40:59 diego Exp $
\*=========================================================================*/
#include "lua.h"
#include "io.h"
#include "timeout.h"
/* buffer size in bytes */
#define BUF_SIZE 8192
/* buffer control structure */
typedef struct t_buffer_ {
double birthday; /* throttle support info: creation time, */
size_t sent, received; /* bytes sent, and bytes received */
p_io io; /* IO driver used for this buffer */
p_timeout tm; /* timeout management for this buffer */
size_t first, last; /* index of first and last bytes of stored data */
char data[BUF_SIZE]; /* storage space for buffer data */
} t_buffer;
typedef t_buffer *p_buffer;
int buffer_open(lua_State *L);
void buffer_init(p_buffer buf, p_io io, p_timeout tm);
int buffer_meth_send(lua_State *L, p_buffer buf);
int buffer_meth_receive(lua_State *L, p_buffer buf);
int buffer_meth_getstats(lua_State *L, p_buffer buf);
int buffer_meth_setstats(lua_State *L, p_buffer buf);
int buffer_isempty(p_buffer buf);
#endif /* BUF_H */
@@ -0,0 +1,99 @@
/*=========================================================================*\
* Simple exception support
* LuaSocket toolkit
*
* RCS ID: $Id: except.c,v 1.8 2005/09/29 06:11:41 diego Exp $
\*=========================================================================*/
#include <stdio.h>
#include "lua.h"
#include "lauxlib.h"
#include "except.h"
/*=========================================================================*\
* Internal function prototypes.
\*=========================================================================*/
static int global_protect(lua_State *L);
static int global_newtry(lua_State *L);
static int protected_(lua_State *L);
static int finalize(lua_State *L);
static int do_nothing(lua_State *L);
/* except functions */
static luaL_reg func[] = {
{"newtry", global_newtry},
{"protect", global_protect},
{NULL, NULL}
};
/*-------------------------------------------------------------------------*\
* Try factory
\*-------------------------------------------------------------------------*/
static void wrap(lua_State *L) {
lua_newtable(L);
lua_pushnumber(L, 1);
lua_pushvalue(L, -3);
lua_settable(L, -3);
lua_insert(L, -2);
lua_pop(L, 1);
}
static int finalize(lua_State *L) {
if (!lua_toboolean(L, 1)) {
lua_pushvalue(L, lua_upvalueindex(1));
lua_pcall(L, 0, 0, 0);
lua_settop(L, 2);
wrap(L);
lua_error(L);
return 0;
} else return lua_gettop(L);
}
static int do_nothing(lua_State *L) {
(void) L;
return 0;
}
static int global_newtry(lua_State *L) {
lua_settop(L, 1);
if (lua_isnil(L, 1)) lua_pushcfunction(L, do_nothing);
lua_pushcclosure(L, finalize, 1);
return 1;
}
/*-------------------------------------------------------------------------*\
* Protect factory
\*-------------------------------------------------------------------------*/
static int unwrap(lua_State *L) {
if (lua_istable(L, -1)) {
lua_pushnumber(L, 1);
lua_gettable(L, -2);
lua_pushnil(L);
lua_insert(L, -2);
return 1;
} else return 0;
}
static int protected_(lua_State *L) {
lua_pushvalue(L, lua_upvalueindex(1));
lua_insert(L, 1);
if (lua_pcall(L, lua_gettop(L) - 1, LUA_MULTRET, 0) != 0) {
if (unwrap(L)) return 2;
else lua_error(L);
return 0;
} else return lua_gettop(L);
}
static int global_protect(lua_State *L) {
lua_pushcclosure(L, protected_, 1);
return 1;
}
/*-------------------------------------------------------------------------*\
* Init module
\*-------------------------------------------------------------------------*/
int except_open(lua_State *L) {
luaL_openlib(L, NULL, func, 0);
return 0;
}
@@ -0,0 +1,35 @@
#ifndef EXCEPT_H
#define EXCEPT_H
/*=========================================================================*\
* Exception control
* LuaSocket toolkit (but completely independent from other modules)
*
* This provides support for simple exceptions in Lua. During the
* development of the HTTP/FTP/SMTP support, it became aparent that
* error checking was taking a substantial amount of the coding. These
* function greatly simplify the task of checking errors.
*
* The main idea is that functions should return nil as its first return
* value when it finds an error, and return an error message (or value)
* following nil. In case of success, as long as the first value is not nil,
* the other values don't matter.
*
* The idea is to nest function calls with the "try" function. This function
* checks the first value, and calls "error" on the second if the first is
* nil. Otherwise, it returns all values it received.
*
* The protect function returns a new function that behaves exactly like the
* function it receives, but the new function doesn't throw exceptions: it
* returns nil followed by the error message instead.
*
* With these two function, it's easy to write functions that throw
* exceptions on error, but that don't interrupt the user script.
*
* RCS ID: $Id: except.h,v 1.2 2005/09/29 06:11:41 diego Exp $
\*=========================================================================*/
#include "lua.h"
int except_open(lua_State *L);
#endif
@@ -0,0 +1,281 @@
-----------------------------------------------------------------------------
-- FTP support for the Lua language
-- LuaSocket toolkit.
-- Author: Diego Nehab
-- RCS ID: $Id: ftp.lua,v 1.45 2007/07/11 19:25:47 diego Exp $
-----------------------------------------------------------------------------
-----------------------------------------------------------------------------
-- Declare module and import dependencies
-----------------------------------------------------------------------------
local base = _G
local table = require("table")
local string = require("string")
local math = require("math")
local socket = require("socket")
local url = require("socket.url")
local tp = require("socket.tp")
local ltn12 = require("ltn12")
module("socket.ftp")
-----------------------------------------------------------------------------
-- Program constants
-----------------------------------------------------------------------------
-- timeout in seconds before the program gives up on a connection
TIMEOUT = 60
-- default port for ftp service
PORT = 21
-- this is the default anonymous password. used when no password is
-- provided in url. should be changed to your e-mail.
USER = "ftp"
PASSWORD = "anonymous@anonymous.org"
-----------------------------------------------------------------------------
-- Low level FTP API
-----------------------------------------------------------------------------
local metat = { __index = {} }
function open(server, port, create)
local tp = socket.try(tp.connect(server, port or PORT, TIMEOUT, create))
local f = base.setmetatable({ tp = tp }, metat)
-- make sure everything gets closed in an exception
f.try = socket.newtry(function() f:close() end)
return f
end
function metat.__index:portconnect()
self.try(self.server:settimeout(TIMEOUT))
self.data = self.try(self.server:accept())
self.try(self.data:settimeout(TIMEOUT))
end
function metat.__index:pasvconnect()
self.data = self.try(socket.tcp())
self.try(self.data:settimeout(TIMEOUT))
self.try(self.data:connect(self.pasvt.ip, self.pasvt.port))
end
function metat.__index:login(user, password)
self.try(self.tp:command("user", user or USER))
local code, reply = self.try(self.tp:check{"2..", 331})
if code == 331 then
self.try(self.tp:command("pass", password or PASSWORD))
self.try(self.tp:check("2.."))
end
return 1
end
function metat.__index:pasv()
self.try(self.tp:command("pasv"))
local code, reply = self.try(self.tp:check("2.."))
local pattern = "(%d+)%D(%d+)%D(%d+)%D(%d+)%D(%d+)%D(%d+)"
local a, b, c, d, p1, p2 = socket.skip(2, string.find(reply, pattern))
self.try(a and b and c and d and p1 and p2, reply)
self.pasvt = {
ip = string.format("%d.%d.%d.%d", a, b, c, d),
port = p1*256 + p2
}
if self.server then
self.server:close()
self.server = nil
end
return self.pasvt.ip, self.pasvt.port
end
function metat.__index:port(ip, port)
self.pasvt = nil
if not ip then
ip, port = self.try(self.tp:getcontrol():getsockname())
self.server = self.try(socket.bind(ip, 0))
ip, port = self.try(self.server:getsockname())
self.try(self.server:settimeout(TIMEOUT))
end
local pl = math.mod(port, 256)
local ph = (port - pl)/256
local arg = string.gsub(string.format("%s,%d,%d", ip, ph, pl), "%.", ",")
self.try(self.tp:command("port", arg))
self.try(self.tp:check("2.."))
return 1
end
function metat.__index:send(sendt)
self.try(self.pasvt or self.server, "need port or pasv first")
-- if there is a pasvt table, we already sent a PASV command
-- we just get the data connection into self.data
if self.pasvt then self:pasvconnect() end
-- get the transfer argument and command
local argument = sendt.argument or
url.unescape(string.gsub(sendt.path or "", "^[/\\]", ""))
if argument == "" then argument = nil end
local command = sendt.command or "stor"
-- send the transfer command and check the reply
self.try(self.tp:command(command, argument))
local code, reply = self.try(self.tp:check{"2..", "1.."})
-- if there is not a a pasvt table, then there is a server
-- and we already sent a PORT command
if not self.pasvt then self:portconnect() end
-- get the sink, source and step for the transfer
local step = sendt.step or ltn12.pump.step
local readt = {self.tp.c}
local checkstep = function(src, snk)
-- check status in control connection while downloading
local readyt = socket.select(readt, nil, 0)
if readyt[tp] then code = self.try(self.tp:check("2..")) end
return step(src, snk)
end
local sink = socket.sink("close-when-done", self.data)
-- transfer all data and check error
self.try(ltn12.pump.all(sendt.source, sink, checkstep))
if string.find(code, "1..") then self.try(self.tp:check("2..")) end
-- done with data connection
self.data:close()
-- find out how many bytes were sent
local sent = socket.skip(1, self.data:getstats())
self.data = nil
return sent
end
function metat.__index:receive(recvt)
self.try(self.pasvt or self.server, "need port or pasv first")
if self.pasvt then self:pasvconnect() end
local argument = recvt.argument or
url.unescape(string.gsub(recvt.path or "", "^[/\\]", ""))
if argument == "" then argument = nil end
local command = recvt.command or "retr"
self.try(self.tp:command(command, argument))
local code = self.try(self.tp:check{"1..", "2.."})
if not self.pasvt then self:portconnect() end
local source = socket.source("until-closed", self.data)
local step = recvt.step or ltn12.pump.step
self.try(ltn12.pump.all(source, recvt.sink, step))
if string.find(code, "1..") then self.try(self.tp:check("2..")) end
self.data:close()
self.data = nil
return 1
end
function metat.__index:cwd(dir)
self.try(self.tp:command("cwd", dir))
self.try(self.tp:check(250))
return 1
end
function metat.__index:type(type)
self.try(self.tp:command("type", type))
self.try(self.tp:check(200))
return 1
end
function metat.__index:greet()
local code = self.try(self.tp:check{"1..", "2.."})
if string.find(code, "1..") then self.try(self.tp:check("2..")) end
return 1
end
function metat.__index:quit()
self.try(self.tp:command("quit"))
self.try(self.tp:check("2.."))
return 1
end
function metat.__index:close()
if self.data then self.data:close() end
if self.server then self.server:close() end
return self.tp:close()
end
-----------------------------------------------------------------------------
-- High level FTP API
-----------------------------------------------------------------------------
local function override(t)
if t.url then
local u = url.parse(t.url)
for i,v in base.pairs(t) do
u[i] = v
end
return u
else return t end
end
local function tput(putt)
putt = override(putt)
socket.try(putt.host, "missing hostname")
local f = open(putt.host, putt.port, putt.create)
f:greet()
f:login(putt.user, putt.password)
if putt.type then f:type(putt.type) end
f:pasv()
local sent = f:send(putt)
f:quit()
f:close()
return sent
end
local default = {
path = "/",
scheme = "ftp"
}
local function parse(u)
local t = socket.try(url.parse(u, default))
socket.try(t.scheme == "ftp", "wrong scheme '" .. t.scheme .. "'")
socket.try(t.host, "missing hostname")
local pat = "^type=(.)$"
if t.params then
t.type = socket.skip(2, string.find(t.params, pat))
socket.try(t.type == "a" or t.type == "i",
"invalid type '" .. t.type .. "'")
end
return t
end
local function sput(u, body)
local putt = parse(u)
putt.source = ltn12.source.string(body)
return tput(putt)
end
put = socket.protect(function(putt, body)
if base.type(putt) == "string" then return sput(putt, body)
else return tput(putt) end
end)
local function tget(gett)
gett = override(gett)
socket.try(gett.host, "missing hostname")
local f = open(gett.host, gett.port, gett.create)
f:greet()
f:login(gett.user, gett.password)
if gett.type then f:type(gett.type) end
f:pasv()
f:receive(gett)
f:quit()
return f:close()
end
local function sget(u)
local gett = parse(u)
local t = {}
gett.sink = ltn12.sink.table(t)
tget(gett)
return table.concat(t)
end
command = socket.protect(function(cmdt)
cmdt = override(cmdt)
socket.try(cmdt.host, "missing hostname")
socket.try(cmdt.command, "missing command")
local f = open(cmdt.host, cmdt.port, cmdt.create)
f:greet()
f:login(cmdt.user, cmdt.password)
f.try(f.tp:command(cmdt.command, cmdt.argument))
if cmdt.check then f.try(f.tp:check(cmdt.check)) end
f:quit()
return f:close()
end)
get = socket.protect(function(gett)
if base.type(gett) == "string" then return sget(gett)
else return tget(gett) end
end)
@@ -0,0 +1,468 @@
/* code automatically generated by bin2c -- DO NOT EDIT */
{
/* #include'ing this file in a C program is equivalent to calling
if (luaL_loadfile(L,"ftp.lua")==0) lua_call(L, 0, 0);
*/
/* ftp.lua */
static const unsigned char B1[]={
45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45,
45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45,
45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45,
45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 10, 45, 45,
32, 70, 84, 80, 32,115,117,112,112,111,114,116, 32,102,111,114, 32,116,104,101,
32, 76,117, 97, 32,108, 97,110,103,117, 97,103,101, 10, 45, 45, 32, 76,117, 97,
83,111, 99,107,101,116, 32,116,111,111,108,107,105,116, 46, 10, 45, 45, 32, 65,
117,116,104,111,114, 58, 32, 68,105,101,103,111, 32, 78,101,104, 97, 98, 10, 45,
45, 32, 82, 67, 83, 32, 73, 68, 58, 32, 36, 73,100, 58, 32,102,116,112, 46,108,
117, 97, 44,118, 32, 49, 46, 52, 53, 32, 50, 48, 48, 55, 47, 48, 55, 47, 49, 49,
32, 49, 57, 58, 50, 53, 58, 52, 55, 32,100,105,101,103,111, 32, 69,120,112, 32,
36, 10, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45,
45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45,
45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45,
45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 10,
10, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45,
45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45,
45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45,
45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 10, 45,
45, 32, 68,101, 99,108, 97,114,101, 32,109,111,100,117,108,101, 32, 97,110,100,
32,105,109,112,111,114,116, 32,100,101,112,101,110,100,101,110, 99,105,101,115,
10, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45,
45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45,
45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45,
45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 10,108,
111, 99, 97,108, 32, 98, 97,115,101, 32, 61, 32, 95, 71, 10,108,111, 99, 97,108,
32,116, 97, 98,108,101, 32, 61, 32,114,101,113,117,105,114,101, 40, 34,116, 97,
98,108,101, 34, 41, 10,108,111, 99, 97,108, 32,115,116,114,105,110,103, 32, 61,
32,114,101,113,117,105,114,101, 40, 34,115,116,114,105,110,103, 34, 41, 10,108,
111, 99, 97,108, 32,109, 97,116,104, 32, 61, 32,114,101,113,117,105,114,101, 40,
34,109, 97,116,104, 34, 41, 10,108,111, 99, 97,108, 32,115,111, 99,107,101,116,
32, 61, 32,114,101,113,117,105,114,101, 40, 34,115,111, 99,107,101,116, 34, 41,
10,108,111, 99, 97,108, 32,117,114,108, 32, 61, 32,114,101,113,117,105,114,101,
40, 34,115,111, 99,107,101,116, 46,117,114,108, 34, 41, 10,108,111, 99, 97,108,
32,116,112, 32, 61, 32,114,101,113,117,105,114,101, 40, 34,115,111, 99,107,101,
116, 46,116,112, 34, 41, 10,108,111, 99, 97,108, 32,108,116,110, 49, 50, 32, 61,
32,114,101,113,117,105,114,101, 40, 34,108,116,110, 49, 50, 34, 41, 10,109,111,
100,117,108,101, 40, 34,115,111, 99,107,101,116, 46,102,116,112, 34, 41, 10, 10,
45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45,
45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45,
45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45,
45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 10, 45, 45,
32, 80,114,111,103,114, 97,109, 32, 99,111,110,115,116, 97,110,116,115, 10, 45,
45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45,
45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45,
45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45,
45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 10, 45, 45, 32,
116,105,109,101,111,117,116, 32,105,110, 32,115,101, 99,111,110,100,115, 32, 98,
101,102,111,114,101, 32,116,104,101, 32,112,114,111,103,114, 97,109, 32,103,105,
118,101,115, 32,117,112, 32,111,110, 32, 97, 32, 99,111,110,110,101, 99,116,105,
111,110, 10, 84, 73, 77, 69, 79, 85, 84, 32, 61, 32, 54, 48, 10, 45, 45, 32,100,
101,102, 97,117,108,116, 32,112,111,114,116, 32,102,111,114, 32,102,116,112, 32,
115,101,114,118,105, 99,101, 10, 80, 79, 82, 84, 32, 61, 32, 50, 49, 10, 45, 45,
32,116,104,105,115, 32,105,115, 32,116,104,101, 32,100,101,102, 97,117,108,116,
32, 97,110,111,110,121,109,111,117,115, 32,112, 97,115,115,119,111,114,100, 46,
32,117,115,101,100, 32,119,104,101,110, 32,110,111, 32,112, 97,115,115,119,111,
114,100, 32,105,115, 10, 45, 45, 32,112,114,111,118,105,100,101,100, 32,105,110,
32,117,114,108, 46, 32,115,104,111,117,108,100, 32, 98,101, 32, 99,104, 97,110,
103,101,100, 32,116,111, 32,121,111,117,114, 32,101, 45,109, 97,105,108, 46, 10,
85, 83, 69, 82, 32, 61, 32, 34,102,116,112, 34, 10, 80, 65, 83, 83, 87, 79, 82,
68, 32, 61, 32, 34, 97,110,111,110,121,109,111,117,115, 64, 97,110,111,110,121,
109,111,117,115, 46,111,114,103, 34, 10, 10, 45, 45, 45, 45, 45, 45, 45, 45, 45,
45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45,
45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45,
45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45,
45, 45, 45, 45, 45, 45, 45, 45, 10, 45, 45, 32, 76,111,119, 32,108,101,118,101,
108, 32, 70, 84, 80, 32, 65, 80, 73, 10, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45,
45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45,
45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45,
45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45,
45, 45, 45, 45, 45, 45, 45, 10,108,111, 99, 97,108, 32,109,101,116, 97,116, 32,
61, 32,123, 32, 95, 95,105,110,100,101,120, 32, 61, 32,123,125, 32,125, 10, 10,
102,117,110, 99,116,105,111,110, 32,111,112,101,110, 40,115,101,114,118,101,114,
44, 32,112,111,114,116, 44, 32, 99,114,101, 97,116,101, 41, 10, 32, 32, 32, 32,
108,111, 99, 97,108, 32,116,112, 32, 61, 32,115,111, 99,107,101,116, 46,116,114,
121, 40,116,112, 46, 99,111,110,110,101, 99,116, 40,115,101,114,118,101,114, 44,
32,112,111,114,116, 32,111,114, 32, 80, 79, 82, 84, 44, 32, 84, 73, 77, 69, 79,
85, 84, 44, 32, 99,114,101, 97,116,101, 41, 41, 10, 32, 32, 32, 32,108,111, 99,
97,108, 32,102, 32, 61, 32, 98, 97,115,101, 46,115,101,116,109,101,116, 97,116,
97, 98,108,101, 40,123, 32,116,112, 32, 61, 32,116,112, 32,125, 44, 32,109,101,
116, 97,116, 41, 10, 32, 32, 32, 32, 45, 45, 32,109, 97,107,101, 32,115,117,114,
101, 32,101,118,101,114,121,116,104,105,110,103, 32,103,101,116,115, 32, 99,108,
111,115,101,100, 32,105,110, 32, 97,110, 32,101,120, 99,101,112,116,105,111,110,
10, 32, 32, 32, 32,102, 46,116,114,121, 32, 61, 32,115,111, 99,107,101,116, 46,
110,101,119,116,114,121, 40,102,117,110, 99,116,105,111,110, 40, 41, 32,102, 58,
99,108,111,115,101, 40, 41, 32,101,110,100, 41, 10, 32, 32, 32, 32,114,101,116,
117,114,110, 32,102, 10,101,110,100, 10, 10,102,117,110, 99,116,105,111,110, 32,
109,101,116, 97,116, 46, 95, 95,105,110,100,101,120, 58,112,111,114,116, 99,111,
110,110,101, 99,116, 40, 41, 10, 32, 32, 32, 32,115,101,108,102, 46,116,114,121,
40,115,101,108,102, 46,115,101,114,118,101,114, 58,115,101,116,116,105,109,101,
111,117,116, 40, 84, 73, 77, 69, 79, 85, 84, 41, 41, 10, 32, 32, 32, 32,115,101,
108,102, 46,100, 97,116, 97, 32, 61, 32,115,101,108,102, 46,116,114,121, 40,115,
101,108,102, 46,115,101,114,118,101,114, 58, 97, 99, 99,101,112,116, 40, 41, 41,
10, 32, 32, 32, 32,115,101,108,102, 46,116,114,121, 40,115,101,108,102, 46,100,
97,116, 97, 58,115,101,116,116,105,109,101,111,117,116, 40, 84, 73, 77, 69, 79,
85, 84, 41, 41, 10,101,110,100, 10, 10,102,117,110, 99,116,105,111,110, 32,109,
101,116, 97,116, 46, 95, 95,105,110,100,101,120, 58,112, 97,115,118, 99,111,110,
110,101, 99,116, 40, 41, 10, 32, 32, 32, 32,115,101,108,102, 46,100, 97,116, 97,
32, 61, 32,115,101,108,102, 46,116,114,121, 40,115,111, 99,107,101,116, 46,116,
99,112, 40, 41, 41, 10, 32, 32, 32, 32,115,101,108,102, 46,116,114,121, 40,115,
101,108,102, 46,100, 97,116, 97, 58,115,101,116,116,105,109,101,111,117,116, 40,
84, 73, 77, 69, 79, 85, 84, 41, 41, 10, 32, 32, 32, 32,115,101,108,102, 46,116,
114,121, 40,115,101,108,102, 46,100, 97,116, 97, 58, 99,111,110,110,101, 99,116,
40,115,101,108,102, 46,112, 97,115,118,116, 46,105,112, 44, 32,115,101,108,102,
46,112, 97,115,118,116, 46,112,111,114,116, 41, 41, 10,101,110,100, 10, 10,102,
117,110, 99,116,105,111,110, 32,109,101,116, 97,116, 46, 95, 95,105,110,100,101,
120, 58,108,111,103,105,110, 40,117,115,101,114, 44, 32,112, 97,115,115,119,111,
114,100, 41, 10, 32, 32, 32, 32,115,101,108,102, 46,116,114,121, 40,115,101,108,
102, 46,116,112, 58, 99,111,109,109, 97,110,100, 40, 34,117,115,101,114, 34, 44,
32,117,115,101,114, 32,111,114, 32, 85, 83, 69, 82, 41, 41, 10, 32, 32, 32, 32,
108,111, 99, 97,108, 32, 99,111,100,101, 44, 32,114,101,112,108,121, 32, 61, 32,
115,101,108,102, 46,116,114,121, 40,115,101,108,102, 46,116,112, 58, 99,104,101,
99,107,123, 34, 50, 46, 46, 34, 44, 32, 51, 51, 49,125, 41, 10, 32, 32, 32, 32,
105,102, 32, 99,111,100,101, 32, 61, 61, 32, 51, 51, 49, 32,116,104,101,110, 10,
32, 32, 32, 32, 32, 32, 32, 32,115,101,108,102, 46,116,114,121, 40,115,101,108,
102, 46,116,112, 58, 99,111,109,109, 97,110,100, 40, 34,112, 97,115,115, 34, 44,
32,112, 97,115,115,119,111,114,100, 32,111,114, 32, 80, 65, 83, 83, 87, 79, 82,
68, 41, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32,115,101,108,102, 46,116,114,121,
40,115,101,108,102, 46,116,112, 58, 99,104,101, 99,107, 40, 34, 50, 46, 46, 34,
41, 41, 10, 32, 32, 32, 32,101,110,100, 10, 32, 32, 32, 32,114,101,116,117,114,
110, 32, 49, 10,101,110,100, 10, 10,102,117,110, 99,116,105,111,110, 32,109,101,
116, 97,116, 46, 95, 95,105,110,100,101,120, 58,112, 97,115,118, 40, 41, 10, 32,
32, 32, 32,115,101,108,102, 46,116,114,121, 40,115,101,108,102, 46,116,112, 58,
99,111,109,109, 97,110,100, 40, 34,112, 97,115,118, 34, 41, 41, 10, 32, 32, 32,
32,108,111, 99, 97,108, 32, 99,111,100,101, 44, 32,114,101,112,108,121, 32, 61,
32,115,101,108,102, 46,116,114,121, 40,115,101,108,102, 46,116,112, 58, 99,104,
101, 99,107, 40, 34, 50, 46, 46, 34, 41, 41, 10, 32, 32, 32, 32,108,111, 99, 97,
108, 32,112, 97,116,116,101,114,110, 32, 61, 32, 34, 40, 37,100, 43, 41, 37, 68,
40, 37,100, 43, 41, 37, 68, 40, 37,100, 43, 41, 37, 68, 40, 37,100, 43, 41, 37,
68, 40, 37,100, 43, 41, 37, 68, 40, 37,100, 43, 41, 34, 10, 32, 32, 32, 32,108,
111, 99, 97,108, 32, 97, 44, 32, 98, 44, 32, 99, 44, 32,100, 44, 32,112, 49, 44,
32,112, 50, 32, 61, 32,115,111, 99,107,101,116, 46,115,107,105,112, 40, 50, 44,
32,115,116,114,105,110,103, 46,102,105,110,100, 40,114,101,112,108,121, 44, 32,
112, 97,116,116,101,114,110, 41, 41, 10, 32, 32, 32, 32,115,101,108,102, 46,116,
114,121, 40, 97, 32, 97,110,100, 32, 98, 32, 97,110,100, 32, 99, 32, 97,110,100,
32,100, 32, 97,110,100, 32,112, 49, 32, 97,110,100, 32,112, 50, 44, 32,114,101,
112,108,121, 41, 10, 32, 32, 32, 32,115,101,108,102, 46,112, 97,115,118,116, 32,
61, 32,123, 10, 32, 32, 32, 32, 32, 32, 32, 32,105,112, 32, 61, 32,115,116,114,
105,110,103, 46,102,111,114,109, 97,116, 40, 34, 37,100, 46, 37,100, 46, 37,100,
46, 37,100, 34, 44, 32, 97, 44, 32, 98, 44, 32, 99, 44, 32,100, 41, 44, 10, 32,
32, 32, 32, 32, 32, 32, 32,112,111,114,116, 32, 61, 32,112, 49, 42, 50, 53, 54,
32, 43, 32,112, 50, 10, 32, 32, 32, 32,125, 10, 32, 32, 32, 32,105,102, 32,115,
101,108,102, 46,115,101,114,118,101,114, 32,116,104,101,110, 10, 32, 32, 32, 32,
32, 32, 32, 32,115,101,108,102, 46,115,101,114,118,101,114, 58, 99,108,111,115,
101, 40, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32,115,101,108,102, 46,115,101,114,
118,101,114, 32, 61, 32,110,105,108, 10, 32, 32, 32, 32,101,110,100, 10, 32, 32,
32, 32,114,101,116,117,114,110, 32,115,101,108,102, 46,112, 97,115,118,116, 46,
105,112, 44, 32,115,101,108,102, 46,112, 97,115,118,116, 46,112,111,114,116, 10,
101,110,100, 10, 10,102,117,110, 99,116,105,111,110, 32,109,101,116, 97,116, 46,
95, 95,105,110,100,101,120, 58,112,111,114,116, 40,105,112, 44, 32,112,111,114,
116, 41, 10, 32, 32, 32, 32,115,101,108,102, 46,112, 97,115,118,116, 32, 61, 32,
110,105,108, 10, 32, 32, 32, 32,105,102, 32,110,111,116, 32,105,112, 32,116,104,
101,110, 10, 32, 32, 32, 32, 32, 32, 32, 32,105,112, 44, 32,112,111,114,116, 32,
61, 32,115,101,108,102, 46,116,114,121, 40,115,101,108,102, 46,116,112, 58,103,
101,116, 99,111,110,116,114,111,108, 40, 41, 58,103,101,116,115,111, 99,107,110,
97,109,101, 40, 41, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32,115,101,108,102, 46,
115,101,114,118,101,114, 32, 61, 32,115,101,108,102, 46,116,114,121, 40,115,111,
99,107,101,116, 46, 98,105,110,100, 40,105,112, 44, 32, 48, 41, 41, 10, 32, 32,
32, 32, 32, 32, 32, 32,105,112, 44, 32,112,111,114,116, 32, 61, 32,115,101,108,
102, 46,116,114,121, 40,115,101,108,102, 46,115,101,114,118,101,114, 58,103,101,
116,115,111, 99,107,110, 97,109,101, 40, 41, 41, 10, 32, 32, 32, 32, 32, 32, 32,
32,115,101,108,102, 46,116,114,121, 40,115,101,108,102, 46,115,101,114,118,101,
114, 58,115,101,116,116,105,109,101,111,117,116, 40, 84, 73, 77, 69, 79, 85, 84,
41, 41, 10, 32, 32, 32, 32,101,110,100, 10, 32, 32, 32, 32,108,111, 99, 97,108,
32,112,108, 32, 61, 32,109, 97,116,104, 46,109,111,100, 40,112,111,114,116, 44,
32, 50, 53, 54, 41, 10, 32, 32, 32, 32,108,111, 99, 97,108, 32,112,104, 32, 61,
32, 40,112,111,114,116, 32, 45, 32,112,108, 41, 47, 50, 53, 54, 10, 32, 32, 32,
32,108,111, 99, 97,108, 32, 97,114,103, 32, 61, 32,115,116,114,105,110,103, 46,
103,115,117, 98, 40,115,116,114,105,110,103, 46,102,111,114,109, 97,116, 40, 34,
37,115, 44, 37,100, 44, 37,100, 34, 44, 32,105,112, 44, 32,112,104, 44, 32,112,
108, 41, 44, 32, 34, 37, 46, 34, 44, 32, 34, 44, 34, 41, 10, 32, 32, 32, 32,115,
101,108,102, 46,116,114,121, 40,115,101,108,102, 46,116,112, 58, 99,111,109,109,
97,110,100, 40, 34,112,111,114,116, 34, 44, 32, 97,114,103, 41, 41, 10, 32, 32,
32, 32,115,101,108,102, 46,116,114,121, 40,115,101,108,102, 46,116,112, 58, 99,
104,101, 99,107, 40, 34, 50, 46, 46, 34, 41, 41, 10, 32, 32, 32, 32,114,101,116,
117,114,110, 32, 49, 10,101,110,100, 10, 10,102,117,110, 99,116,105,111,110, 32,
109,101,116, 97,116, 46, 95, 95,105,110,100,101,120, 58,115,101,110,100, 40,115,
101,110,100,116, 41, 10, 32, 32, 32, 32,115,101,108,102, 46,116,114,121, 40,115,
101,108,102, 46,112, 97,115,118,116, 32,111,114, 32,115,101,108,102, 46,115,101,
114,118,101,114, 44, 32, 34,110,101,101,100, 32,112,111,114,116, 32,111,114, 32,
112, 97,115,118, 32,102,105,114,115,116, 34, 41, 10, 32, 32, 32, 32, 45, 45, 32,
105,102, 32,116,104,101,114,101, 32,105,115, 32, 97, 32,112, 97,115,118,116, 32,
116, 97, 98,108,101, 44, 32,119,101, 32, 97,108,114,101, 97,100,121, 32,115,101,
110,116, 32, 97, 32, 80, 65, 83, 86, 32, 99,111,109,109, 97,110,100, 10, 32, 32,
32, 32, 45, 45, 32,119,101, 32,106,117,115,116, 32,103,101,116, 32,116,104,101,
32,100, 97,116, 97, 32, 99,111,110,110,101, 99,116,105,111,110, 32,105,110,116,
111, 32,115,101,108,102, 46,100, 97,116, 97, 10, 32, 32, 32, 32,105,102, 32,115,
101,108,102, 46,112, 97,115,118,116, 32,116,104,101,110, 32,115,101,108,102, 58,
112, 97,115,118, 99,111,110,110,101, 99,116, 40, 41, 32,101,110,100, 10, 32, 32,
32, 32, 45, 45, 32,103,101,116, 32,116,104,101, 32,116,114, 97,110,115,102,101,
114, 32, 97,114,103,117,109,101,110,116, 32, 97,110,100, 32, 99,111,109,109, 97,
110,100, 10, 32, 32, 32, 32,108,111, 99, 97,108, 32, 97,114,103,117,109,101,110,
116, 32, 61, 32,115,101,110,100,116, 46, 97,114,103,117,109,101,110,116, 32,111,
114, 10, 32, 32, 32, 32, 32, 32, 32, 32,117,114,108, 46,117,110,101,115, 99, 97,
112,101, 40,115,116,114,105,110,103, 46,103,115,117, 98, 40,115,101,110,100,116,
46,112, 97,116,104, 32,111,114, 32, 34, 34, 44, 32, 34, 94, 91, 47, 92, 92, 93,
34, 44, 32, 34, 34, 41, 41, 10, 32, 32, 32, 32,105,102, 32, 97,114,103,117,109,
101,110,116, 32, 61, 61, 32, 34, 34, 32,116,104,101,110, 32, 97,114,103,117,109,
101,110,116, 32, 61, 32,110,105,108, 32,101,110,100, 10, 32, 32, 32, 32,108,111,
99, 97,108, 32, 99,111,109,109, 97,110,100, 32, 61, 32,115,101,110,100,116, 46,
99,111,109,109, 97,110,100, 32,111,114, 32, 34,115,116,111,114, 34, 10, 32, 32,
32, 32, 45, 45, 32,115,101,110,100, 32,116,104,101, 32,116,114, 97,110,115,102,
101,114, 32, 99,111,109,109, 97,110,100, 32, 97,110,100, 32, 99,104,101, 99,107,
32,116,104,101, 32,114,101,112,108,121, 10, 32, 32, 32, 32,115,101,108,102, 46,
116,114,121, 40,115,101,108,102, 46,116,112, 58, 99,111,109,109, 97,110,100, 40,
99,111,109,109, 97,110,100, 44, 32, 97,114,103,117,109,101,110,116, 41, 41, 10,
32, 32, 32, 32,108,111, 99, 97,108, 32, 99,111,100,101, 44, 32,114,101,112,108,
121, 32, 61, 32,115,101,108,102, 46,116,114,121, 40,115,101,108,102, 46,116,112,
58, 99,104,101, 99,107,123, 34, 50, 46, 46, 34, 44, 32, 34, 49, 46, 46, 34,125,
41, 10, 32, 32, 32, 32, 45, 45, 32,105,102, 32,116,104,101,114,101, 32,105,115,
32,110,111,116, 32, 97, 32, 97, 32,112, 97,115,118,116, 32,116, 97, 98,108,101,
44, 32,116,104,101,110, 32,116,104,101,114,101, 32,105,115, 32, 97, 32,115,101,
114,118,101,114, 10, 32, 32, 32, 32, 45, 45, 32, 97,110,100, 32,119,101, 32, 97,
108,114,101, 97,100,121, 32,115,101,110,116, 32, 97, 32, 80, 79, 82, 84, 32, 99,
111,109,109, 97,110,100, 10, 32, 32, 32, 32,105,102, 32,110,111,116, 32,115,101,
108,102, 46,112, 97,115,118,116, 32,116,104,101,110, 32,115,101,108,102, 58,112,
111,114,116, 99,111,110,110,101, 99,116, 40, 41, 32,101,110,100, 10, 32, 32, 32,
32, 45, 45, 32,103,101,116, 32,116,104,101, 32,115,105,110,107, 44, 32,115,111,
117,114, 99,101, 32, 97,110,100, 32,115,116,101,112, 32,102,111,114, 32,116,104,
101, 32,116,114, 97,110,115,102,101,114, 10, 32, 32, 32, 32,108,111, 99, 97,108,
32,115,116,101,112, 32, 61, 32,115,101,110,100,116, 46,115,116,101,112, 32,111,
114, 32,108,116,110, 49, 50, 46,112,117,109,112, 46,115,116,101,112, 10, 32, 32,
32, 32,108,111, 99, 97,108, 32,114,101, 97,100,116, 32, 61, 32,123,115,101,108,
102, 46,116,112, 46, 99,125, 10, 32, 32, 32, 32,108,111, 99, 97,108, 32, 99,104,
101, 99,107,115,116,101,112, 32, 61, 32,102,117,110, 99,116,105,111,110, 40,115,
114, 99, 44, 32,115,110,107, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 45, 45, 32,
99,104,101, 99,107, 32,115,116, 97,116,117,115, 32,105,110, 32, 99,111,110,116,
114,111,108, 32, 99,111,110,110,101, 99,116,105,111,110, 32,119,104,105,108,101,
32,100,111,119,110,108,111, 97,100,105,110,103, 10, 32, 32, 32, 32, 32, 32, 32,
32,108,111, 99, 97,108, 32,114,101, 97,100,121,116, 32, 61, 32,115,111, 99,107,
101,116, 46,115,101,108,101, 99,116, 40,114,101, 97,100,116, 44, 32,110,105,108,
44, 32, 48, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32,105,102, 32,114,101, 97,100,
121,116, 91,116,112, 93, 32,116,104,101,110, 32, 99,111,100,101, 32, 61, 32,115,
101,108,102, 46,116,114,121, 40,115,101,108,102, 46,116,112, 58, 99,104,101, 99,
107, 40, 34, 50, 46, 46, 34, 41, 41, 32,101,110,100, 10, 32, 32, 32, 32, 32, 32,
32, 32,114,101,116,117,114,110, 32,115,116,101,112, 40,115,114, 99, 44, 32,115,
110,107, 41, 10, 32, 32, 32, 32,101,110,100, 10, 32, 32, 32, 32,108,111, 99, 97,
108, 32,115,105,110,107, 32, 61, 32,115,111, 99,107,101,116, 46,115,105,110,107,
40, 34, 99,108,111,115,101, 45,119,104,101,110, 45,100,111,110,101, 34, 44, 32,
115,101,108,102, 46,100, 97,116, 97, 41, 10, 32, 32, 32, 32, 45, 45, 32,116,114,
97,110,115,102,101,114, 32, 97,108,108, 32,100, 97,116, 97, 32, 97,110,100, 32,
99,104,101, 99,107, 32,101,114,114,111,114, 10, 32, 32, 32, 32,115,101,108,102,
46,116,114,121, 40,108,116,110, 49, 50, 46,112,117,109,112, 46, 97,108,108, 40,
115,101,110,100,116, 46,115,111,117,114, 99,101, 44, 32,115,105,110,107, 44, 32,
99,104,101, 99,107,115,116,101,112, 41, 41, 10, 32, 32, 32, 32,105,102, 32,115,
116,114,105,110,103, 46,102,105,110,100, 40, 99,111,100,101, 44, 32, 34, 49, 46,
46, 34, 41, 32,116,104,101,110, 32,115,101,108,102, 46,116,114,121, 40,115,101,
108,102, 46,116,112, 58, 99,104,101, 99,107, 40, 34, 50, 46, 46, 34, 41, 41, 32,
101,110,100, 10, 32, 32, 32, 32, 45, 45, 32,100,111,110,101, 32,119,105,116,104,
32,100, 97,116, 97, 32, 99,111,110,110,101, 99,116,105,111,110, 10, 32, 32, 32,
32,115,101,108,102, 46,100, 97,116, 97, 58, 99,108,111,115,101, 40, 41, 10, 32,
32, 32, 32, 45, 45, 32,102,105,110,100, 32,111,117,116, 32,104,111,119, 32,109,
97,110,121, 32, 98,121,116,101,115, 32,119,101,114,101, 32,115,101,110,116, 10,
32, 32, 32, 32,108,111, 99, 97,108, 32,115,101,110,116, 32, 61, 32,115,111, 99,
107,101,116, 46,115,107,105,112, 40, 49, 44, 32,115,101,108,102, 46,100, 97,116,
97, 58,103,101,116,115,116, 97,116,115, 40, 41, 41, 10, 32, 32, 32, 32,115,101,
108,102, 46,100, 97,116, 97, 32, 61, 32,110,105,108, 10, 32, 32, 32, 32,114,101,
116,117,114,110, 32,115,101,110,116, 10,101,110,100, 10, 10,102,117,110, 99,116,
105,111,110, 32,109,101,116, 97,116, 46, 95, 95,105,110,100,101,120, 58,114,101,
99,101,105,118,101, 40,114,101, 99,118,116, 41, 10, 32, 32, 32, 32,115,101,108,
102, 46,116,114,121, 40,115,101,108,102, 46,112, 97,115,118,116, 32,111,114, 32,
115,101,108,102, 46,115,101,114,118,101,114, 44, 32, 34,110,101,101,100, 32,112,
111,114,116, 32,111,114, 32,112, 97,115,118, 32,102,105,114,115,116, 34, 41, 10,
32, 32, 32, 32,105,102, 32,115,101,108,102, 46,112, 97,115,118,116, 32,116,104,
101,110, 32,115,101,108,102, 58,112, 97,115,118, 99,111,110,110,101, 99,116, 40,
41, 32,101,110,100, 10, 32, 32, 32, 32,108,111, 99, 97,108, 32, 97,114,103,117,
109,101,110,116, 32, 61, 32,114,101, 99,118,116, 46, 97,114,103,117,109,101,110,
116, 32,111,114, 10, 32, 32, 32, 32, 32, 32, 32, 32,117,114,108, 46,117,110,101,
115, 99, 97,112,101, 40,115,116,114,105,110,103, 46,103,115,117, 98, 40,114,101,
99,118,116, 46,112, 97,116,104, 32,111,114, 32, 34, 34, 44, 32, 34, 94, 91, 47,
92, 92, 93, 34, 44, 32, 34, 34, 41, 41, 10, 32, 32, 32, 32,105,102, 32, 97,114,
103,117,109,101,110,116, 32, 61, 61, 32, 34, 34, 32,116,104,101,110, 32, 97,114,
103,117,109,101,110,116, 32, 61, 32,110,105,108, 32,101,110,100, 10, 32, 32, 32,
32,108,111, 99, 97,108, 32, 99,111,109,109, 97,110,100, 32, 61, 32,114,101, 99,
118,116, 46, 99,111,109,109, 97,110,100, 32,111,114, 32, 34,114,101,116,114, 34,
10, 32, 32, 32, 32,115,101,108,102, 46,116,114,121, 40,115,101,108,102, 46,116,
112, 58, 99,111,109,109, 97,110,100, 40, 99,111,109,109, 97,110,100, 44, 32, 97,
114,103,117,109,101,110,116, 41, 41, 10, 32, 32, 32, 32,108,111, 99, 97,108, 32,
99,111,100,101, 32, 61, 32,115,101,108,102, 46,116,114,121, 40,115,101,108,102,
46,116,112, 58, 99,104,101, 99,107,123, 34, 49, 46, 46, 34, 44, 32, 34, 50, 46,
46, 34,125, 41, 10, 32, 32, 32, 32,105,102, 32,110,111,116, 32,115,101,108,102,
46,112, 97,115,118,116, 32,116,104,101,110, 32,115,101,108,102, 58,112,111,114,
116, 99,111,110,110,101, 99,116, 40, 41, 32,101,110,100, 10, 32, 32, 32, 32,108,
111, 99, 97,108, 32,115,111,117,114, 99,101, 32, 61, 32,115,111, 99,107,101,116,
46,115,111,117,114, 99,101, 40, 34,117,110,116,105,108, 45, 99,108,111,115,101,
100, 34, 44, 32,115,101,108,102, 46,100, 97,116, 97, 41, 10, 32, 32, 32, 32,108,
111, 99, 97,108, 32,115,116,101,112, 32, 61, 32,114,101, 99,118,116, 46,115,116,
101,112, 32,111,114, 32,108,116,110, 49, 50, 46,112,117,109,112, 46,115,116,101,
112, 10, 32, 32, 32, 32,115,101,108,102, 46,116,114,121, 40,108,116,110, 49, 50,
46,112,117,109,112, 46, 97,108,108, 40,115,111,117,114, 99,101, 44, 32,114,101,
99,118,116, 46,115,105,110,107, 44, 32,115,116,101,112, 41, 41, 10, 32, 32, 32,
32,105,102, 32,115,116,114,105,110,103, 46,102,105,110,100, 40, 99,111,100,101,
44, 32, 34, 49, 46, 46, 34, 41, 32,116,104,101,110, 32,115,101,108,102, 46,116,
114,121, 40,115,101,108,102, 46,116,112, 58, 99,104,101, 99,107, 40, 34, 50, 46,
46, 34, 41, 41, 32,101,110,100, 10, 32, 32, 32, 32,115,101,108,102, 46,100, 97,
116, 97, 58, 99,108,111,115,101, 40, 41, 10, 32, 32, 32, 32,115,101,108,102, 46,
100, 97,116, 97, 32, 61, 32,110,105,108, 10, 32, 32, 32, 32,114,101,116,117,114,
110, 32, 49, 10,101,110,100, 10, 10,102,117,110, 99,116,105,111,110, 32,109,101,
116, 97,116, 46, 95, 95,105,110,100,101,120, 58, 99,119,100, 40,100,105,114, 41,
10, 32, 32, 32, 32,115,101,108,102, 46,116,114,121, 40,115,101,108,102, 46,116,
112, 58, 99,111,109,109, 97,110,100, 40, 34, 99,119,100, 34, 44, 32,100,105,114,
41, 41, 10, 32, 32, 32, 32,115,101,108,102, 46,116,114,121, 40,115,101,108,102,
46,116,112, 58, 99,104,101, 99,107, 40, 50, 53, 48, 41, 41, 10, 32, 32, 32, 32,
114,101,116,117,114,110, 32, 49, 10,101,110,100, 10, 10,102,117,110, 99,116,105,
111,110, 32,109,101,116, 97,116, 46, 95, 95,105,110,100,101,120, 58,116,121,112,
101, 40,116,121,112,101, 41, 10, 32, 32, 32, 32,115,101,108,102, 46,116,114,121,
40,115,101,108,102, 46,116,112, 58, 99,111,109,109, 97,110,100, 40, 34,116,121,
112,101, 34, 44, 32,116,121,112,101, 41, 41, 10, 32, 32, 32, 32,115,101,108,102,
46,116,114,121, 40,115,101,108,102, 46,116,112, 58, 99,104,101, 99,107, 40, 50,
48, 48, 41, 41, 10, 32, 32, 32, 32,114,101,116,117,114,110, 32, 49, 10,101,110,
100, 10, 10,102,117,110, 99,116,105,111,110, 32,109,101,116, 97,116, 46, 95, 95,
105,110,100,101,120, 58,103,114,101,101,116, 40, 41, 10, 32, 32, 32, 32,108,111,
99, 97,108, 32, 99,111,100,101, 32, 61, 32,115,101,108,102, 46,116,114,121, 40,
115,101,108,102, 46,116,112, 58, 99,104,101, 99,107,123, 34, 49, 46, 46, 34, 44,
32, 34, 50, 46, 46, 34,125, 41, 10, 32, 32, 32, 32,105,102, 32,115,116,114,105,
110,103, 46,102,105,110,100, 40, 99,111,100,101, 44, 32, 34, 49, 46, 46, 34, 41,
32,116,104,101,110, 32,115,101,108,102, 46,116,114,121, 40,115,101,108,102, 46,
116,112, 58, 99,104,101, 99,107, 40, 34, 50, 46, 46, 34, 41, 41, 32,101,110,100,
10, 32, 32, 32, 32,114,101,116,117,114,110, 32, 49, 10,101,110,100, 10, 10,102,
117,110, 99,116,105,111,110, 32,109,101,116, 97,116, 46, 95, 95,105,110,100,101,
120, 58,113,117,105,116, 40, 41, 10, 32, 32, 32, 32,115,101,108,102, 46,116,114,
121, 40,115,101,108,102, 46,116,112, 58, 99,111,109,109, 97,110,100, 40, 34,113,
117,105,116, 34, 41, 41, 10, 32, 32, 32, 32,115,101,108,102, 46,116,114,121, 40,
115,101,108,102, 46,116,112, 58, 99,104,101, 99,107, 40, 34, 50, 46, 46, 34, 41,
41, 10, 32, 32, 32, 32,114,101,116,117,114,110, 32, 49, 10,101,110,100, 10, 10,
102,117,110, 99,116,105,111,110, 32,109,101,116, 97,116, 46, 95, 95,105,110,100,
101,120, 58, 99,108,111,115,101, 40, 41, 10, 32, 32, 32, 32,105,102, 32,115,101,
108,102, 46,100, 97,116, 97, 32,116,104,101,110, 32,115,101,108,102, 46,100, 97,
116, 97, 58, 99,108,111,115,101, 40, 41, 32,101,110,100, 10, 32, 32, 32, 32,105,
102, 32,115,101,108,102, 46,115,101,114,118,101,114, 32,116,104,101,110, 32,115,
101,108,102, 46,115,101,114,118,101,114, 58, 99,108,111,115,101, 40, 41, 32,101,
110,100, 10, 32, 32, 32, 32,114,101,116,117,114,110, 32,115,101,108,102, 46,116,
112, 58, 99,108,111,115,101, 40, 41, 10,101,110,100, 10, 10, 45, 45, 45, 45, 45,
45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45,
45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45,
45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45,
45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 10, 45, 45, 32, 72,105,103,104,
32,108,101,118,101,108, 32, 70, 84, 80, 32, 65, 80, 73, 10, 45, 45, 45, 45, 45,
45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45,
45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45,
45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45,
45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 10,108,111, 99, 97,108, 32,102,
117,110, 99,116,105,111,110, 32,111,118,101,114,114,105,100,101, 40,116, 41, 10,
32, 32, 32, 32,105,102, 32,116, 46,117,114,108, 32,116,104,101,110, 10, 32, 32,
32, 32, 32, 32, 32, 32,108,111, 99, 97,108, 32,117, 32, 61, 32,117,114,108, 46,
112, 97,114,115,101, 40,116, 46,117,114,108, 41, 10, 32, 32, 32, 32, 32, 32, 32,
32,102,111,114, 32,105, 44,118, 32,105,110, 32, 98, 97,115,101, 46,112, 97,105,
114,115, 40,116, 41, 32,100,111, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
32,117, 91,105, 93, 32, 61, 32,118, 10, 32, 32, 32, 32, 32, 32, 32, 32,101,110,
100, 10, 32, 32, 32, 32, 32, 32, 32, 32,114,101,116,117,114,110, 32,117, 10, 32,
32, 32, 32,101,108,115,101, 32,114,101,116,117,114,110, 32,116, 32,101,110,100,
10,101,110,100, 10, 10,108,111, 99, 97,108, 32,102,117,110, 99,116,105,111,110,
32,116,112,117,116, 40,112,117,116,116, 41, 10, 32, 32, 32, 32,112,117,116,116,
32, 61, 32,111,118,101,114,114,105,100,101, 40,112,117,116,116, 41, 10, 32, 32,
32, 32,115,111, 99,107,101,116, 46,116,114,121, 40,112,117,116,116, 46,104,111,
115,116, 44, 32, 34,109,105,115,115,105,110,103, 32,104,111,115,116,110, 97,109,
101, 34, 41, 10, 32, 32, 32, 32,108,111, 99, 97,108, 32,102, 32, 61, 32,111,112,
101,110, 40,112,117,116,116, 46,104,111,115,116, 44, 32,112,117,116,116, 46,112,
111,114,116, 44, 32,112,117,116,116, 46, 99,114,101, 97,116,101, 41, 10, 32, 32,
32, 32,102, 58,103,114,101,101,116, 40, 41, 10, 32, 32, 32, 32,102, 58,108,111,
103,105,110, 40,112,117,116,116, 46,117,115,101,114, 44, 32,112,117,116,116, 46,
112, 97,115,115,119,111,114,100, 41, 10, 32, 32, 32, 32,105,102, 32,112,117,116,
116, 46,116,121,112,101, 32,116,104,101,110, 32,102, 58,116,121,112,101, 40,112,
117,116,116, 46,116,121,112,101, 41, 32,101,110,100, 10, 32, 32, 32, 32,102, 58,
112, 97,115,118, 40, 41, 10, 32, 32, 32, 32,108,111, 99, 97,108, 32,115,101,110,
116, 32, 61, 32,102, 58,115,101,110,100, 40,112,117,116,116, 41, 10, 32, 32, 32,
32,102, 58,113,117,105,116, 40, 41, 10, 32, 32, 32, 32,102, 58, 99,108,111,115,
101, 40, 41, 10, 32, 32, 32, 32,114,101,116,117,114,110, 32,115,101,110,116, 10,
101,110,100, 10, 10,108,111, 99, 97,108, 32,100,101,102, 97,117,108,116, 32, 61,
32,123, 10, 9,112, 97,116,104, 32, 61, 32, 34, 47, 34, 44, 10, 9,115, 99,104,
101,109,101, 32, 61, 32, 34,102,116,112, 34, 10,125, 10, 10,108,111, 99, 97,108,
32,102,117,110, 99,116,105,111,110, 32,112, 97,114,115,101, 40,117, 41, 10, 32,
32, 32, 32,108,111, 99, 97,108, 32,116, 32, 61, 32,115,111, 99,107,101,116, 46,
116,114,121, 40,117,114,108, 46,112, 97,114,115,101, 40,117, 44, 32,100,101,102,
97,117,108,116, 41, 41, 10, 32, 32, 32, 32,115,111, 99,107,101,116, 46,116,114,
121, 40,116, 46,115, 99,104,101,109,101, 32, 61, 61, 32, 34,102,116,112, 34, 44,
32, 34,119,114,111,110,103, 32,115, 99,104,101,109,101, 32, 39, 34, 32, 46, 46,
32,116, 46,115, 99,104,101,109,101, 32, 46, 46, 32, 34, 39, 34, 41, 10, 32, 32,
32, 32,115,111, 99,107,101,116, 46,116,114,121, 40,116, 46,104,111,115,116, 44,
32, 34,109,105,115,115,105,110,103, 32,104,111,115,116,110, 97,109,101, 34, 41,
10, 32, 32, 32, 32,108,111, 99, 97,108, 32,112, 97,116, 32, 61, 32, 34, 94,116,
121,112,101, 61, 40, 46, 41, 36, 34, 10, 32, 32, 32, 32,105,102, 32,116, 46,112,
97,114, 97,109,115, 32,116,104,101,110, 10, 32, 32, 32, 32, 32, 32, 32, 32,116,
46,116,121,112,101, 32, 61, 32,115,111, 99,107,101,116, 46,115,107,105,112, 40,
50, 44, 32,115,116,114,105,110,103, 46,102,105,110,100, 40,116, 46,112, 97,114,
97,109,115, 44, 32,112, 97,116, 41, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32,115,
111, 99,107,101,116, 46,116,114,121, 40,116, 46,116,121,112,101, 32, 61, 61, 32,
34, 97, 34, 32,111,114, 32,116, 46,116,121,112,101, 32, 61, 61, 32, 34,105, 34,
44, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 34,105,110,118, 97,108,
105,100, 32,116,121,112,101, 32, 39, 34, 32, 46, 46, 32,116, 46,116,121,112,101,
32, 46, 46, 32, 34, 39, 34, 41, 10, 32, 32, 32, 32,101,110,100, 10, 32, 32, 32,
32,114,101,116,117,114,110, 32,116, 10,101,110,100, 10, 10,108,111, 99, 97,108,
32,102,117,110, 99,116,105,111,110, 32,115,112,117,116, 40,117, 44, 32, 98,111,
100,121, 41, 10, 32, 32, 32, 32,108,111, 99, 97,108, 32,112,117,116,116, 32, 61,
32,112, 97,114,115,101, 40,117, 41, 10, 32, 32, 32, 32,112,117,116,116, 46,115,
111,117,114, 99,101, 32, 61, 32,108,116,110, 49, 50, 46,115,111,117,114, 99,101,
46,115,116,114,105,110,103, 40, 98,111,100,121, 41, 10, 32, 32, 32, 32,114,101,
116,117,114,110, 32,116,112,117,116, 40,112,117,116,116, 41, 10,101,110,100, 10,
10,112,117,116, 32, 61, 32,115,111, 99,107,101,116, 46,112,114,111,116,101, 99,
116, 40,102,117,110, 99,116,105,111,110, 40,112,117,116,116, 44, 32, 98,111,100,
121, 41, 10, 32, 32, 32, 32,105,102, 32, 98, 97,115,101, 46,116,121,112,101, 40,
112,117,116,116, 41, 32, 61, 61, 32, 34,115,116,114,105,110,103, 34, 32,116,104,
101,110, 32,114,101,116,117,114,110, 32,115,112,117,116, 40,112,117,116,116, 44,
32, 98,111,100,121, 41, 10, 32, 32, 32, 32,101,108,115,101, 32,114,101,116,117,
114,110, 32,116,112,117,116, 40,112,117,116,116, 41, 32,101,110,100, 10,101,110,
100, 41, 10, 10,108,111, 99, 97,108, 32,102,117,110, 99,116,105,111,110, 32,116,
103,101,116, 40,103,101,116,116, 41, 10, 32, 32, 32, 32,103,101,116,116, 32, 61,
32,111,118,101,114,114,105,100,101, 40,103,101,116,116, 41, 10, 32, 32, 32, 32,
115,111, 99,107,101,116, 46,116,114,121, 40,103,101,116,116, 46,104,111,115,116,
44, 32, 34,109,105,115,115,105,110,103, 32,104,111,115,116,110, 97,109,101, 34,
41, 10, 32, 32, 32, 32,108,111, 99, 97,108, 32,102, 32, 61, 32,111,112,101,110,
40,103,101,116,116, 46,104,111,115,116, 44, 32,103,101,116,116, 46,112,111,114,
116, 44, 32,103,101,116,116, 46, 99,114,101, 97,116,101, 41, 10, 32, 32, 32, 32,
102, 58,103,114,101,101,116, 40, 41, 10, 32, 32, 32, 32,102, 58,108,111,103,105,
110, 40,103,101,116,116, 46,117,115,101,114, 44, 32,103,101,116,116, 46,112, 97,
115,115,119,111,114,100, 41, 10, 32, 32, 32, 32,105,102, 32,103,101,116,116, 46,
116,121,112,101, 32,116,104,101,110, 32,102, 58,116,121,112,101, 40,103,101,116,
116, 46,116,121,112,101, 41, 32,101,110,100, 10, 32, 32, 32, 32,102, 58,112, 97,
115,118, 40, 41, 10, 32, 32, 32, 32,102, 58,114,101, 99,101,105,118,101, 40,103,
101,116,116, 41, 10, 32, 32, 32, 32,102, 58,113,117,105,116, 40, 41, 10, 32, 32,
32, 32,114,101,116,117,114,110, 32,102, 58, 99,108,111,115,101, 40, 41, 10,101,
110,100, 10, 10,108,111, 99, 97,108, 32,102,117,110, 99,116,105,111,110, 32,115,
103,101,116, 40,117, 41, 10, 32, 32, 32, 32,108,111, 99, 97,108, 32,103,101,116,
116, 32, 61, 32,112, 97,114,115,101, 40,117, 41, 10, 32, 32, 32, 32,108,111, 99,
97,108, 32,116, 32, 61, 32,123,125, 10, 32, 32, 32, 32,103,101,116,116, 46,115,
105,110,107, 32, 61, 32,108,116,110, 49, 50, 46,115,105,110,107, 46,116, 97, 98,
108,101, 40,116, 41, 10, 32, 32, 32, 32,116,103,101,116, 40,103,101,116,116, 41,
10, 32, 32, 32, 32,114,101,116,117,114,110, 32,116, 97, 98,108,101, 46, 99,111,
110, 99, 97,116, 40,116, 41, 10,101,110,100, 10, 10, 99,111,109,109, 97,110,100,
32, 61, 32,115,111, 99,107,101,116, 46,112,114,111,116,101, 99,116, 40,102,117,
110, 99,116,105,111,110, 40, 99,109,100,116, 41, 10, 32, 32, 32, 32, 99,109,100,
116, 32, 61, 32,111,118,101,114,114,105,100,101, 40, 99,109,100,116, 41, 10, 32,
32, 32, 32,115,111, 99,107,101,116, 46,116,114,121, 40, 99,109,100,116, 46,104,
111,115,116, 44, 32, 34,109,105,115,115,105,110,103, 32,104,111,115,116,110, 97,
109,101, 34, 41, 10, 32, 32, 32, 32,115,111, 99,107,101,116, 46,116,114,121, 40,
99,109,100,116, 46, 99,111,109,109, 97,110,100, 44, 32, 34,109,105,115,115,105,
110,103, 32, 99,111,109,109, 97,110,100, 34, 41, 10, 32, 32, 32, 32,108,111, 99,
97,108, 32,102, 32, 61, 32,111,112,101,110, 40, 99,109,100,116, 46,104,111,115,
116, 44, 32, 99,109,100,116, 46,112,111,114,116, 44, 32, 99,109,100,116, 46, 99,
114,101, 97,116,101, 41, 10, 32, 32, 32, 32,102, 58,103,114,101,101,116, 40, 41,
10, 32, 32, 32, 32,102, 58,108,111,103,105,110, 40, 99,109,100,116, 46,117,115,
101,114, 44, 32, 99,109,100,116, 46,112, 97,115,115,119,111,114,100, 41, 10, 32,
32, 32, 32,102, 46,116,114,121, 40,102, 46,116,112, 58, 99,111,109,109, 97,110,
100, 40, 99,109,100,116, 46, 99,111,109,109, 97,110,100, 44, 32, 99,109,100,116,
46, 97,114,103,117,109,101,110,116, 41, 41, 10, 32, 32, 32, 32,105,102, 32, 99,
109,100,116, 46, 99,104,101, 99,107, 32,116,104,101,110, 32,102, 46,116,114,121,
40,102, 46,116,112, 58, 99,104,101, 99,107, 40, 99,109,100,116, 46, 99,104,101,
99,107, 41, 41, 32,101,110,100, 10, 32, 32, 32, 32,102, 58,113,117,105,116, 40,
41, 10, 32, 32, 32, 32,114,101,116,117,114,110, 32,102, 58, 99,108,111,115,101,
40, 41, 10,101,110,100, 41, 10, 10,103,101,116, 32, 61, 32,115,111, 99,107,101,
116, 46,112,114,111,116,101, 99,116, 40,102,117,110, 99,116,105,111,110, 40,103,
101,116,116, 41, 10, 32, 32, 32, 32,105,102, 32, 98, 97,115,101, 46,116,121,112,
101, 40,103,101,116,116, 41, 32, 61, 61, 32, 34,115,116,114,105,110,103, 34, 32,
116,104,101,110, 32,114,101,116,117,114,110, 32,115,103,101,116, 40,103,101,116,
116, 41, 10, 32, 32, 32, 32,101,108,115,101, 32,114,101,116,117,114,110, 32,116,
103,101,116, 40,103,101,116,116, 41, 32,101,110,100, 10,101,110,100, 41, 10, 10,
};
if (luaL_loadbuffer(L,(const char*)B1,sizeof(B1),"ftp.lua")==0) lua_call(L, 0, 0);
}
@@ -0,0 +1,350 @@
-----------------------------------------------------------------------------
-- HTTP/1.1 client support for the Lua language.
-- LuaSocket toolkit.
-- Author: Diego Nehab
-- RCS ID: $Id: http.lua,v 1.71 2007/10/13 23:55:20 diego Exp $
-----------------------------------------------------------------------------
-----------------------------------------------------------------------------
-- Declare module and import dependencies
-------------------------------------------------------------------------------
local socket = require("socket")
local url = require("socket.url")
local ltn12 = require("ltn12")
local mime = require("mime")
local string = require("string")
local base = _G
local table = require("table")
module("socket.http")
-----------------------------------------------------------------------------
-- Program constants
-----------------------------------------------------------------------------
-- connection timeout in seconds
TIMEOUT = 60
-- default port for document retrieval
PORT = 80
-- user agent field sent in request
USERAGENT = socket._VERSION
-----------------------------------------------------------------------------
-- Reads MIME headers from a connection, unfolding where needed
-----------------------------------------------------------------------------
local function receiveheaders(sock, headers)
local line, name, value, err
headers = headers or {}
-- get first line
line, err = sock:receive()
if err then return nil, err end
-- headers go until a blank line is found
while line ~= "" do
-- get field-name and value
name, value = socket.skip(2, string.find(line, "^(.-):%s*(.*)"))
if not (name and value) then return nil, "malformed reponse headers" end
name = string.lower(name)
-- get next line (value might be folded)
line, err = sock:receive()
if err then return nil, err end
-- unfold any folded values
while string.find(line, "^%s") do
value = value .. line
line = sock:receive()
if err then return nil, err end
end
-- save pair in table
if headers[name] then headers[name] = headers[name] .. ", " .. value
else headers[name] = value end
end
return headers
end
-----------------------------------------------------------------------------
-- Extra sources and sinks
-----------------------------------------------------------------------------
socket.sourcet["http-chunked"] = function(sock, headers)
return base.setmetatable({
getfd = function() return sock:getfd() end,
dirty = function() return sock:dirty() end
}, {
__call = function()
-- get chunk size, skip extention
local line, err = sock:receive()
if err then return nil, err end
local size = base.tonumber(string.gsub(line, ";.*", ""), 16)
if not size then return nil, "invalid chunk size" end
-- was it the last chunk?
if size > 0 then
-- if not, get chunk and skip terminating CRLF
local chunk, err, part = sock:receive(size)
if chunk then sock:receive() end
return chunk, err
else
-- if it was, read trailers into headers table
headers, err = receiveheaders(sock, headers)
if not headers then return nil, err end
end
end
})
end
socket.sinkt["http-chunked"] = function(sock)
return base.setmetatable({
getfd = function() return sock:getfd() end,
dirty = function() return sock:dirty() end
}, {
__call = function(self, chunk, err)
if not chunk then return sock:send("0\r\n\r\n") end
local size = string.format("%X\r\n", string.len(chunk))
return sock:send(size .. chunk .. "\r\n")
end
})
end
-----------------------------------------------------------------------------
-- Low level HTTP API
-----------------------------------------------------------------------------
local metat = { __index = {} }
function open(host, port, create)
-- create socket with user connect function, or with default
local c = socket.try((create or socket.tcp)())
local h = base.setmetatable({ c = c }, metat)
-- create finalized try
h.try = socket.newtry(function() h:close() end)
-- set timeout before connecting
h.try(c:settimeout(TIMEOUT))
h.try(c:connect(host, port or PORT))
-- here everything worked
return h
end
function metat.__index:sendrequestline(method, uri)
local reqline = string.format("%s %s HTTP/1.1\r\n", method or "GET", uri)
return self.try(self.c:send(reqline))
end
function metat.__index:sendheaders(headers)
local h = "\r\n"
for i, v in base.pairs(headers) do
h = i .. ": " .. v .. "\r\n" .. h
end
self.try(self.c:send(h))
return 1
end
function metat.__index:sendbody(headers, source, step)
source = source or ltn12.source.empty()
step = step or ltn12.pump.step
-- if we don't know the size in advance, send chunked and hope for the best
local mode = "http-chunked"
if headers["content-length"] then mode = "keep-open" end
return self.try(ltn12.pump.all(source, socket.sink(mode, self.c), step))
end
function metat.__index:receivestatusline()
local status = self.try(self.c:receive(5))
-- identify HTTP/0.9 responses, which do not contain a status line
-- this is just a heuristic, but is what the RFC recommends
if status ~= "HTTP/" then return nil, status end
-- otherwise proceed reading a status line
status = self.try(self.c:receive("*l", status))
local code = socket.skip(2, string.find(status, "HTTP/%d*%.%d* (%d%d%d)"))
return self.try(base.tonumber(code), status)
end
function metat.__index:receiveheaders()
return self.try(receiveheaders(self.c))
end
function metat.__index:receivebody(headers, sink, step)
sink = sink or ltn12.sink.null()
step = step or ltn12.pump.step
local length = base.tonumber(headers["content-length"])
local t = headers["transfer-encoding"] -- shortcut
local mode = "default" -- connection close
if t and t ~= "identity" then mode = "http-chunked"
elseif base.tonumber(headers["content-length"]) then mode = "by-length" end
return self.try(ltn12.pump.all(socket.source(mode, self.c, length),
sink, step))
end
function metat.__index:receive09body(status, sink, step)
local source = ltn12.source.rewind(socket.source("until-closed", self.c))
source(status)
return self.try(ltn12.pump.all(source, sink, step))
end
function metat.__index:close()
return self.c:close()
end
-----------------------------------------------------------------------------
-- High level HTTP API
-----------------------------------------------------------------------------
local function adjusturi(reqt)
local u = reqt
-- if there is a proxy, we need the full url. otherwise, just a part.
if not reqt.proxy and not PROXY then
u = {
path = socket.try(reqt.path, "invalid path 'nil'"),
params = reqt.params,
query = reqt.query,
fragment = reqt.fragment
}
end
return url.build(u)
end
local function adjustproxy(reqt)
local proxy = reqt.proxy or PROXY
if proxy then
proxy = url.parse(proxy)
return proxy.host, proxy.port or 3128
else
return reqt.host, reqt.port
end
end
local function adjustheaders(reqt)
-- default headers
local lower = {
["user-agent"] = USERAGENT,
["host"] = reqt.host,
["connection"] = "close, TE",
["te"] = "trailers"
}
-- if we have authentication information, pass it along
if reqt.user and reqt.password then
lower["authorization"] =
"Basic " .. (mime.b64(reqt.user .. ":" .. reqt.password))
end
-- override with user headers
for i,v in base.pairs(reqt.headers or lower) do
lower[string.lower(i)] = v
end
return lower
end
-- default url parts
local default = {
host = "",
port = PORT,
path ="/",
scheme = "http"
}
local function adjustrequest(reqt)
-- parse url if provided
local nreqt = reqt.url and url.parse(reqt.url, default) or {}
-- explicit components override url
for i,v in base.pairs(reqt) do nreqt[i] = v end
if nreqt.port == "" then nreqt.port = 80 end
socket.try(nreqt.host and nreqt.host ~= "",
"invalid host '" .. base.tostring(nreqt.host) .. "'")
-- compute uri if user hasn't overriden
nreqt.uri = reqt.uri or adjusturi(nreqt)
-- ajust host and port if there is a proxy
nreqt.host, nreqt.port = adjustproxy(nreqt)
-- adjust headers in request
nreqt.headers = adjustheaders(nreqt)
return nreqt
end
local function shouldredirect(reqt, code, headers)
return headers.location and
string.gsub(headers.location, "%s", "") ~= "" and
(reqt.redirect ~= false) and
(code == 301 or code == 302) and
(not reqt.method or reqt.method == "GET" or reqt.method == "HEAD")
and (not reqt.nredirects or reqt.nredirects < 5)
end
local function shouldreceivebody(reqt, code)
if reqt.method == "HEAD" then return nil end
if code == 204 or code == 304 then return nil end
if code >= 100 and code < 200 then return nil end
return 1
end
-- forward declarations
local trequest, tredirect
function tredirect(reqt, location)
local result, code, headers, status = trequest {
-- the RFC says the redirect URL has to be absolute, but some
-- servers do not respect that
url = url.absolute(reqt.url, location),
source = reqt.source,
sink = reqt.sink,
headers = reqt.headers,
proxy = reqt.proxy,
nredirects = (reqt.nredirects or 0) + 1,
create = reqt.create
}
-- pass location header back as a hint we redirected
headers = headers or {}
headers.location = headers.location or location
return result, code, headers, status
end
function trequest(reqt)
-- we loop until we get what we want, or
-- until we are sure there is no way to get it
local nreqt = adjustrequest(reqt)
local h = open(nreqt.host, nreqt.port, nreqt.create)
-- send request line and headers
h:sendrequestline(nreqt.method, nreqt.uri)
h:sendheaders(nreqt.headers)
-- if there is a body, send it
if nreqt.source then
h:sendbody(nreqt.headers, nreqt.source, nreqt.step)
end
local code, status = h:receivestatusline()
-- if it is an HTTP/0.9 server, simply get the body and we are done
if not code then
h:receive09body(status, nreqt.sink, nreqt.step)
return 1, 200
end
local headers
-- ignore any 100-continue messages
while code == 100 do
headers = h:receiveheaders()
code, status = h:receivestatusline()
end
headers = h:receiveheaders()
-- at this point we should have a honest reply from the server
-- we can't redirect if we already used the source, so we report the error
if shouldredirect(nreqt, code, headers) and not nreqt.source then
h:close()
return tredirect(reqt, headers.location)
end
-- here we are finally done
if shouldreceivebody(nreqt, code) then
h:receivebody(headers, nreqt.sink, nreqt.step)
end
h:close()
return 1, code, headers, status
end
local function srequest(u, b)
local t = {}
local reqt = {
url = u,
sink = ltn12.sink.table(t)
}
if b then
reqt.source = ltn12.source.string(b)
reqt.headers = {
["content-length"] = string.len(b),
["content-type"] = "application/x-www-form-urlencoded"
}
reqt.method = "POST"
end
local code, headers, status = socket.skip(1, trequest(reqt))
return table.concat(t), code, headers, status
end
request = socket.protect(function(reqt, body)
if base.type(reqt) == "string" then return srequest(reqt, body)
else return trequest(reqt) end
end)
@@ -0,0 +1,621 @@
/* code automatically generated by bin2c -- DO NOT EDIT */
/* #include'ing this file in a C program is equivalent to calling
if (luaL_loadfile(L,"http.lua")==0) lua_call(L, 0, 0);
*/
{
/* http.lua */
static const unsigned char B1[]={
45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45,
45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45,
45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45,
45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 10, 45, 45,
32, 72, 84, 84, 80, 47, 49, 46, 49, 32, 99,108,105,101,110,116, 32,115,117,112,
112,111,114,116, 32,102,111,114, 32,116,104,101, 32, 76,117, 97, 32,108, 97,110,
103,117, 97,103,101, 46, 10, 45, 45, 32, 76,117, 97, 83,111, 99,107,101,116, 32,
116,111,111,108,107,105,116, 46, 10, 45, 45, 32, 65,117,116,104,111,114, 58, 32,
68,105,101,103,111, 32, 78,101,104, 97, 98, 10, 45, 45, 32, 82, 67, 83, 32, 73,
68, 58, 32, 36, 73,100, 58, 32,104,116,116,112, 46,108,117, 97, 44,118, 32, 49,
46, 55, 49, 32, 50, 48, 48, 55, 47, 49, 48, 47, 49, 51, 32, 50, 51, 58, 53, 53,
58, 50, 48, 32,100,105,101,103,111, 32, 69,120,112, 32, 36, 10, 45, 45, 45, 45,
45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45,
45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45,
45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45,
45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 10, 10, 45, 45, 45, 45, 45,
45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45,
45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45,
45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45,
45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 10, 45, 45, 32, 68,101, 99,108,
97,114,101, 32,109,111,100,117,108,101, 32, 97,110,100, 32,105,109,112,111,114,
116, 32,100,101,112,101,110,100,101,110, 99,105,101,115, 10, 45, 45, 45, 45, 45,
45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45,
45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45,
45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45,
45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 10,108,111, 99, 97,108,
32,115,111, 99,107,101,116, 32, 61, 32,114,101,113,117,105,114,101, 40, 34,115,
111, 99,107,101,116, 34, 41, 10,108,111, 99, 97,108, 32,117,114,108, 32, 61, 32,
114,101,113,117,105,114,101, 40, 34,115,111, 99,107,101,116, 46,117,114,108, 34,
41, 10,108,111, 99, 97,108, 32,108,116,110, 49, 50, 32, 61, 32,114,101,113,117,
105,114,101, 40, 34,108,116,110, 49, 50, 34, 41, 10,108,111, 99, 97,108, 32,109,
105,109,101, 32, 61, 32,114,101,113,117,105,114,101, 40, 34,109,105,109,101, 34,
41, 10,108,111, 99, 97,108, 32,115,116,114,105,110,103, 32, 61, 32,114,101,113,
117,105,114,101, 40, 34,115,116,114,105,110,103, 34, 41, 10,108,111, 99, 97,108,
32, 98, 97,115,101, 32, 61, 32, 95, 71, 10,108,111, 99, 97,108, 32,116, 97, 98,
108,101, 32, 61, 32,114,101,113,117,105,114,101, 40, 34,116, 97, 98,108,101, 34,
41, 10,109,111,100,117,108,101, 40, 34,115,111, 99,107,101,116, 46,104,116,116,
112, 34, 41, 10, 10, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45,
45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45,
45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45,
45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45,
45, 45, 10, 45, 45, 32, 80,114,111,103,114, 97,109, 32, 99,111,110,115,116, 97,
110,116,115, 10, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45,
45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45,
45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45,
45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45,
45, 10, 45, 45, 32, 99,111,110,110,101, 99,116,105,111,110, 32,116,105,109,101,
111,117,116, 32,105,110, 32,115,101, 99,111,110,100,115, 10, 84, 73, 77, 69, 79,
85, 84, 32, 61, 32, 54, 48, 10, 45, 45, 32,100,101,102, 97,117,108,116, 32,112,
111,114,116, 32,102,111,114, 32,100,111, 99,117,109,101,110,116, 32,114,101,116,
114,105,101,118, 97,108, 10, 80, 79, 82, 84, 32, 61, 32, 56, 48, 10, 45, 45, 32,
117,115,101,114, 32, 97,103,101,110,116, 32,102,105,101,108,100, 32,115,101,110,
116, 32,105,110, 32,114,101,113,117,101,115,116, 10, 85, 83, 69, 82, 65, 71, 69,
78, 84, 32, 61, 32,115,111, 99,107,101,116, 46, 95, 86, 69, 82, 83, 73, 79, 78,
10, 10, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45,
45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45,
45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45,
45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 10,
45, 45, 32, 82,101, 97,100,115, 32, 77, 73, 77, 69, 32,104,101, 97,100,101,114,
115, 32,102,114,111,109, 32, 97, 32, 99,111,110,110,101, 99,116,105,111,110, 44,
32,117,110,102,111,108,100,105,110,103, 32,119,104,101,114,101, 32,110,101,101,
100,101,100, 10, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45,
45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45,
45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45,
45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45,
45, 10,108,111, 99, 97,108, 32,102,117,110, 99,116,105,111,110, 32,114,101, 99,
101,105,118,101,104,101, 97,100,101,114,115, 40,115,111, 99,107, 44, 32,104,101,
97,100,101,114,115, 41, 10, 32, 32, 32, 32,108,111, 99, 97,108, 32,108,105,110,
101, 44, 32,110, 97,109,101, 44, 32,118, 97,108,117,101, 44, 32,101,114,114, 10,
32, 32, 32, 32,104,101, 97,100,101,114,115, 32, 61, 32,104,101, 97,100,101,114,
115, 32,111,114, 32,123,125, 10, 32, 32, 32, 32, 45, 45, 32,103,101,116, 32,102,
105,114,115,116, 32,108,105,110,101, 10, 32, 32, 32, 32,108,105,110,101, 44, 32,
101,114,114, 32, 61, 32,115,111, 99,107, 58,114,101, 99,101,105,118,101, 40, 41,
10, 32, 32, 32, 32,105,102, 32,101,114,114, 32,116,104,101,110, 32,114,101,116,
117,114,110, 32,110,105,108, 44, 32,101,114,114, 32,101,110,100, 10, 32, 32, 32,
32, 45, 45, 32,104,101, 97,100,101,114,115, 32,103,111, 32,117,110,116,105,108,
32, 97, 32, 98,108, 97,110,107, 32,108,105,110,101, 32,105,115, 32,102,111,117,
110,100, 10, 32, 32, 32, 32,119,104,105,108,101, 32,108,105,110,101, 32,126, 61,
32, 34, 34, 32,100,111, 10, 32, 32, 32, 32, 32, 32, 32, 32, 45, 45, 32,103,101,
116, 32,102,105,101,108,100, 45,110, 97,109,101, 32, 97,110,100, 32,118, 97,108,
117,101, 10, 32, 32, 32, 32, 32, 32, 32, 32,110, 97,109,101, 44, 32,118, 97,108,
117,101, 32, 61, 32,115,111, 99,107,101,116, 46,115,107,105,112, 40, 50, 44, 32,
115,116,114,105,110,103, 46,102,105,110,100, 40,108,105,110,101, 44, 32, 34, 94,
40, 46, 45, 41, 58, 37,115, 42, 40, 46, 42, 41, 34, 41, 41, 10, 32, 32, 32, 32,
32, 32, 32, 32,105,102, 32,110,111,116, 32, 40,110, 97,109,101, 32, 97,110,100,
32,118, 97,108,117,101, 41, 32,116,104,101,110, 32,114,101,116,117,114,110, 32,
110,105,108, 44, 32, 34,109, 97,108,102,111,114,109,101,100, 32,114,101,112,111,
110,115,101, 32,104,101, 97,100,101,114,115, 34, 32,101,110,100, 10, 32, 32, 32,
32, 32, 32, 32, 32,110, 97,109,101, 32, 61, 32,115,116,114,105,110,103, 46,108,
111,119,101,114, 40,110, 97,109,101, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 45,
45, 32,103,101,116, 32,110,101,120,116, 32,108,105,110,101, 32, 40,118, 97,108,
117,101, 32,109,105,103,104,116, 32, 98,101, 32,102,111,108,100,101,100, 41, 10,
32, 32, 32, 32, 32, 32, 32, 32,108,105,110,101, 44, 32,101,114,114, 32, 32, 61,
32,115,111, 99,107, 58,114,101, 99,101,105,118,101, 40, 41, 10, 32, 32, 32, 32,
32, 32, 32, 32,105,102, 32,101,114,114, 32,116,104,101,110, 32,114,101,116,117,
114,110, 32,110,105,108, 44, 32,101,114,114, 32,101,110,100, 10, 32, 32, 32, 32,
32, 32, 32, 32, 45, 45, 32,117,110,102,111,108,100, 32, 97,110,121, 32,102,111,
108,100,101,100, 32,118, 97,108,117,101,115, 10, 32, 32, 32, 32, 32, 32, 32, 32,
119,104,105,108,101, 32,115,116,114,105,110,103, 46,102,105,110,100, 40,108,105,
110,101, 44, 32, 34, 94, 37,115, 34, 41, 32,100,111, 10, 32, 32, 32, 32, 32, 32,
32, 32, 32, 32, 32, 32,118, 97,108,117,101, 32, 61, 32,118, 97,108,117,101, 32,
46, 46, 32,108,105,110,101, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
108,105,110,101, 32, 61, 32,115,111, 99,107, 58,114,101, 99,101,105,118,101, 40,
41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,105,102, 32,101,114,114,
32,116,104,101,110, 32,114,101,116,117,114,110, 32,110,105,108, 44, 32,101,114,
114, 32,101,110,100, 10, 32, 32, 32, 32, 32, 32, 32, 32,101,110,100, 10, 32, 32,
32, 32, 32, 32, 32, 32, 45, 45, 32,115, 97,118,101, 32,112, 97,105,114, 32,105,
110, 32,116, 97, 98,108,101, 10, 32, 32, 32, 32, 32, 32, 32, 32,105,102, 32,104,
101, 97,100,101,114,115, 91,110, 97,109,101, 93, 32,116,104,101,110, 32,104,101,
97,100,101,114,115, 91,110, 97,109,101, 93, 32, 61, 32,104,101, 97,100,101,114,
115, 91,110, 97,109,101, 93, 32, 46, 46, 32, 34, 44, 32, 34, 32, 46, 46, 32,118,
97,108,117,101, 10, 32, 32, 32, 32, 32, 32, 32, 32,101,108,115,101, 32,104,101,
97,100,101,114,115, 91,110, 97,109,101, 93, 32, 61, 32,118, 97,108,117,101, 32,
101,110,100, 10, 32, 32, 32, 32,101,110,100, 10, 32, 32, 32, 32,114,101,116,117,
114,110, 32,104,101, 97,100,101,114,115, 10,101,110,100, 10, 10, 45, 45, 45, 45,
45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45,
45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45,
45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45,
45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 10, 45, 45, 32, 69,120,116,
114, 97, 32,115,111,117,114, 99,101,115, 32, 97,110,100, 32,115,105,110,107,115,
10, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45,
45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45,
45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45,
45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 10,115,
111, 99,107,101,116, 46,115,111,117,114, 99,101,116, 91, 34,104,116,116,112, 45,
99,104,117,110,107,101,100, 34, 93, 32, 61, 32,102,117,110, 99,116,105,111,110,
40,115,111, 99,107, 44, 32,104,101, 97,100,101,114,115, 41, 10, 32, 32, 32, 32,
114,101,116,117,114,110, 32, 98, 97,115,101, 46,115,101,116,109,101,116, 97,116,
97, 98,108,101, 40,123, 10, 32, 32, 32, 32, 32, 32, 32, 32,103,101,116,102,100,
32, 61, 32,102,117,110, 99,116,105,111,110, 40, 41, 32,114,101,116,117,114,110,
32,115,111, 99,107, 58,103,101,116,102,100, 40, 41, 32,101,110,100, 44, 10, 32,
32, 32, 32, 32, 32, 32, 32,100,105,114,116,121, 32, 61, 32,102,117,110, 99,116,
105,111,110, 40, 41, 32,114,101,116,117,114,110, 32,115,111, 99,107, 58,100,105,
114,116,121, 40, 41, 32,101,110,100, 10, 32, 32, 32, 32,125, 44, 32,123, 10, 32,
32, 32, 32, 32, 32, 32, 32, 95, 95, 99, 97,108,108, 32, 61, 32,102,117,110, 99,
116,105,111,110, 40, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 45,
45, 32,103,101,116, 32, 99,104,117,110,107, 32,115,105,122,101, 44, 32,115,107,
105,112, 32,101,120,116,101,110,116,105,111,110, 10, 32, 32, 32, 32, 32, 32, 32,
32, 32, 32, 32, 32,108,111, 99, 97,108, 32,108,105,110,101, 44, 32,101,114,114,
32, 61, 32,115,111, 99,107, 58,114,101, 99,101,105,118,101, 40, 41, 10, 32, 32,
32, 32, 32, 32, 32, 32, 32, 32, 32, 32,105,102, 32,101,114,114, 32,116,104,101,
110, 32,114,101,116,117,114,110, 32,110,105,108, 44, 32,101,114,114, 32,101,110,
100, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,108,111, 99, 97,108, 32,
115,105,122,101, 32, 61, 32, 98, 97,115,101, 46,116,111,110,117,109, 98,101,114,
40,115,116,114,105,110,103, 46,103,115,117, 98, 40,108,105,110,101, 44, 32, 34,
59, 46, 42, 34, 44, 32, 34, 34, 41, 44, 32, 49, 54, 41, 10, 32, 32, 32, 32, 32,
32, 32, 32, 32, 32, 32, 32,105,102, 32,110,111,116, 32,115,105,122,101, 32,116,
104,101,110, 32,114,101,116,117,114,110, 32,110,105,108, 44, 32, 34,105,110,118,
97,108,105,100, 32, 99,104,117,110,107, 32,115,105,122,101, 34, 32,101,110,100,
10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 45, 45, 32,119, 97,115, 32,
105,116, 32,116,104,101, 32,108, 97,115,116, 32, 99,104,117,110,107, 63, 10, 32,
32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,105,102, 32,115,105,122,101, 32, 62,
32, 48, 32,116,104,101,110, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
32, 32, 32, 32, 45, 45, 32,105,102, 32,110,111,116, 44, 32,103,101,116, 32, 99,
104,117,110,107, 32, 97,110,100, 32,115,107,105,112, 32,116,101,114,109,105,110,
97,116,105,110,103, 32, 67, 82, 76, 70, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32,
32, 32, 32, 32, 32, 32, 32,108,111, 99, 97,108, 32, 99,104,117,110,107, 44, 32,
101,114,114, 44, 32,112, 97,114,116, 32, 61, 32,115,111, 99,107, 58,114,101, 99,
101,105,118,101, 40,115,105,122,101, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32,
32, 32, 32, 32, 32, 32, 32,105,102, 32, 99,104,117,110,107, 32,116,104,101,110,
32,115,111, 99,107, 58,114,101, 99,101,105,118,101, 40, 41, 32,101,110,100, 10,
32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,114,101,116,117,
114,110, 32, 99,104,117,110,107, 44, 32,101,114,114, 10, 32, 32, 32, 32, 32, 32,
32, 32, 32, 32, 32, 32,101,108,115,101, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32,
32, 32, 32, 32, 32, 32, 32, 45, 45, 32,105,102, 32,105,116, 32,119, 97,115, 44,
32,114,101, 97,100, 32,116,114, 97,105,108,101,114,115, 32,105,110,116,111, 32,
104,101, 97,100,101,114,115, 32,116, 97, 98,108,101, 10, 32, 32, 32, 32, 32, 32,
32, 32, 32, 32, 32, 32, 32, 32, 32, 32,104,101, 97,100,101,114,115, 44, 32,101,
114,114, 32, 61, 32,114,101, 99,101,105,118,101,104,101, 97,100,101,114,115, 40,
115,111, 99,107, 44, 32,104,101, 97,100,101,114,115, 41, 10, 32, 32, 32, 32, 32,
32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,105,102, 32,110,111,116, 32,104,101,
97,100,101,114,115, 32,116,104,101,110, 32,114,101,116,117,114,110, 32,110,105,
108, 44, 32,101,114,114, 32,101,110,100, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32,
32, 32, 32,101,110,100, 10, 32, 32, 32, 32, 32, 32, 32, 32,101,110,100, 10, 32,
32, 32, 32,125, 41, 10,101,110,100, 10, 10,115,111, 99,107,101,116, 46,115,105,
110,107,116, 91, 34,104,116,116,112, 45, 99,104,117,110,107,101,100, 34, 93, 32,
61, 32,102,117,110, 99,116,105,111,110, 40,115,111, 99,107, 41, 10, 32, 32, 32,
32,114,101,116,117,114,110, 32, 98, 97,115,101, 46,115,101,116,109,101,116, 97,
116, 97, 98,108,101, 40,123, 10, 32, 32, 32, 32, 32, 32, 32, 32,103,101,116,102,
100, 32, 61, 32,102,117,110, 99,116,105,111,110, 40, 41, 32,114,101,116,117,114,
110, 32,115,111, 99,107, 58,103,101,116,102,100, 40, 41, 32,101,110,100, 44, 10,
32, 32, 32, 32, 32, 32, 32, 32,100,105,114,116,121, 32, 61, 32,102,117,110, 99,
116,105,111,110, 40, 41, 32,114,101,116,117,114,110, 32,115,111, 99,107, 58,100,
105,114,116,121, 40, 41, 32,101,110,100, 10, 32, 32, 32, 32,125, 44, 32,123, 10,
32, 32, 32, 32, 32, 32, 32, 32, 95, 95, 99, 97,108,108, 32, 61, 32,102,117,110,
99,116,105,111,110, 40,115,101,108,102, 44, 32, 99,104,117,110,107, 44, 32,101,
114,114, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,105,102, 32,110,
111,116, 32, 99,104,117,110,107, 32,116,104,101,110, 32,114,101,116,117,114,110,
32,115,111, 99,107, 58,115,101,110,100, 40, 34, 48, 92,114, 92,110, 92,114, 92,
110, 34, 41, 32,101,110,100, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
108,111, 99, 97,108, 32,115,105,122,101, 32, 61, 32,115,116,114,105,110,103, 46,
102,111,114,109, 97,116, 40, 34, 37, 88, 92,114, 92,110, 34, 44, 32,115,116,114,
105,110,103, 46,108,101,110, 40, 99,104,117,110,107, 41, 41, 10, 32, 32, 32, 32,
32, 32, 32, 32, 32, 32, 32, 32,114,101,116,117,114,110, 32,115,111, 99,107, 58,
115,101,110,100, 40,115,105,122,101, 32, 46, 46, 32, 32, 99,104,117,110,107, 32,
46, 46, 32, 34, 92,114, 92,110, 34, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32,101,
110,100, 10, 32, 32, 32, 32,125, 41, 10,101,110,100, 10, 10, 45, 45, 45, 45, 45,
45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45,
45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45,
45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45,
45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 10, 45, 45, 32, 76,111,119, 32,
108,101,118,101,108, 32, 72, 84, 84, 80, 32, 65, 80, 73, 10, 45, 45, 45, 45, 45,
45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45,
45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45,
45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45,
45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 10,108,111, 99, 97,108, 32,109,
101,116, 97,116, 32, 61, 32,123, 32, 95, 95,105,110,100,101,120, 32, 61, 32,123,
125, 32,125, 10, 10,102,117,110, 99,116,105,111,110, 32,111,112,101,110, 40,104,
111,115,116, 44, 32,112,111,114,116, 44, 32, 99,114,101, 97,116,101, 41, 10, 32,
32, 32, 32, 45, 45, 32, 99,114,101, 97,116,101, 32,115,111, 99,107,101,116, 32,
119,105,116,104, 32,117,115,101,114, 32, 99,111,110,110,101, 99,116, 32,102,117,
110, 99,116,105,111,110, 44, 32,111,114, 32,119,105,116,104, 32,100,101,102, 97,
117,108,116, 10, 32, 32, 32, 32,108,111, 99, 97,108, 32, 99, 32, 61, 32,115,111,
99,107,101,116, 46,116,114,121, 40, 40, 99,114,101, 97,116,101, 32,111,114, 32,
115,111, 99,107,101,116, 46,116, 99,112, 41, 40, 41, 41, 10, 32, 32, 32, 32,108,
111, 99, 97,108, 32,104, 32, 61, 32, 98, 97,115,101, 46,115,101,116,109,101,116,
97,116, 97, 98,108,101, 40,123, 32, 99, 32, 61, 32, 99, 32,125, 44, 32,109,101,
116, 97,116, 41, 10, 32, 32, 32, 32, 45, 45, 32, 99,114,101, 97,116,101, 32,102,
105,110, 97,108,105,122,101,100, 32,116,114,121, 10, 32, 32, 32, 32,104, 46,116,
114,121, 32, 61, 32,115,111, 99,107,101,116, 46,110,101,119,116,114,121, 40,102,
117,110, 99,116,105,111,110, 40, 41, 32,104, 58, 99,108,111,115,101, 40, 41, 32,
101,110,100, 41, 10, 32, 32, 32, 32, 45, 45, 32,115,101,116, 32,116,105,109,101,
111,117,116, 32, 98,101,102,111,114,101, 32, 99,111,110,110,101, 99,116,105,110,
103, 10, 32, 32, 32, 32,104, 46,116,114,121, 40, 99, 58,115,101,116,116,105,109,
101,111,117,116, 40, 84, 73, 77, 69, 79, 85, 84, 41, 41, 10, 32, 32, 32, 32,104,
46,116,114,121, 40, 99, 58, 99,111,110,110,101, 99,116, 40,104,111,115,116, 44,
32,112,111,114,116, 32,111,114, 32, 80, 79, 82, 84, 41, 41, 10, 32, 32, 32, 32,
45, 45, 32,104,101,114,101, 32,101,118,101,114,121,116,104,105,110,103, 32,119,
111,114,107,101,100, 10, 32, 32, 32, 32,114,101,116,117,114,110, 32,104, 10,101,
110,100, 10, 10,102,117,110, 99,116,105,111,110, 32,109,101,116, 97,116, 46, 95,
95,105,110,100,101,120, 58,115,101,110,100,114,101,113,117,101,115,116,108,105,
110,101, 40,109,101,116,104,111,100, 44, 32,117,114,105, 41, 10, 32, 32, 32, 32,
108,111, 99, 97,108, 32,114,101,113,108,105,110,101, 32, 61, 32,115,116,114,105,
110,103, 46,102,111,114,109, 97,116, 40, 34, 37,115, 32, 37,115, 32, 72, 84, 84,
80, 47, 49, 46, 49, 92,114, 92,110, 34, 44, 32,109,101,116,104,111,100, 32,111,
114, 32, 34, 71, 69, 84, 34, 44, 32,117,114,105, 41, 10, 32, 32, 32, 32,114,101,
116,117,114,110, 32,115,101,108,102, 46,116,114,121, 40,115,101,108,102, 46, 99,
58,115,101,110,100, 40,114,101,113,108,105,110,101, 41, 41, 10,101,110,100, 10,
10,102,117,110, 99,116,105,111,110, 32,109,101,116, 97,116, 46, 95, 95,105,110,
100,101,120, 58,115,101,110,100,104,101, 97,100,101,114,115, 40,104,101, 97,100,
101,114,115, 41, 10, 32, 32, 32, 32,108,111, 99, 97,108, 32,104, 32, 61, 32, 34,
92,114, 92,110, 34, 10, 32, 32, 32, 32,102,111,114, 32,105, 44, 32,118, 32,105,
110, 32, 98, 97,115,101, 46,112, 97,105,114,115, 40,104,101, 97,100,101,114,115,
41, 32,100,111, 10, 32, 32, 32, 32, 32, 32, 32, 32,104, 32, 61, 32,105, 32, 46,
46, 32, 34, 58, 32, 34, 32, 46, 46, 32,118, 32, 46, 46, 32, 34, 92,114, 92,110,
34, 32, 46, 46, 32,104, 10, 32, 32, 32, 32,101,110,100, 10, 32, 32, 32, 32,115,
101,108,102, 46,116,114,121, 40,115,101,108,102, 46, 99, 58,115,101,110,100, 40,
104, 41, 41, 10, 32, 32, 32, 32,114,101,116,117,114,110, 32, 49, 10,101,110,100,
10, 10,102,117,110, 99,116,105,111,110, 32,109,101,116, 97,116, 46, 95, 95,105,
110,100,101,120, 58,115,101,110,100, 98,111,100,121, 40,104,101, 97,100,101,114,
115, 44, 32,115,111,117,114, 99,101, 44, 32,115,116,101,112, 41, 10, 32, 32, 32,
32,115,111,117,114, 99,101, 32, 61, 32,115,111,117,114, 99,101, 32,111,114, 32,
108,116,110, 49, 50, 46,115,111,117,114, 99,101, 46,101,109,112,116,121, 40, 41,
10, 32, 32, 32, 32,115,116,101,112, 32, 61, 32,115,116,101,112, 32,111,114, 32,
108,116,110, 49, 50, 46,112,117,109,112, 46,115,116,101,112, 10, 32, 32, 32, 32,
45, 45, 32,105,102, 32,119,101, 32,100,111,110, 39,116, 32,107,110,111,119, 32,
116,104,101, 32,115,105,122,101, 32,105,110, 32, 97,100,118, 97,110, 99,101, 44,
32,115,101,110,100, 32, 99,104,117,110,107,101,100, 32, 97,110,100, 32,104,111,
112,101, 32,102,111,114, 32,116,104,101, 32, 98,101,115,116, 10, 32, 32, 32, 32,
108,111, 99, 97,108, 32,109,111,100,101, 32, 61, 32, 34,104,116,116,112, 45, 99,
104,117,110,107,101,100, 34, 10, 32, 32, 32, 32,105,102, 32,104,101, 97,100,101,
114,115, 91, 34, 99,111,110,116,101,110,116, 45,108,101,110,103,116,104, 34, 93,
32,116,104,101,110, 32,109,111,100,101, 32, 61, 32, 34,107,101,101,112, 45,111,
112,101,110, 34, 32,101,110,100, 10, 32, 32, 32, 32,114,101,116,117,114,110, 32,
115,101,108,102, 46,116,114,121, 40,108,116,110, 49, 50, 46,112,117,109,112, 46,
97,108,108, 40,115,111,117,114, 99,101, 44, 32,115,111, 99,107,101,116, 46,115,
105,110,107, 40,109,111,100,101, 44, 32,115,101,108,102, 46, 99, 41, 44, 32,115,
116,101,112, 41, 41, 10,101,110,100, 10, 10,102,117,110, 99,116,105,111,110, 32,
109,101,116, 97,116, 46, 95, 95,105,110,100,101,120, 58,114,101, 99,101,105,118,
101,115,116, 97,116,117,115,108,105,110,101, 40, 41, 10, 32, 32, 32, 32,108,111,
99, 97,108, 32,115,116, 97,116,117,115, 32, 61, 32,115,101,108,102, 46,116,114,
121, 40,115,101,108,102, 46, 99, 58,114,101, 99,101,105,118,101, 40, 53, 41, 41,
10, 32, 32, 32, 32, 45, 45, 32,105,100,101,110,116,105,102,121, 32, 72, 84, 84,
80, 47, 48, 46, 57, 32,114,101,115,112,111,110,115,101,115, 44, 32,119,104,105,
99,104, 32,100,111, 32,110,111,116, 32, 99,111,110,116, 97,105,110, 32, 97, 32,
115,116, 97,116,117,115, 32,108,105,110,101, 10, 32, 32, 32, 32, 45, 45, 32,116,
104,105,115, 32,105,115, 32,106,117,115,116, 32, 97, 32,104,101,117,114,105,115,
116,105, 99, 44, 32, 98,117,116, 32,105,115, 32,119,104, 97,116, 32,116,104,101,
32, 82, 70, 67, 32,114,101, 99,111,109,109,101,110,100,115, 10, 32, 32, 32, 32,
105,102, 32,115,116, 97,116,117,115, 32,126, 61, 32, 34, 72, 84, 84, 80, 47, 34,
32,116,104,101,110, 32,114,101,116,117,114,110, 32,110,105,108, 44, 32,115,116,
97,116,117,115, 32,101,110,100, 10, 32, 32, 32, 32, 45, 45, 32,111,116,104,101,
114,119,105,115,101, 32,112,114,111, 99,101,101,100, 32,114,101, 97,100,105,110,
103, 32, 97, 32,115,116, 97,116,117,115, 32,108,105,110,101, 10, 32, 32, 32, 32,
115,116, 97,116,117,115, 32, 61, 32,115,101,108,102, 46,116,114,121, 40,115,101,
108,102, 46, 99, 58,114,101, 99,101,105,118,101, 40, 34, 42,108, 34, 44, 32,115,
116, 97,116,117,115, 41, 41, 10, 32, 32, 32, 32,108,111, 99, 97,108, 32, 99,111,
100,101, 32, 61, 32,115,111, 99,107,101,116, 46,115,107,105,112, 40, 50, 44, 32,
115,116,114,105,110,103, 46,102,105,110,100, 40,115,116, 97,116,117,115, 44, 32,
34, 72, 84, 84, 80, 47, 37,100, 42, 37, 46, 37,100, 42, 32, 40, 37,100, 37,100,
37,100, 41, 34, 41, 41, 10, 32, 32, 32, 32,114,101,116,117,114,110, 32,115,101,
108,102, 46,116,114,121, 40, 98, 97,115,101, 46,116,111,110,117,109, 98,101,114,
40, 99,111,100,101, 41, 44, 32,115,116, 97,116,117,115, 41, 10,101,110,100, 10,
10,102,117,110, 99,116,105,111,110, 32,109,101,116, 97,116, 46, 95, 95,105,110,
100,101,120, 58,114,101, 99,101,105,118,101,104,101, 97,100,101,114,115, 40, 41,
10, 32, 32, 32, 32,114,101,116,117,114,110, 32,115,101,108,102, 46,116,114,121,
40,114,101, 99,101,105,118,101,104,101, 97,100,101,114,115, 40,115,101,108,102,
46, 99, 41, 41, 10,101,110,100, 10, 10,102,117,110, 99,116,105,111,110, 32,109,
101,116, 97,116, 46, 95, 95,105,110,100,101,120, 58,114,101, 99,101,105,118,101,
98,111,100,121, 40,104,101, 97,100,101,114,115, 44, 32,115,105,110,107, 44, 32,
115,116,101,112, 41, 10, 32, 32, 32, 32,115,105,110,107, 32, 61, 32,115,105,110,
107, 32,111,114, 32,108,116,110, 49, 50, 46,115,105,110,107, 46,110,117,108,108,
40, 41, 10, 32, 32, 32, 32,115,116,101,112, 32, 61, 32,115,116,101,112, 32,111,
114, 32,108,116,110, 49, 50, 46,112,117,109,112, 46,115,116,101,112, 10, 32, 32,
32, 32,108,111, 99, 97,108, 32,108,101,110,103,116,104, 32, 61, 32, 98, 97,115,
101, 46,116,111,110,117,109, 98,101,114, 40,104,101, 97,100,101,114,115, 91, 34,
99,111,110,116,101,110,116, 45,108,101,110,103,116,104, 34, 93, 41, 10, 32, 32,
32, 32,108,111, 99, 97,108, 32,116, 32, 61, 32,104,101, 97,100,101,114,115, 91,
34,116,114, 97,110,115,102,101,114, 45,101,110, 99,111,100,105,110,103, 34, 93,
32, 45, 45, 32,115,104,111,114,116, 99,117,116, 10, 32, 32, 32, 32,108,111, 99,
97,108, 32,109,111,100,101, 32, 61, 32, 34,100,101,102, 97,117,108,116, 34, 32,
45, 45, 32, 99,111,110,110,101, 99,116,105,111,110, 32, 99,108,111,115,101, 10,
32, 32, 32, 32,105,102, 32,116, 32, 97,110,100, 32,116, 32,126, 61, 32, 34,105,
100,101,110,116,105,116,121, 34, 32,116,104,101,110, 32,109,111,100,101, 32, 61,
32, 34,104,116,116,112, 45, 99,104,117,110,107,101,100, 34, 10, 32, 32, 32, 32,
101,108,115,101,105,102, 32, 98, 97,115,101, 46,116,111,110,117,109, 98,101,114,
40,104,101, 97,100,101,114,115, 91, 34, 99,111,110,116,101,110,116, 45,108,101,
110,103,116,104, 34, 93, 41, 32,116,104,101,110, 32,109,111,100,101, 32, 61, 32,
34, 98,121, 45,108,101,110,103,116,104, 34, 32,101,110,100, 10, 32, 32, 32, 32,
114,101,116,117,114,110, 32,115,101,108,102, 46,116,114,121, 40,108,116,110, 49,
50, 46,112,117,109,112, 46, 97,108,108, 40,115,111, 99,107,101,116, 46,115,111,
117,114, 99,101, 40,109,111,100,101, 44, 32,115,101,108,102, 46, 99, 44, 32,108,
101,110,103,116,104, 41, 44, 10, 32, 32, 32, 32, 32, 32, 32, 32,115,105,110,107,
44, 32,115,116,101,112, 41, 41, 10,101,110,100, 10, 10,102,117,110, 99,116,105,
111,110, 32,109,101,116, 97,116, 46, 95, 95,105,110,100,101,120, 58,114,101, 99,
101,105,118,101, 48, 57, 98,111,100,121, 40,115,116, 97,116,117,115, 44, 32,115,
105,110,107, 44, 32,115,116,101,112, 41, 10, 32, 32, 32, 32,108,111, 99, 97,108,
32,115,111,117,114, 99,101, 32, 61, 32,108,116,110, 49, 50, 46,115,111,117,114,
99,101, 46,114,101,119,105,110,100, 40,115,111, 99,107,101,116, 46,115,111,117,
114, 99,101, 40, 34,117,110,116,105,108, 45, 99,108,111,115,101,100, 34, 44, 32,
115,101,108,102, 46, 99, 41, 41, 10, 32, 32, 32, 32,115,111,117,114, 99,101, 40,
115,116, 97,116,117,115, 41, 10, 32, 32, 32, 32,114,101,116,117,114,110, 32,115,
101,108,102, 46,116,114,121, 40,108,116,110, 49, 50, 46,112,117,109,112, 46, 97,
108,108, 40,115,111,117,114, 99,101, 44, 32,115,105,110,107, 44, 32,115,116,101,
112, 41, 41, 10,101,110,100, 10, 10,102,117,110, 99,116,105,111,110, 32,109,101,
116, 97,116, 46, 95, 95,105,110,100,101,120, 58, 99,108,111,115,101, 40, 41, 10,
32, 32, 32, 32,114,101,116,117,114,110, 32,115,101,108,102, 46, 99, 58, 99,108,
111,115,101, 40, 41, 10,101,110,100, 10, 10, 45, 45, 45, 45, 45, 45, 45, 45, 45,
45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45,
45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45,
45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45,
45, 45, 45, 45, 45, 45, 45, 45, 10, 45, 45, 32, 72,105,103,104, 32,108,101,118,
101,108, 32, 72, 84, 84, 80, 32, 65, 80, 73, 10, 45, 45, 45, 45, 45, 45, 45, 45,
45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45,
45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45,
45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45,
45, 45, 45, 45, 45, 45, 45, 45, 45, 10,108,111, 99, 97,108, 32,102,117,110, 99,
116,105,111,110, 32, 97,100,106,117,115,116,117,114,105, 40,114,101,113,116, 41,
10, 32, 32, 32, 32,108,111, 99, 97,108, 32,117, 32, 61, 32,114,101,113,116, 10,
32, 32, 32, 32, 45, 45, 32,105,102, 32,116,104,101,114,101, 32,105,115, 32, 97,
32,112,114,111,120,121, 44, 32,119,101, 32,110,101,101,100, 32,116,104,101, 32,
102,117,108,108, 32,117,114,108, 46, 32,111,116,104,101,114,119,105,115,101, 44,
32,106,117,115,116, 32, 97, 32,112, 97,114,116, 46, 10, 32, 32, 32, 32,105,102,
32,110,111,116, 32,114,101,113,116, 46,112,114,111,120,121, 32, 97,110,100, 32,
110,111,116, 32, 80, 82, 79, 88, 89, 32,116,104,101,110, 10, 32, 32, 32, 32, 32,
32, 32, 32,117, 32, 61, 32,123, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
112, 97,116,104, 32, 61, 32,115,111, 99,107,101,116, 46,116,114,121, 40,114,101,
113,116, 46,112, 97,116,104, 44, 32, 34,105,110,118, 97,108,105,100, 32,112, 97,
116,104, 32, 39,110,105,108, 39, 34, 41, 44, 10, 32, 32, 32, 32, 32, 32, 32, 32,
32, 32, 32,112, 97,114, 97,109,115, 32, 61, 32,114,101,113,116, 46,112, 97,114,
97,109,115, 44, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,113,117,101,114,
121, 32, 61, 32,114,101,113,116, 46,113,117,101,114,121, 44, 10, 32, 32, 32, 32,
32, 32, 32, 32, 32, 32, 32,102,114, 97,103,109,101,110,116, 32, 61, 32,114,101,
113,116, 46,102,114, 97,103,109,101,110,116, 10, 32, 32, 32, 32, 32, 32, 32, 32,
125, 10, 32, 32, 32, 32,101,110,100, 10, 32, 32, 32, 32,114,101,116,117,114,110,
32,117,114,108, 46, 98,117,105,108,100, 40,117, 41, 10,101,110,100, 10, 10,108,
111, 99, 97,108, 32,102,117,110, 99,116,105,111,110, 32, 97,100,106,117,115,116,
112,114,111,120,121, 40,114,101,113,116, 41, 10, 32, 32, 32, 32,108,111, 99, 97,
108, 32,112,114,111,120,121, 32, 61, 32,114,101,113,116, 46,112,114,111,120,121,
32,111,114, 32, 80, 82, 79, 88, 89, 10, 32, 32, 32, 32,105,102, 32,112,114,111,
120,121, 32,116,104,101,110, 10, 32, 32, 32, 32, 32, 32, 32, 32,112,114,111,120,
121, 32, 61, 32,117,114,108, 46,112, 97,114,115,101, 40,112,114,111,120,121, 41,
10, 32, 32, 32, 32, 32, 32, 32, 32,114,101,116,117,114,110, 32,112,114,111,120,
121, 46,104,111,115,116, 44, 32,112,114,111,120,121, 46,112,111,114,116, 32,111,
114, 32, 51, 49, 50, 56, 10, 32, 32, 32, 32,101,108,115,101, 10, 32, 32, 32, 32,
32, 32, 32, 32,114,101,116,117,114,110, 32,114,101,113,116, 46,104,111,115,116,
44, 32,114,101,113,116, 46,112,111,114,116, 10, 32, 32, 32, 32,101,110,100, 10,
101,110,100, 10, 10,108,111, 99, 97,108, 32,102,117,110, 99,116,105,111,110, 32,
97,100,106,117,115,116,104,101, 97,100,101,114,115, 40,114,101,113,116, 41, 10,
32, 32, 32, 32, 45, 45, 32,100,101,102, 97,117,108,116, 32,104,101, 97,100,101,
114,115, 10, 32, 32, 32, 32,108,111, 99, 97,108, 32,108,111,119,101,114, 32, 61,
32,123, 10, 32, 32, 32, 32, 32, 32, 32, 32, 91, 34,117,115,101,114, 45, 97,103,
101,110,116, 34, 93, 32, 61, 32, 85, 83, 69, 82, 65, 71, 69, 78, 84, 44, 10, 32,
32, 32, 32, 32, 32, 32, 32, 91, 34,104,111,115,116, 34, 93, 32, 61, 32,114,101,
113,116, 46,104,111,115,116, 44, 10, 32, 32, 32, 32, 32, 32, 32, 32, 91, 34, 99,
111,110,110,101, 99,116,105,111,110, 34, 93, 32, 61, 32, 34, 99,108,111,115,101,
44, 32, 84, 69, 34, 44, 10, 32, 32, 32, 32, 32, 32, 32, 32, 91, 34,116,101, 34,
93, 32, 61, 32, 34,116,114, 97,105,108,101,114,115, 34, 10, 32, 32, 32, 32,125,
10, 32, 32, 32, 32, 45, 45, 32,105,102, 32,119,101, 32,104, 97,118,101, 32, 97,
117,116,104,101,110,116,105, 99, 97,116,105,111,110, 32,105,110,102,111,114,109,
97,116,105,111,110, 44, 32,112, 97,115,115, 32,105,116, 32, 97,108,111,110,103,
10, 32, 32, 32, 32,105,102, 32,114,101,113,116, 46,117,115,101,114, 32, 97,110,
100, 32,114,101,113,116, 46,112, 97,115,115,119,111,114,100, 32,116,104,101,110,
10, 32, 32, 32, 32, 32, 32, 32, 32,108,111,119,101,114, 91, 34, 97,117,116,104,
111,114,105,122, 97,116,105,111,110, 34, 93, 32, 61, 32, 10, 32, 32, 32, 32, 32,
32, 32, 32, 32, 32, 32, 32, 34, 66, 97,115,105, 99, 32, 34, 32, 46, 46, 32, 32,
40,109,105,109,101, 46, 98, 54, 52, 40,114,101,113,116, 46,117,115,101,114, 32,
46, 46, 32, 34, 58, 34, 32, 46, 46, 32,114,101,113,116, 46,112, 97,115,115,119,
111,114,100, 41, 41, 10, 32, 32, 32, 32,101,110,100, 10, 32, 32, 32, 32, 45, 45,
32,111,118,101,114,114,105,100,101, 32,119,105,116,104, 32,117,115,101,114, 32,
104,101, 97,100,101,114,115, 10, 32, 32, 32, 32,102,111,114, 32,105, 44,118, 32,
105,110, 32, 98, 97,115,101, 46,112, 97,105,114,115, 40,114,101,113,116, 46,104,
101, 97,100,101,114,115, 32,111,114, 32,108,111,119,101,114, 41, 32,100,111, 10,
32, 32, 32, 32, 32, 32, 32, 32,108,111,119,101,114, 91,115,116,114,105,110,103,
46,108,111,119,101,114, 40,105, 41, 93, 32, 61, 32,118, 10, 32, 32, 32, 32,101,
110,100, 10, 32, 32, 32, 32,114,101,116,117,114,110, 32,108,111,119,101,114, 10,
101,110,100, 10, 10, 45, 45, 32,100,101,102, 97,117,108,116, 32,117,114,108, 32,
112, 97,114,116,115, 10,108,111, 99, 97,108, 32,100,101,102, 97,117,108,116, 32,
61, 32,123, 10, 32, 32, 32, 32,104,111,115,116, 32, 61, 32, 34, 34, 44, 10, 32,
32, 32, 32,112,111,114,116, 32, 61, 32, 80, 79, 82, 84, 44, 10, 32, 32, 32, 32,
112, 97,116,104, 32, 61, 34, 47, 34, 44, 10, 32, 32, 32, 32,115, 99,104,101,109,
101, 32, 61, 32, 34,104,116,116,112, 34, 10,125, 10, 10,108,111, 99, 97,108, 32,
102,117,110, 99,116,105,111,110, 32, 97,100,106,117,115,116,114,101,113,117,101,
115,116, 40,114,101,113,116, 41, 10, 32, 32, 32, 32, 45, 45, 32,112, 97,114,115,
101, 32,117,114,108, 32,105,102, 32,112,114,111,118,105,100,101,100, 10, 32, 32,
32, 32,108,111, 99, 97,108, 32,110,114,101,113,116, 32, 61, 32,114,101,113,116,
46,117,114,108, 32, 97,110,100, 32,117,114,108, 46,112, 97,114,115,101, 40,114,
101,113,116, 46,117,114,108, 44, 32,100,101,102, 97,117,108,116, 41, 32,111,114,
32,123,125, 10, 32, 32, 32, 32, 45, 45, 32,101,120,112,108,105, 99,105,116, 32,
99,111,109,112,111,110,101,110,116,115, 32,111,118,101,114,114,105,100,101, 32,
117,114,108, 10, 32, 32, 32, 32,102,111,114, 32,105, 44,118, 32,105,110, 32, 98,
97,115,101, 46,112, 97,105,114,115, 40,114,101,113,116, 41, 32,100,111, 32,110,
114,101,113,116, 91,105, 93, 32, 61, 32,118, 32,101,110,100, 10, 32, 32, 32, 32,
105,102, 32,110,114,101,113,116, 46,112,111,114,116, 32, 61, 61, 32, 34, 34, 32,
116,104,101,110, 32,110,114,101,113,116, 46,112,111,114,116, 32, 61, 32, 56, 48,
32,101,110,100, 10, 32, 32, 32, 32,115,111, 99,107,101,116, 46,116,114,121, 40,
110,114,101,113,116, 46,104,111,115,116, 32, 97,110,100, 32,110,114,101,113,116,
46,104,111,115,116, 32,126, 61, 32, 34, 34, 44, 32, 10, 32, 32, 32, 32, 32, 32,
32, 32, 34,105,110,118, 97,108,105,100, 32,104,111,115,116, 32, 39, 34, 32, 46,
46, 32, 98, 97,115,101, 46,116,111,115,116,114,105,110,103, 40,110,114,101,113,
116, 46,104,111,115,116, 41, 32, 46, 46, 32, 34, 39, 34, 41, 10, 32, 32, 32, 32,
45, 45, 32, 99,111,109,112,117,116,101, 32,117,114,105, 32,105,102, 32,117,115,
101,114, 32,104, 97,115,110, 39,116, 32,111,118,101,114,114,105,100,101,110, 10,
32, 32, 32, 32,110,114,101,113,116, 46,117,114,105, 32, 61, 32,114,101,113,116,
46,117,114,105, 32,111,114, 32, 97,100,106,117,115,116,117,114,105, 40,110,114,
101,113,116, 41, 10, 32, 32, 32, 32, 45, 45, 32, 97,106,117,115,116, 32,104,111,
115,116, 32, 97,110,100, 32,112,111,114,116, 32,105,102, 32,116,104,101,114,101,
32,105,115, 32, 97, 32,112,114,111,120,121, 10, 32, 32, 32, 32,110,114,101,113,
116, 46,104,111,115,116, 44, 32,110,114,101,113,116, 46,112,111,114,116, 32, 61,
32, 97,100,106,117,115,116,112,114,111,120,121, 40,110,114,101,113,116, 41, 10,
32, 32, 32, 32, 45, 45, 32, 97,100,106,117,115,116, 32,104,101, 97,100,101,114,
115, 32,105,110, 32,114,101,113,117,101,115,116, 10, 32, 32, 32, 32,110,114,101,
113,116, 46,104,101, 97,100,101,114,115, 32, 61, 32, 97,100,106,117,115,116,104,
101, 97,100,101,114,115, 40,110,114,101,113,116, 41, 10, 32, 32, 32, 32,114,101,
116,117,114,110, 32,110,114,101,113,116, 10,101,110,100, 10, 10,108,111, 99, 97,
108, 32,102,117,110, 99,116,105,111,110, 32,115,104,111,117,108,100,114,101,100,
105,114,101, 99,116, 40,114,101,113,116, 44, 32, 99,111,100,101, 44, 32,104,101,
97,100,101,114,115, 41, 10, 32, 32, 32, 32,114,101,116,117,114,110, 32,104,101,
97,100,101,114,115, 46,108,111, 99, 97,116,105,111,110, 32, 97,110,100, 10, 32,
32, 32, 32, 32, 32, 32, 32, 32, 32, 32,115,116,114,105,110,103, 46,103,115,117,
98, 40,104,101, 97,100,101,114,115, 46,108,111, 99, 97,116,105,111,110, 44, 32,
34, 37,115, 34, 44, 32, 34, 34, 41, 32,126, 61, 32, 34, 34, 32, 97,110,100, 10,
32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 40,114,101,113,116, 46,114,101,100,
105,114,101, 99,116, 32,126, 61, 32,102, 97,108,115,101, 41, 32, 97,110,100, 10,
32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 40, 99,111,100,101, 32, 61, 61, 32,
51, 48, 49, 32,111,114, 32, 99,111,100,101, 32, 61, 61, 32, 51, 48, 50, 41, 32,
97,110,100, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 40,110,111,116, 32,
114,101,113,116, 46,109,101,116,104,111,100, 32,111,114, 32,114,101,113,116, 46,
109,101,116,104,111,100, 32, 61, 61, 32, 34, 71, 69, 84, 34, 32,111,114, 32,114,
101,113,116, 46,109,101,116,104,111,100, 32, 61, 61, 32, 34, 72, 69, 65, 68, 34,
41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 97,110,100, 32, 40,110,111,
116, 32,114,101,113,116, 46,110,114,101,100,105,114,101, 99,116,115, 32,111,114,
32,114,101,113,116, 46,110,114,101,100,105,114,101, 99,116,115, 32, 60, 32, 53,
41, 10,101,110,100, 10, 10,108,111, 99, 97,108, 32,102,117,110, 99,116,105,111,
110, 32,115,104,111,117,108,100,114,101, 99,101,105,118,101, 98,111,100,121, 40,
114,101,113,116, 44, 32, 99,111,100,101, 41, 10, 32, 32, 32, 32,105,102, 32,114,
101,113,116, 46,109,101,116,104,111,100, 32, 61, 61, 32, 34, 72, 69, 65, 68, 34,
32,116,104,101,110, 32,114,101,116,117,114,110, 32,110,105,108, 32,101,110,100,
10, 32, 32, 32, 32,105,102, 32, 99,111,100,101, 32, 61, 61, 32, 50, 48, 52, 32,
111,114, 32, 99,111,100,101, 32, 61, 61, 32, 51, 48, 52, 32,116,104,101,110, 32,
114,101,116,117,114,110, 32,110,105,108, 32,101,110,100, 10, 32, 32, 32, 32,105,
102, 32, 99,111,100,101, 32, 62, 61, 32, 49, 48, 48, 32, 97,110,100, 32, 99,111,
100,101, 32, 60, 32, 50, 48, 48, 32,116,104,101,110, 32,114,101,116,117,114,110,
32,110,105,108, 32,101,110,100, 10, 32, 32, 32, 32,114,101,116,117,114,110, 32,
49, 10,101,110,100, 10, 10, 45, 45, 32,102,111,114,119, 97,114,100, 32,100,101,
99,108, 97,114, 97,116,105,111,110,115, 10,108,111, 99, 97,108, 32,116,114,101,
113,117,101,115,116, 44, 32,116,114,101,100,105,114,101, 99,116, 10, 10,102,117,
110, 99,116,105,111,110, 32,116,114,101,100,105,114,101, 99,116, 40,114,101,113,
116, 44, 32,108,111, 99, 97,116,105,111,110, 41, 10, 32, 32, 32, 32,108,111, 99,
97,108, 32,114,101,115,117,108,116, 44, 32, 99,111,100,101, 44, 32,104,101, 97,
100,101,114,115, 44, 32,115,116, 97,116,117,115, 32, 61, 32,116,114,101,113,117,
101,115,116, 32,123, 10, 32, 32, 32, 32, 32, 32, 32, 32, 45, 45, 32,116,104,101,
32, 82, 70, 67, 32,115, 97,121,115, 32,116,104,101, 32,114,101,100,105,114,101,
99,116, 32, 85, 82, 76, 32,104, 97,115, 32,116,111, 32, 98,101, 32, 97, 98,115,
111,108,117,116,101, 44, 32, 98,117,116, 32,115,111,109,101, 10, 32, 32, 32, 32,
32, 32, 32, 32, 45, 45, 32,115,101,114,118,101,114,115, 32,100,111, 32,110,111,
116, 32,114,101,115,112,101, 99,116, 32,116,104, 97,116, 10, 32, 32, 32, 32, 32,
32, 32, 32,117,114,108, 32, 61, 32,117,114,108, 46, 97, 98,115,111,108,117,116,
101, 40,114,101,113,116, 46,117,114,108, 44, 32,108,111, 99, 97,116,105,111,110,
41, 44, 10, 32, 32, 32, 32, 32, 32, 32, 32,115,111,117,114, 99,101, 32, 61, 32,
114,101,113,116, 46,115,111,117,114, 99,101, 44, 10, 32, 32, 32, 32, 32, 32, 32,
32,115,105,110,107, 32, 61, 32,114,101,113,116, 46,115,105,110,107, 44, 10, 32,
32, 32, 32, 32, 32, 32, 32,104,101, 97,100,101,114,115, 32, 61, 32,114,101,113,
116, 46,104,101, 97,100,101,114,115, 44, 10, 32, 32, 32, 32, 32, 32, 32, 32,112,
114,111,120,121, 32, 61, 32,114,101,113,116, 46,112,114,111,120,121, 44, 32, 10,
32, 32, 32, 32, 32, 32, 32, 32,110,114,101,100,105,114,101, 99,116,115, 32, 61,
32, 40,114,101,113,116, 46,110,114,101,100,105,114,101, 99,116,115, 32,111,114,
32, 48, 41, 32, 43, 32, 49, 44, 10, 32, 32, 32, 32, 32, 32, 32, 32, 99,114,101,
97,116,101, 32, 61, 32,114,101,113,116, 46, 99,114,101, 97,116,101, 10, 32, 32,
32, 32,125, 32, 32, 32, 10, 32, 32, 32, 32, 45, 45, 32,112, 97,115,115, 32,108,
111, 99, 97,116,105,111,110, 32,104,101, 97,100,101,114, 32, 98, 97, 99,107, 32,
97,115, 32, 97, 32,104,105,110,116, 32,119,101, 32,114,101,100,105,114,101, 99,
116,101,100, 10, 32, 32, 32, 32,104,101, 97,100,101,114,115, 32, 61, 32,104,101,
97,100,101,114,115, 32,111,114, 32,123,125, 10, 32, 32, 32, 32,104,101, 97,100,
101,114,115, 46,108,111, 99, 97,116,105,111,110, 32, 61, 32,104,101, 97,100,101,
114,115, 46,108,111, 99, 97,116,105,111,110, 32,111,114, 32,108,111, 99, 97,116,
105,111,110, 10, 32, 32, 32, 32,114,101,116,117,114,110, 32,114,101,115,117,108,
116, 44, 32, 99,111,100,101, 44, 32,104,101, 97,100,101,114,115, 44, 32,115,116,
97,116,117,115, 10,101,110,100, 10, 10,102,117,110, 99,116,105,111,110, 32,116,
114,101,113,117,101,115,116, 40,114,101,113,116, 41, 10, 32, 32, 32, 32, 45, 45,
32,119,101, 32,108,111,111,112, 32,117,110,116,105,108, 32,119,101, 32,103,101,
116, 32,119,104, 97,116, 32,119,101, 32,119, 97,110,116, 44, 32,111,114, 10, 32,
32, 32, 32, 45, 45, 32,117,110,116,105,108, 32,119,101, 32, 97,114,101, 32,115,
117,114,101, 32,116,104,101,114,101, 32,105,115, 32,110,111, 32,119, 97,121, 32,
116,111, 32,103,101,116, 32,105,116, 10, 32, 32, 32, 32,108,111, 99, 97,108, 32,
110,114,101,113,116, 32, 61, 32, 97,100,106,117,115,116,114,101,113,117,101,115,
116, 40,114,101,113,116, 41, 10, 32, 32, 32, 32,108,111, 99, 97,108, 32,104, 32,
61, 32,111,112,101,110, 40,110,114,101,113,116, 46,104,111,115,116, 44, 32,110,
114,101,113,116, 46,112,111,114,116, 44, 32,110,114,101,113,116, 46, 99,114,101,
97,116,101, 41, 10, 32, 32, 32, 32, 45, 45, 32,115,101,110,100, 32,114,101,113,
117,101,115,116, 32,108,105,110,101, 32, 97,110,100, 32,104,101, 97,100,101,114,
115, 10, 32, 32, 32, 32,104, 58,115,101,110,100,114,101,113,117,101,115,116,108,
105,110,101, 40,110,114,101,113,116, 46,109,101,116,104,111,100, 44, 32,110,114,
101,113,116, 46,117,114,105, 41, 10, 32, 32, 32, 32,104, 58,115,101,110,100,104,
101, 97,100,101,114,115, 40,110,114,101,113,116, 46,104,101, 97,100,101,114,115,
41, 10, 32, 32, 32, 32, 45, 45, 32,105,102, 32,116,104,101,114,101, 32,105,115,
32, 97, 32, 98,111,100,121, 44, 32,115,101,110,100, 32,105,116, 10, 32, 32, 32,
32,105,102, 32,110,114,101,113,116, 46,115,111,117,114, 99,101, 32,116,104,101,
110, 10, 32, 32, 32, 32, 32, 32, 32, 32,104, 58,115,101,110,100, 98,111,100,121,
40,110,114,101,113,116, 46,104,101, 97,100,101,114,115, 44, 32,110,114,101,113,
116, 46,115,111,117,114, 99,101, 44, 32,110,114,101,113,116, 46,115,116,101,112,
41, 32, 10, 32, 32, 32, 32,101,110,100, 10, 32, 32, 32, 32,108,111, 99, 97,108,
32, 99,111,100,101, 44, 32,115,116, 97,116,117,115, 32, 61, 32,104, 58,114,101,
99,101,105,118,101,115,116, 97,116,117,115,108,105,110,101, 40, 41, 10, 32, 32,
32, 32, 45, 45, 32,105,102, 32,105,116, 32,105,115, 32, 97,110, 32, 72, 84, 84,
80, 47, 48, 46, 57, 32,115,101,114,118,101,114, 44, 32,115,105,109,112,108,121,
32,103,101,116, 32,116,104,101, 32, 98,111,100,121, 32, 97,110,100, 32,119,101,
32, 97,114,101, 32,100,111,110,101, 10, 32, 32, 32, 32,105,102, 32,110,111,116,
32, 99,111,100,101, 32,116,104,101,110, 10, 32, 32, 32, 32, 32, 32, 32, 32,104,
58,114,101, 99,101,105,118,101, 48, 57, 98,111,100,121, 40,115,116, 97,116,117,
115, 44, 32,110,114,101,113,116, 46,115,105,110,107, 44, 32,110,114,101,113,116,
46,115,116,101,112, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32,114,101,116,117,114,
110, 32, 49, 44, 32, 50, 48, 48, 10, 32, 32, 32, 32,101,110,100, 10, 32, 32, 32,
32,108,111, 99, 97,108, 32,104,101, 97,100,101,114,115, 10, 32, 32, 32, 32, 45,
45, 32,105,103,110,111,114,101, 32, 97,110,121, 32, 49, 48, 48, 45, 99,111,110,
116,105,110,117,101, 32,109,101,115,115, 97,103,101,115, 10, 32, 32, 32, 32,119,
104,105,108,101, 32, 99,111,100,101, 32, 61, 61, 32, 49, 48, 48, 32,100,111, 32,
10, 32, 32, 32, 32, 32, 32, 32, 32,104,101, 97,100,101,114,115, 32, 61, 32,104,
58,114,101, 99,101,105,118,101,104,101, 97,100,101,114,115, 40, 41, 10, 32, 32,
32, 32, 32, 32, 32, 32, 99,111,100,101, 44, 32,115,116, 97,116,117,115, 32, 61,
32,104, 58,114,101, 99,101,105,118,101,115,116, 97,116,117,115,108,105,110,101,
40, 41, 10, 32, 32, 32, 32,101,110,100, 10, 32, 32, 32, 32,104,101, 97,100,101,
114,115, 32, 61, 32,104, 58,114,101, 99,101,105,118,101,104,101, 97,100,101,114,
115, 40, 41, 10, 32, 32, 32, 32, 45, 45, 32, 97,116, 32,116,104,105,115, 32,112,
111,105,110,116, 32,119,101, 32,115,104,111,117,108,100, 32,104, 97,118,101, 32,
97, 32,104,111,110,101,115,116, 32,114,101,112,108,121, 32,102,114,111,109, 32,
116,104,101, 32,115,101,114,118,101,114, 10, 32, 32, 32, 32, 45, 45, 32,119,101,
32, 99, 97,110, 39,116, 32,114,101,100,105,114,101, 99,116, 32,105,102, 32,119,
101, 32, 97,108,114,101, 97,100,121, 32,117,115,101,100, 32,116,104,101, 32,115,
111,117,114, 99,101, 44, 32,115,111, 32,119,101, 32,114,101,112,111,114,116, 32,
116,104,101, 32,101,114,114,111,114, 32, 10, 32, 32, 32, 32,105,102, 32,115,104,
111,117,108,100,114,101,100,105,114,101, 99,116, 40,110,114,101,113,116, 44, 32,
99,111,100,101, 44, 32,104,101, 97,100,101,114,115, 41, 32, 97,110,100, 32,110,
111,116, 32,110,114,101,113,116, 46,115,111,117,114, 99,101, 32,116,104,101,110,
10, 32, 32, 32, 32, 32, 32, 32, 32,104, 58, 99,108,111,115,101, 40, 41, 10, 32,
32, 32, 32, 32, 32, 32, 32,114,101,116,117,114,110, 32,116,114,101,100,105,114,
101, 99,116, 40,114,101,113,116, 44, 32,104,101, 97,100,101,114,115, 46,108,111,
99, 97,116,105,111,110, 41, 10, 32, 32, 32, 32,101,110,100, 10, 32, 32, 32, 32,
45, 45, 32,104,101,114,101, 32,119,101, 32, 97,114,101, 32,102,105,110, 97,108,
108,121, 32,100,111,110,101, 10, 32, 32, 32, 32,105,102, 32,115,104,111,117,108,
100,114,101, 99,101,105,118,101, 98,111,100,121, 40,110,114,101,113,116, 44, 32,
99,111,100,101, 41, 32,116,104,101,110, 10, 32, 32, 32, 32, 32, 32, 32, 32,104,
58,114,101, 99,101,105,118,101, 98,111,100,121, 40,104,101, 97,100,101,114,115,
44, 32,110,114,101,113,116, 46,115,105,110,107, 44, 32,110,114,101,113,116, 46,
115,116,101,112, 41, 10, 32, 32, 32, 32,101,110,100, 10, 32, 32, 32, 32,104, 58,
99,108,111,115,101, 40, 41, 10, 32, 32, 32, 32,114,101,116,117,114,110, 32, 49,
44, 32, 99,111,100,101, 44, 32,104,101, 97,100,101,114,115, 44, 32,115,116, 97,
116,117,115, 10,101,110,100, 10, 10,108,111, 99, 97,108, 32,102,117,110, 99,116,
105,111,110, 32,115,114,101,113,117,101,115,116, 40,117, 44, 32, 98, 41, 10, 32,
32, 32, 32,108,111, 99, 97,108, 32,116, 32, 61, 32,123,125, 10, 32, 32, 32, 32,
108,111, 99, 97,108, 32,114,101,113,116, 32, 61, 32,123, 10, 32, 32, 32, 32, 32,
32, 32, 32,117,114,108, 32, 61, 32,117, 44, 10, 32, 32, 32, 32, 32, 32, 32, 32,
115,105,110,107, 32, 61, 32,108,116,110, 49, 50, 46,115,105,110,107, 46,116, 97,
98,108,101, 40,116, 41, 10, 32, 32, 32, 32,125, 10, 32, 32, 32, 32,105,102, 32,
98, 32,116,104,101,110, 10, 32, 32, 32, 32, 32, 32, 32, 32,114,101,113,116, 46,
115,111,117,114, 99,101, 32, 61, 32,108,116,110, 49, 50, 46,115,111,117,114, 99,
101, 46,115,116,114,105,110,103, 40, 98, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32,
114,101,113,116, 46,104,101, 97,100,101,114,115, 32, 61, 32,123, 10, 32, 32, 32,
32, 32, 32, 32, 32, 32, 32, 32, 32, 91, 34, 99,111,110,116,101,110,116, 45,108,
101,110,103,116,104, 34, 93, 32, 61, 32,115,116,114,105,110,103, 46,108,101,110,
40, 98, 41, 44, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 91, 34, 99,
111,110,116,101,110,116, 45,116,121,112,101, 34, 93, 32, 61, 32, 34, 97,112,112,
108,105, 99, 97,116,105,111,110, 47,120, 45,119,119,119, 45,102,111,114,109, 45,
117,114,108,101,110, 99,111,100,101,100, 34, 10, 32, 32, 32, 32, 32, 32, 32, 32,
125, 10, 32, 32, 32, 32, 32, 32, 32, 32,114,101,113,116, 46,109,101,116,104,111,
100, 32, 61, 32, 34, 80, 79, 83, 84, 34, 10, 32, 32, 32, 32,101,110,100, 10, 32,
32, 32, 32,108,111, 99, 97,108, 32, 99,111,100,101, 44, 32,104,101, 97,100,101,
114,115, 44, 32,115,116, 97,116,117,115, 32, 61, 32,115,111, 99,107,101,116, 46,
115,107,105,112, 40, 49, 44, 32,116,114,101,113,117,101,115,116, 40,114,101,113,
116, 41, 41, 10, 32, 32, 32, 32,114,101,116,117,114,110, 32,116, 97, 98,108,101,
46, 99,111,110, 99, 97,116, 40,116, 41, 44, 32, 99,111,100,101, 44, 32,104,101,
97,100,101,114,115, 44, 32,115,116, 97,116,117,115, 10,101,110,100, 10, 10,114,
101,113,117,101,115,116, 32, 61, 32,115,111, 99,107,101,116, 46,112,114,111,116,
101, 99,116, 40,102,117,110, 99,116,105,111,110, 40,114,101,113,116, 44, 32, 98,
111,100,121, 41, 10, 32, 32, 32, 32,105,102, 32, 98, 97,115,101, 46,116,121,112,
101, 40,114,101,113,116, 41, 32, 61, 61, 32, 34,115,116,114,105,110,103, 34, 32,
116,104,101,110, 32,114,101,116,117,114,110, 32,115,114,101,113,117,101,115,116,
40,114,101,113,116, 44, 32, 98,111,100,121, 41, 10, 32, 32, 32, 32,101,108,115,
101, 32,114,101,116,117,114,110, 32,116,114,101,113,117,101,115,116, 40,114,101,
113,116, 41, 32,101,110,100, 10,101,110,100, 41, 10,
};
if (luaL_loadbuffer(L,(const char*)B1,sizeof(B1),"http.lua")==0) lua_call(L, 0, 0);
}
+281
View File
@@ -0,0 +1,281 @@
/*=========================================================================*\
* Internet domain functions
* LuaSocket toolkit
*
* RCS ID: $Id: inet.c,v 1.28 2005/10/07 04:40:59 diego Exp $
\*=========================================================================*/
#include <stdio.h>
#include <string.h>
#include "lua.h"
#include "lauxlib.h"
#include "inet.h"
/*=========================================================================*\
* Internal function prototypes.
\*=========================================================================*/
static int inet_global_toip(lua_State *L);
static int inet_global_tohostname(lua_State *L);
static void inet_pushresolved(lua_State *L, struct hostent *hp);
static int inet_global_gethostname(lua_State *L);
/* DNS functions */
static luaL_reg func[] = {
{ "toip", inet_global_toip },
{ "tohostname", inet_global_tohostname },
{ "gethostname", inet_global_gethostname},
{ NULL, NULL}
};
/*=========================================================================*\
* Exported functions
\*=========================================================================*/
/*-------------------------------------------------------------------------*\
* Initializes module
\*-------------------------------------------------------------------------*/
int inet_open(lua_State *L)
{
lua_pushstring(L, "dns");
lua_newtable(L);
luaL_openlib(L, NULL, func, 0);
lua_settable(L, -3);
return 0;
}
/*=========================================================================*\
* Global Lua functions
\*=========================================================================*/
/*-------------------------------------------------------------------------*\
* Returns all information provided by the resolver given a host name
* or ip address
\*-------------------------------------------------------------------------*/
static int inet_gethost(const char *address, struct hostent **hp) {
struct in_addr addr;
if (inet_aton(address, &addr))
return socket_gethostbyaddr((char *) &addr, sizeof(addr), hp);
else
return socket_gethostbyname(address, hp);
}
/*-------------------------------------------------------------------------*\
* Returns all information provided by the resolver given a host name
* or ip address
\*-------------------------------------------------------------------------*/
static int inet_global_tohostname(lua_State *L) {
const char *address = luaL_checkstring(L, 1);
struct hostent *hp = NULL;
int err = inet_gethost(address, &hp);
if (err != IO_DONE) {
lua_pushnil(L);
lua_pushstring(L, socket_hoststrerror(err));
return 2;
}
lua_pushstring(L, hp->h_name);
inet_pushresolved(L, hp);
return 2;
}
/*-------------------------------------------------------------------------*\
* Returns all information provided by the resolver given a host name
* or ip address
\*-------------------------------------------------------------------------*/
static int inet_global_toip(lua_State *L)
{
const char *address = luaL_checkstring(L, 1);
struct hostent *hp = NULL;
int err = inet_gethost(address, &hp);
if (err != IO_DONE) {
lua_pushnil(L);
lua_pushstring(L, socket_hoststrerror(err));
return 2;
}
lua_pushstring(L, inet_ntoa(*((struct in_addr *) hp->h_addr)));
inet_pushresolved(L, hp);
return 2;
}
/*-------------------------------------------------------------------------*\
* Gets the host name
\*-------------------------------------------------------------------------*/
static int inet_global_gethostname(lua_State *L)
{
char name[257];
name[256] = '\0';
if (gethostname(name, 256) < 0) {
lua_pushnil(L);
lua_pushstring(L, "gethostname failed");
return 2;
} else {
lua_pushstring(L, name);
return 1;
}
}
/*=========================================================================*\
* Lua methods
\*=========================================================================*/
/*-------------------------------------------------------------------------*\
* Retrieves socket peer name
\*-------------------------------------------------------------------------*/
int inet_meth_getpeername(lua_State *L, p_socket ps)
{
struct sockaddr_in peer;
socklen_t peer_len = sizeof(peer);
if (getpeername(*ps, (SA *) &peer, &peer_len) < 0) {
lua_pushnil(L);
lua_pushstring(L, "getpeername failed");
} else {
lua_pushstring(L, inet_ntoa(peer.sin_addr));
lua_pushnumber(L, ntohs(peer.sin_port));
}
return 2;
}
/*-------------------------------------------------------------------------*\
* Retrieves socket local name
\*-------------------------------------------------------------------------*/
int inet_meth_getsockname(lua_State *L, p_socket ps)
{
struct sockaddr_in local;
socklen_t local_len = sizeof(local);
if (getsockname(*ps, (SA *) &local, &local_len) < 0) {
lua_pushnil(L);
lua_pushstring(L, "getsockname failed");
} else {
lua_pushstring(L, inet_ntoa(local.sin_addr));
lua_pushnumber(L, ntohs(local.sin_port));
}
return 2;
}
/*=========================================================================*\
* Internal functions
\*=========================================================================*/
/*-------------------------------------------------------------------------*\
* Passes all resolver information to Lua as a table
\*-------------------------------------------------------------------------*/
static void inet_pushresolved(lua_State *L, struct hostent *hp)
{
char **alias;
struct in_addr **addr;
int i, resolved;
lua_newtable(L); resolved = lua_gettop(L);
lua_pushstring(L, "name");
lua_pushstring(L, hp->h_name);
lua_settable(L, resolved);
lua_pushstring(L, "ip");
lua_pushstring(L, "alias");
i = 1;
alias = hp->h_aliases;
lua_newtable(L);
if (alias) {
while (*alias) {
lua_pushnumber(L, i);
lua_pushstring(L, *alias);
lua_settable(L, -3);
i++; alias++;
}
}
lua_settable(L, resolved);
i = 1;
lua_newtable(L);
addr = (struct in_addr **) hp->h_addr_list;
if (addr) {
while (*addr) {
lua_pushnumber(L, i);
lua_pushstring(L, inet_ntoa(**addr));
lua_settable(L, -3);
i++; addr++;
}
}
lua_settable(L, resolved);
}
/*-------------------------------------------------------------------------*\
* Tries to create a new inet socket
\*-------------------------------------------------------------------------*/
const char *inet_trycreate(p_socket ps, int type) {
return socket_strerror(socket_create(ps, AF_INET, type, 0));
}
/*-------------------------------------------------------------------------*\
* Tries to connect to remote address (address, port)
\*-------------------------------------------------------------------------*/
const char *inet_tryconnect(p_socket ps, const char *address,
unsigned short port, p_timeout tm)
{
struct sockaddr_in remote;
int err;
memset(&remote, 0, sizeof(remote));
remote.sin_family = AF_INET;
remote.sin_port = htons(port);
if (strcmp(address, "*")) {
if (!inet_aton(address, &remote.sin_addr)) {
struct hostent *hp = NULL;
struct in_addr **addr;
err = socket_gethostbyname(address, &hp);
if (err != IO_DONE) return socket_hoststrerror(err);
addr = (struct in_addr **) hp->h_addr_list;
memcpy(&remote.sin_addr, *addr, sizeof(struct in_addr));
}
} else remote.sin_family = AF_UNSPEC;
err = socket_connect(ps, (SA *) &remote, sizeof(remote), tm);
return socket_strerror(err);
}
/*-------------------------------------------------------------------------*\
* Tries to bind socket to (address, port)
\*-------------------------------------------------------------------------*/
const char *inet_trybind(p_socket ps, const char *address, unsigned short port)
{
struct sockaddr_in local;
int err;
memset(&local, 0, sizeof(local));
/* address is either wildcard or a valid ip address */
local.sin_addr.s_addr = htonl(INADDR_ANY);
local.sin_port = htons(port);
local.sin_family = AF_INET;
if (strcmp(address, "*") && !inet_aton(address, &local.sin_addr)) {
struct hostent *hp = NULL;
struct in_addr **addr;
err = socket_gethostbyname(address, &hp);
if (err != IO_DONE) return socket_hoststrerror(err);
addr = (struct in_addr **) hp->h_addr_list;
memcpy(&local.sin_addr, *addr, sizeof(struct in_addr));
}
err = socket_bind(ps, (SA *) &local, sizeof(local));
if (err != IO_DONE) socket_destroy(ps);
return socket_strerror(err);
}
/*-------------------------------------------------------------------------*\
* Some systems do not provide this so that we provide our own. It's not
* marvelously fast, but it works just fine.
\*-------------------------------------------------------------------------*/
#ifdef INET_ATON
int inet_aton(const char *cp, struct in_addr *inp)
{
unsigned int a = 0, b = 0, c = 0, d = 0;
int n = 0, r;
unsigned long int addr = 0;
r = sscanf(cp, "%u.%u.%u.%u%n", &a, &b, &c, &d, &n);
if (r == 0 || n == 0) return 0;
cp += n;
if (*cp) return 0;
if (a > 255 || b > 255 || c > 255 || d > 255) return 0;
if (inp) {
addr += a; addr <<= 8;
addr += b; addr <<= 8;
addr += c; addr <<= 8;
addr += d;
inp->s_addr = htonl(addr);
}
return 1;
}
#endif
@@ -0,0 +1,42 @@
#ifndef INET_H
#define INET_H
/*=========================================================================*\
* Internet domain functions
* LuaSocket toolkit
*
* This module implements the creation and connection of internet domain
* sockets, on top of the socket.h interface, and the interface of with the
* resolver.
*
* The function inet_aton is provided for the platforms where it is not
* available. The module also implements the interface of the internet
* getpeername and getsockname functions as seen by Lua programs.
*
* The Lua functions toip and tohostname are also implemented here.
*
* RCS ID: $Id: inet.h,v 1.16 2005/10/07 04:40:59 diego Exp $
\*=========================================================================*/
#include "lua.h"
#include "socket.h"
#include "timeout.h"
#ifdef _WIN32
#define INET_ATON
#endif
int inet_open(lua_State *L);
const char *inet_trycreate(p_socket ps, int type);
const char *inet_tryconnect(p_socket ps, const char *address,
unsigned short port, p_timeout tm);
const char *inet_trybind(p_socket ps, const char *address,
unsigned short port);
int inet_meth_getpeername(lua_State *L, p_socket ps);
int inet_meth_getsockname(lua_State *L, p_socket ps);
#ifdef INET_ATON
int inet_aton(const char *cp, struct in_addr *inp);
#endif
#endif /* INET_H */
+32
View File
@@ -0,0 +1,32 @@
/*=========================================================================*\
* Input/Output abstraction
* LuaSocket toolkit
*
* RCS ID: $Id: io.c,v 1.6 2005/09/29 06:11:41 diego Exp $
\*=========================================================================*/
#include "io.h"
/*=========================================================================*\
* Exported functions
\*=========================================================================*/
/*-------------------------------------------------------------------------*\
* Initializes C structure
\*-------------------------------------------------------------------------*/
void io_init(p_io io, p_send send, p_recv recv, p_error error, void *ctx) {
io->send = send;
io->recv = recv;
io->error = error;
io->ctx = ctx;
}
/*-------------------------------------------------------------------------*\
* I/O error strings
\*-------------------------------------------------------------------------*/
const char *io_strerror(int err) {
switch (err) {
case IO_DONE: return NULL;
case IO_CLOSED: return "closed";
case IO_TIMEOUT: return "timeout";
default: return "unknown error";
}
}
+67
View File
@@ -0,0 +1,67 @@
#ifndef IO_H
#define IO_H
/*=========================================================================*\
* Input/Output abstraction
* LuaSocket toolkit
*
* This module defines the interface that LuaSocket expects from the
* transport layer for streamed input/output. The idea is that if any
* transport implements this interface, then the buffer.c functions
* automatically work on it.
*
* The module socket.h implements this interface, and thus the module tcp.h
* is very simple.
*
* RCS ID: $Id: io.h,v 1.11 2005/10/07 04:40:59 diego Exp $
\*=========================================================================*/
#include <stdio.h>
#include "lua.h"
#include "timeout.h"
/* IO error codes */
enum {
IO_DONE = 0, /* operation completed successfully */
IO_TIMEOUT = -1, /* operation timed out */
IO_CLOSED = -2, /* the connection has been closed */
IO_UNKNOWN = -3
};
/* interface to error message function */
typedef const char *(*p_error) (
void *ctx, /* context needed by send */
int err /* error code */
);
/* interface to send function */
typedef int (*p_send) (
void *ctx, /* context needed by send */
const char *data, /* pointer to buffer with data to send */
size_t count, /* number of bytes to send from buffer */
size_t *sent, /* number of bytes sent uppon return */
p_timeout tm /* timeout control */
);
/* interface to recv function */
typedef int (*p_recv) (
void *ctx, /* context needed by recv */
char *data, /* pointer to buffer where data will be writen */
size_t count, /* number of bytes to receive into buffer */
size_t *got, /* number of bytes received uppon return */
p_timeout tm /* timeout control */
);
/* IO driver definition */
typedef struct t_io_ {
void *ctx; /* context needed by send/recv */
p_send send; /* send function pointer */
p_recv recv; /* receive function pointer */
p_error error; /* strerror function */
} t_io;
typedef t_io *p_io;
void io_init(p_io io, p_send send, p_recv recv, p_error error, void *ctx);
const char *io_strerror(int err);
#endif /* IO_H */
@@ -0,0 +1,292 @@
-----------------------------------------------------------------------------
-- LTN12 - Filters, sources, sinks and pumps.
-- LuaSocket toolkit.
-- Author: Diego Nehab
-- RCS ID: $Id: ltn12.lua,v 1.31 2006/04/03 04:45:42 diego Exp $
-----------------------------------------------------------------------------
-----------------------------------------------------------------------------
-- Declare module
-----------------------------------------------------------------------------
local string = require("string")
local table = require("table")
local base = _G
module("ltn12")
filter = {}
source = {}
sink = {}
pump = {}
-- 2048 seems to be better in windows...
BLOCKSIZE = 2048
_VERSION = "LTN12 1.0.1"
-----------------------------------------------------------------------------
-- Filter stuff
-----------------------------------------------------------------------------
-- returns a high level filter that cycles a low-level filter
function filter.cycle(low, ctx, extra)
base.assert(low)
return function(chunk)
local ret
ret, ctx = low(ctx, chunk, extra)
return ret
end
end
-- chains a bunch of filters together
-- (thanks to Wim Couwenberg)
function filter.chain(...)
local n = table.getn(arg)
local top, index = 1, 1
local retry = ""
return function(chunk)
retry = chunk and retry
while true do
if index == top then
chunk = arg[index](chunk)
if chunk == "" or top == n then return chunk
elseif chunk then index = index + 1
else
top = top+1
index = top
end
else
chunk = arg[index](chunk or "")
if chunk == "" then
index = index - 1
chunk = retry
elseif chunk then
if index == n then return chunk
else index = index + 1 end
else base.error("filter returned inappropriate nil") end
end
end
end
end
-----------------------------------------------------------------------------
-- Source stuff
-----------------------------------------------------------------------------
-- create an empty source
local function empty()
return nil
end
function source.empty()
return empty
end
-- returns a source that just outputs an error
function source.error(err)
return function()
return nil, err
end
end
-- creates a file source
function source.file(handle, io_err)
if handle then
return function()
local chunk = handle:read(BLOCKSIZE)
if not chunk then handle:close() end
return chunk
end
else return source.error(io_err or "unable to open file") end
end
-- turns a fancy source into a simple source
function source.simplify(src)
base.assert(src)
return function()
local chunk, err_or_new = src()
src = err_or_new or src
if not chunk then return nil, err_or_new
else return chunk end
end
end
-- creates string source
function source.string(s)
if s then
local i = 1
return function()
local chunk = string.sub(s, i, i+BLOCKSIZE-1)
i = i + BLOCKSIZE
if chunk ~= "" then return chunk
else return nil end
end
else return source.empty() end
end
-- creates rewindable source
function source.rewind(src)
base.assert(src)
local t = {}
return function(chunk)
if not chunk then
chunk = table.remove(t)
if not chunk then return src()
else return chunk end
else
table.insert(t, chunk)
end
end
end
function source.chain(src, f)
base.assert(src and f)
local last_in, last_out = "", ""
local state = "feeding"
local err
return function()
if not last_out then
base.error('source is empty!', 2)
end
while true do
if state == "feeding" then
last_in, err = src()
if err then return nil, err end
last_out = f(last_in)
if not last_out then
if last_in then
base.error('filter returned inappropriate nil')
else
return nil
end
elseif last_out ~= "" then
state = "eating"
if last_in then last_in = "" end
return last_out
end
else
last_out = f(last_in)
if last_out == "" then
if last_in == "" then
state = "feeding"
else
base.error('filter returned ""')
end
elseif not last_out then
if last_in then
base.error('filter returned inappropriate nil')
else
return nil
end
else
return last_out
end
end
end
end
end
-- creates a source that produces contents of several sources, one after the
-- other, as if they were concatenated
-- (thanks to Wim Couwenberg)
function source.cat(...)
local src = table.remove(arg, 1)
return function()
while src do
local chunk, err = src()
if chunk then return chunk end
if err then return nil, err end
src = table.remove(arg, 1)
end
end
end
-----------------------------------------------------------------------------
-- Sink stuff
-----------------------------------------------------------------------------
-- creates a sink that stores into a table
function sink.table(t)
t = t or {}
local f = function(chunk, err)
if chunk then table.insert(t, chunk) end
return 1
end
return f, t
end
-- turns a fancy sink into a simple sink
function sink.simplify(snk)
base.assert(snk)
return function(chunk, err)
local ret, err_or_new = snk(chunk, err)
if not ret then return nil, err_or_new end
snk = err_or_new or snk
return 1
end
end
-- creates a file sink
function sink.file(handle, io_err)
if handle then
return function(chunk, err)
if not chunk then
handle:close()
return 1
else return handle:write(chunk) end
end
else return sink.error(io_err or "unable to open file") end
end
-- creates a sink that discards data
local function null()
return 1
end
function sink.null()
return null
end
-- creates a sink that just returns an error
function sink.error(err)
return function()
return nil, err
end
end
-- chains a sink with a filter
function sink.chain(f, snk)
base.assert(f and snk)
return function(chunk, err)
if chunk ~= "" then
local filtered = f(chunk)
local done = chunk and ""
while true do
local ret, snkerr = snk(filtered, err)
if not ret then return nil, snkerr end
if filtered == done then return 1 end
filtered = f(done)
end
else return 1 end
end
end
-----------------------------------------------------------------------------
-- Pump stuff
-----------------------------------------------------------------------------
-- pumps one chunk from the source to the sink
function pump.step(src, snk)
local chunk, src_err = src()
local ret, snk_err = snk(chunk, src_err)
if chunk and ret then return 1
else return nil, src_err or snk_err end
end
-- pumps all data from a source to a sink, using a step function
function pump.all(src, snk, step)
base.assert(src and snk)
step = step or pump.step
while true do
local ret, err = step(src, snk)
if not ret then
if err then return nil, err
else return 1 end
end
end
end
@@ -0,0 +1,420 @@
/* code automatically generated by bin2c -- DO NOT EDIT */
{
/* #include'ing this file in a C program is equivalent to calling
if (luaL_loadfile(L,"ltn12.lua")==0) lua_call(L, 0, 0);
*/
/* ltn12.lua */
static const unsigned char B1[]={
45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45,
45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45,
45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45,
45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 10, 45, 45,
32, 76, 84, 78, 49, 50, 32, 45, 32, 70,105,108,116,101,114,115, 44, 32,115,111,
117,114, 99,101,115, 44, 32,115,105,110,107,115, 32, 97,110,100, 32,112,117,109,
112,115, 46, 10, 45, 45, 32, 76,117, 97, 83,111, 99,107,101,116, 32,116,111,111,
108,107,105,116, 46, 10, 45, 45, 32, 65,117,116,104,111,114, 58, 32, 68,105,101,
103,111, 32, 78,101,104, 97, 98, 10, 45, 45, 32, 82, 67, 83, 32, 73, 68, 58, 32,
36, 73,100, 58, 32,108,116,110, 49, 50, 46,108,117, 97, 44,118, 32, 49, 46, 51,
49, 32, 50, 48, 48, 54, 47, 48, 52, 47, 48, 51, 32, 48, 52, 58, 52, 53, 58, 52,
50, 32,100,105,101,103,111, 32, 69,120,112, 32, 36, 10, 45, 45, 45, 45, 45, 45,
45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45,
45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45,
45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45,
45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 10, 10, 45, 45, 45, 45, 45, 45, 45,
45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45,
45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45,
45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45,
45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 10, 45, 45, 32, 68,101, 99,108, 97,114,
101, 32,109,111,100,117,108,101, 10, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45,
45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45,
45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45,
45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45,
45, 45, 45, 45, 45, 45, 10,108,111, 99, 97,108, 32,115,116,114,105,110,103, 32,
61, 32,114,101,113,117,105,114,101, 40, 34,115,116,114,105,110,103, 34, 41, 10,
108,111, 99, 97,108, 32,116, 97, 98,108,101, 32, 61, 32,114,101,113,117,105,114,
101, 40, 34,116, 97, 98,108,101, 34, 41, 10,108,111, 99, 97,108, 32, 98, 97,115,
101, 32, 61, 32, 95, 71, 10,109,111,100,117,108,101, 40, 34,108,116,110, 49, 50,
34, 41, 10, 10,102,105,108,116,101,114, 32, 61, 32,123,125, 10,115,111,117,114,
99,101, 32, 61, 32,123,125, 10,115,105,110,107, 32, 61, 32,123,125, 10,112,117,
109,112, 32, 61, 32,123,125, 10, 10, 45, 45, 32, 50, 48, 52, 56, 32,115,101,101,
109,115, 32,116,111, 32, 98,101, 32, 98,101,116,116,101,114, 32,105,110, 32,119,
105,110,100,111,119,115, 46, 46, 46, 10, 66, 76, 79, 67, 75, 83, 73, 90, 69, 32,
61, 32, 50, 48, 52, 56, 10, 95, 86, 69, 82, 83, 73, 79, 78, 32, 61, 32, 34, 76,
84, 78, 49, 50, 32, 49, 46, 48, 46, 49, 34, 10, 10, 45, 45, 45, 45, 45, 45, 45,
45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45,
45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45,
45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45,
45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 10, 45, 45, 32, 70,105,108,116,101,114,
32,115,116,117,102,102, 10, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45,
45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45,
45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45,
45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45,
45, 45, 45, 45, 10, 45, 45, 32,114,101,116,117,114,110,115, 32, 97, 32,104,105,
103,104, 32,108,101,118,101,108, 32,102,105,108,116,101,114, 32,116,104, 97,116,
32, 99,121, 99,108,101,115, 32, 97, 32,108,111,119, 45,108,101,118,101,108, 32,
102,105,108,116,101,114, 10,102,117,110, 99,116,105,111,110, 32,102,105,108,116,
101,114, 46, 99,121, 99,108,101, 40,108,111,119, 44, 32, 99,116,120, 44, 32,101,
120,116,114, 97, 41, 10, 32, 32, 32, 32, 98, 97,115,101, 46, 97,115,115,101,114,
116, 40,108,111,119, 41, 10, 32, 32, 32, 32,114,101,116,117,114,110, 32,102,117,
110, 99,116,105,111,110, 40, 99,104,117,110,107, 41, 10, 32, 32, 32, 32, 32, 32,
32, 32,108,111, 99, 97,108, 32,114,101,116, 10, 32, 32, 32, 32, 32, 32, 32, 32,
114,101,116, 44, 32, 99,116,120, 32, 61, 32,108,111,119, 40, 99,116,120, 44, 32,
99,104,117,110,107, 44, 32,101,120,116,114, 97, 41, 10, 32, 32, 32, 32, 32, 32,
32, 32,114,101,116,117,114,110, 32,114,101,116, 10, 32, 32, 32, 32,101,110,100,
10,101,110,100, 10, 10, 45, 45, 32, 99,104, 97,105,110,115, 32, 97, 32, 98,117,
110, 99,104, 32,111,102, 32,102,105,108,116,101,114,115, 32,116,111,103,101,116,
104,101,114, 10, 45, 45, 32, 40,116,104, 97,110,107,115, 32,116,111, 32, 87,105,
109, 32, 67,111,117,119,101,110, 98,101,114,103, 41, 10,102,117,110, 99,116,105,
111,110, 32,102,105,108,116,101,114, 46, 99,104, 97,105,110, 40, 46, 46, 46, 41,
10, 32, 32, 32, 32,108,111, 99, 97,108, 32,110, 32, 61, 32,116, 97, 98,108,101,
46,103,101,116,110, 40, 97,114,103, 41, 10, 32, 32, 32, 32,108,111, 99, 97,108,
32,116,111,112, 44, 32,105,110,100,101,120, 32, 61, 32, 49, 44, 32, 49, 10, 32,
32, 32, 32,108,111, 99, 97,108, 32,114,101,116,114,121, 32, 61, 32, 34, 34, 10,
32, 32, 32, 32,114,101,116,117,114,110, 32,102,117,110, 99,116,105,111,110, 40,
99,104,117,110,107, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32,114,101,116,114,121,
32, 61, 32, 99,104,117,110,107, 32, 97,110,100, 32,114,101,116,114,121, 10, 32,
32, 32, 32, 32, 32, 32, 32,119,104,105,108,101, 32,116,114,117,101, 32,100,111,
10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,105,102, 32,105,110,100,101,
120, 32, 61, 61, 32,116,111,112, 32,116,104,101,110, 10, 32, 32, 32, 32, 32, 32,
32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 99,104,117,110,107, 32, 61, 32, 97,114,
103, 91,105,110,100,101,120, 93, 40, 99,104,117,110,107, 41, 10, 32, 32, 32, 32,
32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,105,102, 32, 99,104,117,110,107,
32, 61, 61, 32, 34, 34, 32,111,114, 32,116,111,112, 32, 61, 61, 32,110, 32,116,
104,101,110, 32,114,101,116,117,114,110, 32, 99,104,117,110,107, 10, 32, 32, 32,
32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,101,108,115,101,105,102, 32,
99,104,117,110,107, 32,116,104,101,110, 32,105,110,100,101,120, 32, 61, 32,105,
110,100,101,120, 32, 43, 32, 49, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
32, 32, 32, 32, 32,101,108,115,101, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
32, 32, 32, 32, 32, 32, 32, 32, 32, 32,116,111,112, 32, 61, 32,116,111,112, 43,
49, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
32, 32,105,110,100,101,120, 32, 61, 32,116,111,112, 10, 32, 32, 32, 32, 32, 32,
32, 32, 32, 32, 32, 32, 32, 32, 32, 32,101,110,100, 10, 32, 32, 32, 32, 32, 32,
32, 32, 32, 32, 32, 32,101,108,115,101, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32,
32, 32, 32, 32, 32, 32, 32, 99,104,117,110,107, 32, 61, 32, 97,114,103, 91,105,
110,100,101,120, 93, 40, 99,104,117,110,107, 32,111,114, 32, 34, 34, 41, 10, 32,
32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,105,102, 32, 99,104,
117,110,107, 32, 61, 61, 32, 34, 34, 32,116,104,101,110, 10, 32, 32, 32, 32, 32,
32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,105,110,100,101,120,
32, 61, 32,105,110,100,101,120, 32, 45, 32, 49, 10, 32, 32, 32, 32, 32, 32, 32,
32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 99,104,117,110,107, 32, 61,
32,114,101,116,114,121, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
32, 32, 32,101,108,115,101,105,102, 32, 99,104,117,110,107, 32,116,104,101,110,
10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
32,105,102, 32,105,110,100,101,120, 32, 61, 61, 32,110, 32,116,104,101,110, 32,
114,101,116,117,114,110, 32, 99,104,117,110,107, 10, 32, 32, 32, 32, 32, 32, 32,
32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,101,108,115,101, 32,105,110,
100,101,120, 32, 61, 32,105,110,100,101,120, 32, 43, 32, 49, 32,101,110,100, 10,
32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,101,108,115,101,
32, 98, 97,115,101, 46,101,114,114,111,114, 40, 34,102,105,108,116,101,114, 32,
114,101,116,117,114,110,101,100, 32,105,110, 97,112,112,114,111,112,114,105, 97,
116,101, 32,110,105,108, 34, 41, 32,101,110,100, 10, 32, 32, 32, 32, 32, 32, 32,
32, 32, 32, 32, 32,101,110,100, 10, 32, 32, 32, 32, 32, 32, 32, 32,101,110,100,
10, 32, 32, 32, 32,101,110,100, 10,101,110,100, 10, 10, 45, 45, 45, 45, 45, 45,
45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45,
45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45,
45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45,
45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 10, 45, 45, 32, 83,111,117,114, 99,
101, 32,115,116,117,102,102, 10, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45,
45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45,
45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45,
45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45,
45, 45, 45, 45, 45, 10, 45, 45, 32, 99,114,101, 97,116,101, 32, 97,110, 32,101,
109,112,116,121, 32,115,111,117,114, 99,101, 10,108,111, 99, 97,108, 32,102,117,
110, 99,116,105,111,110, 32,101,109,112,116,121, 40, 41, 10, 32, 32, 32, 32,114,
101,116,117,114,110, 32,110,105,108, 10,101,110,100, 10, 10,102,117,110, 99,116,
105,111,110, 32,115,111,117,114, 99,101, 46,101,109,112,116,121, 40, 41, 10, 32,
32, 32, 32,114,101,116,117,114,110, 32,101,109,112,116,121, 10,101,110,100, 10,
10, 45, 45, 32,114,101,116,117,114,110,115, 32, 97, 32,115,111,117,114, 99,101,
32,116,104, 97,116, 32,106,117,115,116, 32,111,117,116,112,117,116,115, 32, 97,
110, 32,101,114,114,111,114, 10,102,117,110, 99,116,105,111,110, 32,115,111,117,
114, 99,101, 46,101,114,114,111,114, 40,101,114,114, 41, 10, 32, 32, 32, 32,114,
101,116,117,114,110, 32,102,117,110, 99,116,105,111,110, 40, 41, 10, 32, 32, 32,
32, 32, 32, 32, 32,114,101,116,117,114,110, 32,110,105,108, 44, 32,101,114,114,
10, 32, 32, 32, 32,101,110,100, 10,101,110,100, 10, 10, 45, 45, 32, 99,114,101,
97,116,101,115, 32, 97, 32,102,105,108,101, 32,115,111,117,114, 99,101, 10,102,
117,110, 99,116,105,111,110, 32,115,111,117,114, 99,101, 46,102,105,108,101, 40,
104, 97,110,100,108,101, 44, 32,105,111, 95,101,114,114, 41, 10, 32, 32, 32, 32,
105,102, 32,104, 97,110,100,108,101, 32,116,104,101,110, 10, 32, 32, 32, 32, 32,
32, 32, 32,114,101,116,117,114,110, 32,102,117,110, 99,116,105,111,110, 40, 41,
10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,108,111, 99, 97,108, 32, 99,
104,117,110,107, 32, 61, 32,104, 97,110,100,108,101, 58,114,101, 97,100, 40, 66,
76, 79, 67, 75, 83, 73, 90, 69, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
32, 32,105,102, 32,110,111,116, 32, 99,104,117,110,107, 32,116,104,101,110, 32,
104, 97,110,100,108,101, 58, 99,108,111,115,101, 40, 41, 32,101,110,100, 10, 32,
32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,114,101,116,117,114,110, 32, 99,104,
117,110,107, 10, 32, 32, 32, 32, 32, 32, 32, 32,101,110,100, 10, 32, 32, 32, 32,
101,108,115,101, 32,114,101,116,117,114,110, 32,115,111,117,114, 99,101, 46,101,
114,114,111,114, 40,105,111, 95,101,114,114, 32,111,114, 32, 34,117,110, 97, 98,
108,101, 32,116,111, 32,111,112,101,110, 32,102,105,108,101, 34, 41, 32,101,110,
100, 10,101,110,100, 10, 10, 45, 45, 32,116,117,114,110,115, 32, 97, 32,102, 97,
110, 99,121, 32,115,111,117,114, 99,101, 32,105,110,116,111, 32, 97, 32,115,105,
109,112,108,101, 32,115,111,117,114, 99,101, 10,102,117,110, 99,116,105,111,110,
32,115,111,117,114, 99,101, 46,115,105,109,112,108,105,102,121, 40,115,114, 99,
41, 10, 32, 32, 32, 32, 98, 97,115,101, 46, 97,115,115,101,114,116, 40,115,114,
99, 41, 10, 32, 32, 32, 32,114,101,116,117,114,110, 32,102,117,110, 99,116,105,
111,110, 40, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32,108,111, 99, 97,108, 32, 99,
104,117,110,107, 44, 32,101,114,114, 95,111,114, 95,110,101,119, 32, 61, 32,115,
114, 99, 40, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32,115,114, 99, 32, 61, 32,101,
114,114, 95,111,114, 95,110,101,119, 32,111,114, 32,115,114, 99, 10, 32, 32, 32,
32, 32, 32, 32, 32,105,102, 32,110,111,116, 32, 99,104,117,110,107, 32,116,104,
101,110, 32,114,101,116,117,114,110, 32,110,105,108, 44, 32,101,114,114, 95,111,
114, 95,110,101,119, 10, 32, 32, 32, 32, 32, 32, 32, 32,101,108,115,101, 32,114,
101,116,117,114,110, 32, 99,104,117,110,107, 32,101,110,100, 10, 32, 32, 32, 32,
101,110,100, 10,101,110,100, 10, 10, 45, 45, 32, 99,114,101, 97,116,101,115, 32,
115,116,114,105,110,103, 32,115,111,117,114, 99,101, 10,102,117,110, 99,116,105,
111,110, 32,115,111,117,114, 99,101, 46,115,116,114,105,110,103, 40,115, 41, 10,
32, 32, 32, 32,105,102, 32,115, 32,116,104,101,110, 10, 32, 32, 32, 32, 32, 32,
32, 32,108,111, 99, 97,108, 32,105, 32, 61, 32, 49, 10, 32, 32, 32, 32, 32, 32,
32, 32,114,101,116,117,114,110, 32,102,117,110, 99,116,105,111,110, 40, 41, 10,
32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,108,111, 99, 97,108, 32, 99,104,
117,110,107, 32, 61, 32,115,116,114,105,110,103, 46,115,117, 98, 40,115, 44, 32,
105, 44, 32,105, 43, 66, 76, 79, 67, 75, 83, 73, 90, 69, 45, 49, 41, 10, 32, 32,
32, 32, 32, 32, 32, 32, 32, 32, 32, 32,105, 32, 61, 32,105, 32, 43, 32, 66, 76,
79, 67, 75, 83, 73, 90, 69, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
105,102, 32, 99,104,117,110,107, 32,126, 61, 32, 34, 34, 32,116,104,101,110, 32,
114,101,116,117,114,110, 32, 99,104,117,110,107, 10, 32, 32, 32, 32, 32, 32, 32,
32, 32, 32, 32, 32,101,108,115,101, 32,114,101,116,117,114,110, 32,110,105,108,
32,101,110,100, 10, 32, 32, 32, 32, 32, 32, 32, 32,101,110,100, 10, 32, 32, 32,
32,101,108,115,101, 32,114,101,116,117,114,110, 32,115,111,117,114, 99,101, 46,
101,109,112,116,121, 40, 41, 32,101,110,100, 10,101,110,100, 10, 10, 45, 45, 32,
99,114,101, 97,116,101,115, 32,114,101,119,105,110,100, 97, 98,108,101, 32,115,
111,117,114, 99,101, 10,102,117,110, 99,116,105,111,110, 32,115,111,117,114, 99,
101, 46,114,101,119,105,110,100, 40,115,114, 99, 41, 10, 32, 32, 32, 32, 98, 97,
115,101, 46, 97,115,115,101,114,116, 40,115,114, 99, 41, 10, 32, 32, 32, 32,108,
111, 99, 97,108, 32,116, 32, 61, 32,123,125, 10, 32, 32, 32, 32,114,101,116,117,
114,110, 32,102,117,110, 99,116,105,111,110, 40, 99,104,117,110,107, 41, 10, 32,
32, 32, 32, 32, 32, 32, 32,105,102, 32,110,111,116, 32, 99,104,117,110,107, 32,
116,104,101,110, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 99,104,117,
110,107, 32, 61, 32,116, 97, 98,108,101, 46,114,101,109,111,118,101, 40,116, 41,
10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,105,102, 32,110,111,116, 32,
99,104,117,110,107, 32,116,104,101,110, 32,114,101,116,117,114,110, 32,115,114,
99, 40, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,101,108,115,101,
32,114,101,116,117,114,110, 32, 99,104,117,110,107, 32,101,110,100, 10, 32, 32,
32, 32, 32, 32, 32, 32,101,108,115,101, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32,
32, 32, 32,116, 97, 98,108,101, 46,105,110,115,101,114,116, 40,116, 44, 32, 99,
104,117,110,107, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32,101,110,100, 10, 32, 32,
32, 32,101,110,100, 10,101,110,100, 10, 10,102,117,110, 99,116,105,111,110, 32,
115,111,117,114, 99,101, 46, 99,104, 97,105,110, 40,115,114, 99, 44, 32,102, 41,
10, 32, 32, 32, 32, 98, 97,115,101, 46, 97,115,115,101,114,116, 40,115,114, 99,
32, 97,110,100, 32,102, 41, 10, 32, 32, 32, 32,108,111, 99, 97,108, 32,108, 97,
115,116, 95,105,110, 44, 32,108, 97,115,116, 95,111,117,116, 32, 61, 32, 34, 34,
44, 32, 34, 34, 10, 32, 32, 32, 32,108,111, 99, 97,108, 32,115,116, 97,116,101,
32, 61, 32, 34,102,101,101,100,105,110,103, 34, 10, 32, 32, 32, 32,108,111, 99,
97,108, 32,101,114,114, 10, 32, 32, 32, 32,114,101,116,117,114,110, 32,102,117,
110, 99,116,105,111,110, 40, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32,105,102, 32,
110,111,116, 32,108, 97,115,116, 95,111,117,116, 32,116,104,101,110, 10, 32, 32,
32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 98, 97,115,101, 46,101,114,114,111,114,
40, 39,115,111,117,114, 99,101, 32,105,115, 32,101,109,112,116,121, 33, 39, 44,
32, 50, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32,101,110,100, 10, 32, 32, 32, 32,
32, 32, 32, 32,119,104,105,108,101, 32,116,114,117,101, 32,100,111, 10, 32, 32,
32, 32, 32, 32, 32, 32, 32, 32, 32, 32,105,102, 32,115,116, 97,116,101, 32, 61,
61, 32, 34,102,101,101,100,105,110,103, 34, 32,116,104,101,110, 10, 32, 32, 32,
32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,108, 97,115,116, 95,105,110,
44, 32,101,114,114, 32, 61, 32,115,114, 99, 40, 41, 10, 32, 32, 32, 32, 32, 32,
32, 32, 32, 32, 32, 32, 32, 32, 32, 32,105,102, 32,101,114,114, 32,116,104,101,
110, 32,114,101,116,117,114,110, 32,110,105,108, 44, 32,101,114,114, 32,101,110,
100, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,108, 97,
115,116, 95,111,117,116, 32, 61, 32,102, 40,108, 97,115,116, 95,105,110, 41, 10,
32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,105,102, 32,110,
111,116, 32,108, 97,115,116, 95,111,117,116, 32,116,104,101,110, 10, 32, 32, 32,
32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,105,102, 32,
108, 97,115,116, 95,105,110, 32,116,104,101,110, 10, 32, 32, 32, 32, 32, 32, 32,
32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 98, 97,115,
101, 46,101,114,114,111,114, 40, 39,102,105,108,116,101,114, 32,114,101,116,117,
114,110,101,100, 32,105,110, 97,112,112,114,111,112,114,105, 97,116,101, 32,110,
105,108, 39, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
32, 32, 32, 32, 32,101,108,115,101, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,114,101,116,117,114,110,
32,110,105,108, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
32, 32, 32, 32, 32,101,110,100, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
32, 32, 32, 32, 32,101,108,115,101,105,102, 32,108, 97,115,116, 95,111,117,116,
32,126, 61, 32, 34, 34, 32,116,104,101,110, 10, 32, 32, 32, 32, 32, 32, 32, 32,
32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,115,116, 97,116,101, 32, 61, 32,
34,101, 97,116,105,110,103, 34, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
32, 32, 32, 32, 32, 32, 32, 32, 32,105,102, 32,108, 97,115,116, 95,105,110, 32,
116,104,101,110, 32,108, 97,115,116, 95,105,110, 32, 61, 32, 34, 34, 32,101,110,
100, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
32, 32,114,101,116,117,114,110, 32,108, 97,115,116, 95,111,117,116, 10, 32, 32,
32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,101,110,100, 10, 32, 32,
32, 32, 32, 32, 32, 32, 32, 32, 32, 32,101,108,115,101, 10, 32, 32, 32, 32, 32,
32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,108, 97,115,116, 95,111,117,116, 32,
61, 32,102, 40,108, 97,115,116, 95,105,110, 41, 10, 32, 32, 32, 32, 32, 32, 32,
32, 32, 32, 32, 32, 32, 32, 32, 32,105,102, 32,108, 97,115,116, 95,111,117,116,
32, 61, 61, 32, 34, 34, 32,116,104,101,110, 10, 32, 32, 32, 32, 32, 32, 32, 32,
32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,105,102, 32,108, 97,115,116, 95,
105,110, 32, 61, 61, 32, 34, 34, 32,116,104,101,110, 10, 32, 32, 32, 32, 32, 32,
32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,115,116,
97,116,101, 32, 61, 32, 34,102,101,101,100,105,110,103, 34, 10, 32, 32, 32, 32,
32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,101,108,115,101,
10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
32, 32, 32, 32, 32, 98, 97,115,101, 46,101,114,114,111,114, 40, 39,102,105,108,
116,101,114, 32,114,101,116,117,114,110,101,100, 32, 34, 34, 39, 41, 10, 32, 32,
32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,101,110,
100, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,101,108,
115,101,105,102, 32,110,111,116, 32,108, 97,115,116, 95,111,117,116, 32,116,104,
101,110, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
32, 32, 32,105,102, 32,108, 97,115,116, 95,105,110, 32,116,104,101,110, 10, 32,
32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
32, 32, 32, 98, 97,115,101, 46,101,114,114,111,114, 40, 39,102,105,108,116,101,
114, 32,114,101,116,117,114,110,101,100, 32,105,110, 97,112,112,114,111,112,114,
105, 97,116,101, 32,110,105,108, 39, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32,
32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,101,108,115,101, 10, 32, 32, 32, 32,
32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
114,101,116,117,114,110, 32,110,105,108, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32,
32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,101,110,100, 10, 32, 32, 32, 32, 32,
32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,101,108,115,101, 10, 32, 32, 32, 32,
32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,114,101,116,117,
114,110, 32,108, 97,115,116, 95,111,117,116, 10, 32, 32, 32, 32, 32, 32, 32, 32,
32, 32, 32, 32, 32, 32, 32, 32,101,110,100, 10, 32, 32, 32, 32, 32, 32, 32, 32,
32, 32, 32, 32,101,110,100, 10, 32, 32, 32, 32, 32, 32, 32, 32,101,110,100, 10,
32, 32, 32, 32,101,110,100, 10,101,110,100, 10, 10, 45, 45, 32, 99,114,101, 97,
116,101,115, 32, 97, 32,115,111,117,114, 99,101, 32,116,104, 97,116, 32,112,114,
111,100,117, 99,101,115, 32, 99,111,110,116,101,110,116,115, 32,111,102, 32,115,
101,118,101,114, 97,108, 32,115,111,117,114, 99,101,115, 44, 32,111,110,101, 32,
97,102,116,101,114, 32,116,104,101, 10, 45, 45, 32,111,116,104,101,114, 44, 32,
97,115, 32,105,102, 32,116,104,101,121, 32,119,101,114,101, 32, 99,111,110, 99,
97,116,101,110, 97,116,101,100, 10, 45, 45, 32, 40,116,104, 97,110,107,115, 32,
116,111, 32, 87,105,109, 32, 67,111,117,119,101,110, 98,101,114,103, 41, 10,102,
117,110, 99,116,105,111,110, 32,115,111,117,114, 99,101, 46, 99, 97,116, 40, 46,
46, 46, 41, 10, 32, 32, 32, 32,108,111, 99, 97,108, 32,115,114, 99, 32, 61, 32,
116, 97, 98,108,101, 46,114,101,109,111,118,101, 40, 97,114,103, 44, 32, 49, 41,
10, 32, 32, 32, 32,114,101,116,117,114,110, 32,102,117,110, 99,116,105,111,110,
40, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32,119,104,105,108,101, 32,115,114, 99,
32,100,111, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,108,111, 99, 97,
108, 32, 99,104,117,110,107, 44, 32,101,114,114, 32, 61, 32,115,114, 99, 40, 41,
10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,105,102, 32, 99,104,117,110,
107, 32,116,104,101,110, 32,114,101,116,117,114,110, 32, 99,104,117,110,107, 32,
101,110,100, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,105,102, 32,101,
114,114, 32,116,104,101,110, 32,114,101,116,117,114,110, 32,110,105,108, 44, 32,
101,114,114, 32,101,110,100, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
115,114, 99, 32, 61, 32,116, 97, 98,108,101, 46,114,101,109,111,118,101, 40, 97,
114,103, 44, 32, 49, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32,101,110,100, 10, 32,
32, 32, 32,101,110,100, 10,101,110,100, 10, 10, 45, 45, 45, 45, 45, 45, 45, 45,
45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45,
45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45,
45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45,
45, 45, 45, 45, 45, 45, 45, 45, 45, 10, 45, 45, 32, 83,105,110,107, 32,115,116,
117,102,102, 10, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45,
45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45,
45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45,
45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45,
45, 10, 45, 45, 32, 99,114,101, 97,116,101,115, 32, 97, 32,115,105,110,107, 32,
116,104, 97,116, 32,115,116,111,114,101,115, 32,105,110,116,111, 32, 97, 32,116,
97, 98,108,101, 10,102,117,110, 99,116,105,111,110, 32,115,105,110,107, 46,116,
97, 98,108,101, 40,116, 41, 10, 32, 32, 32, 32,116, 32, 61, 32,116, 32,111,114,
32,123,125, 10, 32, 32, 32, 32,108,111, 99, 97,108, 32,102, 32, 61, 32,102,117,
110, 99,116,105,111,110, 40, 99,104,117,110,107, 44, 32,101,114,114, 41, 10, 32,
32, 32, 32, 32, 32, 32, 32,105,102, 32, 99,104,117,110,107, 32,116,104,101,110,
32,116, 97, 98,108,101, 46,105,110,115,101,114,116, 40,116, 44, 32, 99,104,117,
110,107, 41, 32,101,110,100, 10, 32, 32, 32, 32, 32, 32, 32, 32,114,101,116,117,
114,110, 32, 49, 10, 32, 32, 32, 32,101,110,100, 10, 32, 32, 32, 32,114,101,116,
117,114,110, 32,102, 44, 32,116, 10,101,110,100, 10, 10, 45, 45, 32,116,117,114,
110,115, 32, 97, 32,102, 97,110, 99,121, 32,115,105,110,107, 32,105,110,116,111,
32, 97, 32,115,105,109,112,108,101, 32,115,105,110,107, 10,102,117,110, 99,116,
105,111,110, 32,115,105,110,107, 46,115,105,109,112,108,105,102,121, 40,115,110,
107, 41, 10, 32, 32, 32, 32, 98, 97,115,101, 46, 97,115,115,101,114,116, 40,115,
110,107, 41, 10, 32, 32, 32, 32,114,101,116,117,114,110, 32,102,117,110, 99,116,
105,111,110, 40, 99,104,117,110,107, 44, 32,101,114,114, 41, 10, 32, 32, 32, 32,
32, 32, 32, 32,108,111, 99, 97,108, 32,114,101,116, 44, 32,101,114,114, 95,111,
114, 95,110,101,119, 32, 61, 32,115,110,107, 40, 99,104,117,110,107, 44, 32,101,
114,114, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32,105,102, 32,110,111,116, 32,114,
101,116, 32,116,104,101,110, 32,114,101,116,117,114,110, 32,110,105,108, 44, 32,
101,114,114, 95,111,114, 95,110,101,119, 32,101,110,100, 10, 32, 32, 32, 32, 32,
32, 32, 32,115,110,107, 32, 61, 32,101,114,114, 95,111,114, 95,110,101,119, 32,
111,114, 32,115,110,107, 10, 32, 32, 32, 32, 32, 32, 32, 32,114,101,116,117,114,
110, 32, 49, 10, 32, 32, 32, 32,101,110,100, 10,101,110,100, 10, 10, 45, 45, 32,
99,114,101, 97,116,101,115, 32, 97, 32,102,105,108,101, 32,115,105,110,107, 10,
102,117,110, 99,116,105,111,110, 32,115,105,110,107, 46,102,105,108,101, 40,104,
97,110,100,108,101, 44, 32,105,111, 95,101,114,114, 41, 10, 32, 32, 32, 32,105,
102, 32,104, 97,110,100,108,101, 32,116,104,101,110, 10, 32, 32, 32, 32, 32, 32,
32, 32,114,101,116,117,114,110, 32,102,117,110, 99,116,105,111,110, 40, 99,104,
117,110,107, 44, 32,101,114,114, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
32, 32,105,102, 32,110,111,116, 32, 99,104,117,110,107, 32,116,104,101,110, 10,
32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,104, 97,110,100,
108,101, 58, 99,108,111,115,101, 40, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32,
32, 32, 32, 32, 32, 32, 32,114,101,116,117,114,110, 32, 49, 10, 32, 32, 32, 32,
32, 32, 32, 32, 32, 32, 32, 32,101,108,115,101, 32,114,101,116,117,114,110, 32,
104, 97,110,100,108,101, 58,119,114,105,116,101, 40, 99,104,117,110,107, 41, 32,
101,110,100, 10, 32, 32, 32, 32, 32, 32, 32, 32,101,110,100, 10, 32, 32, 32, 32,
101,108,115,101, 32,114,101,116,117,114,110, 32,115,105,110,107, 46,101,114,114,
111,114, 40,105,111, 95,101,114,114, 32,111,114, 32, 34,117,110, 97, 98,108,101,
32,116,111, 32,111,112,101,110, 32,102,105,108,101, 34, 41, 32,101,110,100, 10,
101,110,100, 10, 10, 45, 45, 32, 99,114,101, 97,116,101,115, 32, 97, 32,115,105,
110,107, 32,116,104, 97,116, 32,100,105,115, 99, 97,114,100,115, 32,100, 97,116,
97, 10,108,111, 99, 97,108, 32,102,117,110, 99,116,105,111,110, 32,110,117,108,
108, 40, 41, 10, 32, 32, 32, 32,114,101,116,117,114,110, 32, 49, 10,101,110,100,
10, 10,102,117,110, 99,116,105,111,110, 32,115,105,110,107, 46,110,117,108,108,
40, 41, 10, 32, 32, 32, 32,114,101,116,117,114,110, 32,110,117,108,108, 10,101,
110,100, 10, 10, 45, 45, 32, 99,114,101, 97,116,101,115, 32, 97, 32,115,105,110,
107, 32,116,104, 97,116, 32,106,117,115,116, 32,114,101,116,117,114,110,115, 32,
97,110, 32,101,114,114,111,114, 10,102,117,110, 99,116,105,111,110, 32,115,105,
110,107, 46,101,114,114,111,114, 40,101,114,114, 41, 10, 32, 32, 32, 32,114,101,
116,117,114,110, 32,102,117,110, 99,116,105,111,110, 40, 41, 10, 32, 32, 32, 32,
32, 32, 32, 32,114,101,116,117,114,110, 32,110,105,108, 44, 32,101,114,114, 10,
32, 32, 32, 32,101,110,100, 10,101,110,100, 10, 10, 45, 45, 32, 99,104, 97,105,
110,115, 32, 97, 32,115,105,110,107, 32,119,105,116,104, 32, 97, 32,102,105,108,
116,101,114, 10,102,117,110, 99,116,105,111,110, 32,115,105,110,107, 46, 99,104,
97,105,110, 40,102, 44, 32,115,110,107, 41, 10, 32, 32, 32, 32, 98, 97,115,101,
46, 97,115,115,101,114,116, 40,102, 32, 97,110,100, 32,115,110,107, 41, 10, 32,
32, 32, 32,114,101,116,117,114,110, 32,102,117,110, 99,116,105,111,110, 40, 99,
104,117,110,107, 44, 32,101,114,114, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32,105,
102, 32, 99,104,117,110,107, 32,126, 61, 32, 34, 34, 32,116,104,101,110, 10, 32,
32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,108,111, 99, 97,108, 32,102,105,108,
116,101,114,101,100, 32, 61, 32,102, 40, 99,104,117,110,107, 41, 10, 32, 32, 32,
32, 32, 32, 32, 32, 32, 32, 32, 32,108,111, 99, 97,108, 32,100,111,110,101, 32,
61, 32, 99,104,117,110,107, 32, 97,110,100, 32, 34, 34, 10, 32, 32, 32, 32, 32,
32, 32, 32, 32, 32, 32, 32,119,104,105,108,101, 32,116,114,117,101, 32,100,111,
10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,108,111, 99,
97,108, 32,114,101,116, 44, 32,115,110,107,101,114,114, 32, 61, 32,115,110,107,
40,102,105,108,116,101,114,101,100, 44, 32,101,114,114, 41, 10, 32, 32, 32, 32,
32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,105,102, 32,110,111,116, 32,114,
101,116, 32,116,104,101,110, 32,114,101,116,117,114,110, 32,110,105,108, 44, 32,
115,110,107,101,114,114, 32,101,110,100, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32,
32, 32, 32, 32, 32, 32, 32,105,102, 32,102,105,108,116,101,114,101,100, 32, 61,
61, 32,100,111,110,101, 32,116,104,101,110, 32,114,101,116,117,114,110, 32, 49,
32,101,110,100, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
32,102,105,108,116,101,114,101,100, 32, 61, 32,102, 40,100,111,110,101, 41, 10,
32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,101,110,100, 10, 32, 32, 32, 32,
32, 32, 32, 32,101,108,115,101, 32,114,101,116,117,114,110, 32, 49, 32,101,110,
100, 10, 32, 32, 32, 32,101,110,100, 10,101,110,100, 10, 10, 45, 45, 45, 45, 45,
45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45,
45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45,
45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45,
45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 10, 45, 45, 32, 80,117,109,112,
32,115,116,117,102,102, 10, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45,
45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45,
45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45,
45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45,
45, 45, 45, 45, 10, 45, 45, 32,112,117,109,112,115, 32,111,110,101, 32, 99,104,
117,110,107, 32,102,114,111,109, 32,116,104,101, 32,115,111,117,114, 99,101, 32,
116,111, 32,116,104,101, 32,115,105,110,107, 10,102,117,110, 99,116,105,111,110,
32,112,117,109,112, 46,115,116,101,112, 40,115,114, 99, 44, 32,115,110,107, 41,
10, 32, 32, 32, 32,108,111, 99, 97,108, 32, 99,104,117,110,107, 44, 32,115,114,
99, 95,101,114,114, 32, 61, 32,115,114, 99, 40, 41, 10, 32, 32, 32, 32,108,111,
99, 97,108, 32,114,101,116, 44, 32,115,110,107, 95,101,114,114, 32, 61, 32,115,
110,107, 40, 99,104,117,110,107, 44, 32,115,114, 99, 95,101,114,114, 41, 10, 32,
32, 32, 32,105,102, 32, 99,104,117,110,107, 32, 97,110,100, 32,114,101,116, 32,
116,104,101,110, 32,114,101,116,117,114,110, 32, 49, 10, 32, 32, 32, 32,101,108,
115,101, 32,114,101,116,117,114,110, 32,110,105,108, 44, 32,115,114, 99, 95,101,
114,114, 32,111,114, 32,115,110,107, 95,101,114,114, 32,101,110,100, 10,101,110,
100, 10, 10, 45, 45, 32,112,117,109,112,115, 32, 97,108,108, 32,100, 97,116, 97,
32,102,114,111,109, 32, 97, 32,115,111,117,114, 99,101, 32,116,111, 32, 97, 32,
115,105,110,107, 44, 32,117,115,105,110,103, 32, 97, 32,115,116,101,112, 32,102,
117,110, 99,116,105,111,110, 10,102,117,110, 99,116,105,111,110, 32,112,117,109,
112, 46, 97,108,108, 40,115,114, 99, 44, 32,115,110,107, 44, 32,115,116,101,112,
41, 10, 32, 32, 32, 32, 98, 97,115,101, 46, 97,115,115,101,114,116, 40,115,114,
99, 32, 97,110,100, 32,115,110,107, 41, 10, 32, 32, 32, 32,115,116,101,112, 32,
61, 32,115,116,101,112, 32,111,114, 32,112,117,109,112, 46,115,116,101,112, 10,
32, 32, 32, 32,119,104,105,108,101, 32,116,114,117,101, 32,100,111, 10, 32, 32,
32, 32, 32, 32, 32, 32,108,111, 99, 97,108, 32,114,101,116, 44, 32,101,114,114,
32, 61, 32,115,116,101,112, 40,115,114, 99, 44, 32,115,110,107, 41, 10, 32, 32,
32, 32, 32, 32, 32, 32,105,102, 32,110,111,116, 32,114,101,116, 32,116,104,101,
110, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,105,102, 32,101,114,114,
32,116,104,101,110, 32,114,101,116,117,114,110, 32,110,105,108, 44, 32,101,114,
114, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,101,108,115,101, 32,114,
101,116,117,114,110, 32, 49, 32,101,110,100, 10, 32, 32, 32, 32, 32, 32, 32, 32,
101,110,100, 10, 32, 32, 32, 32,101,110,100, 10,101,110,100, 10, 10,
};
if (luaL_loadbuffer(L,(const char*)B1,sizeof(B1),"ltn12.lua")==0) lua_call(L, 0, 0);
}
@@ -0,0 +1,118 @@
/*=========================================================================*\
* LuaSocket toolkit
* Networking support for the Lua language
* Diego Nehab
* 26/11/1999
*
* This library is part of an effort to progressively increase the network
* connectivity of the Lua language. The Lua interface to networking
* functions follows the Sockets API closely, trying to simplify all tasks
* involved in setting up both client and server connections. The provided
* IO routines, however, follow the Lua style, being very similar to the
* standard Lua read and write functions.
*
* RCS ID: $Id: luasocket.c,v 1.53 2005/10/07 04:40:59 diego Exp $
\*=========================================================================*/
/*=========================================================================*\
* Standard include files
\*=========================================================================*/
#include "lua.h"
#include "lauxlib.h"
#if !defined(LUA_VERSION_NUM) || (LUA_VERSION_NUM < 501)
#include "compat-5.1.h"
#endif
/*=========================================================================*\
* LuaSocket includes
\*=========================================================================*/
#include "luasocket.h"
#include "auxiliar.h"
#include "except.h"
#include "timeout.h"
#include "buffer.h"
#include "inet.h"
#include "tcp.h"
#include "udp.h"
#include "select.h"
/*-------------------------------------------------------------------------*\
* Internal function prototypes
\*-------------------------------------------------------------------------*/
static int global_skip(lua_State *L);
static int global_unload(lua_State *L);
static int base_open(lua_State *L);
/*-------------------------------------------------------------------------*\
* Modules and functions
\*-------------------------------------------------------------------------*/
static const luaL_reg mod[] = {
{"auxiliar", auxiliar_open},
{"except", except_open},
{"timeout", timeout_open},
{"buffer", buffer_open},
{"inet", inet_open},
{"tcp", tcp_open},
{"udp", udp_open},
{"select", select_open},
{NULL, NULL}
};
static luaL_reg func[] = {
{"skip", global_skip},
{"__unload", global_unload},
{NULL, NULL}
};
/*-------------------------------------------------------------------------*\
* Skip a few arguments
\*-------------------------------------------------------------------------*/
static int global_skip(lua_State *L) {
int amount = luaL_checkint(L, 1);
int ret = lua_gettop(L) - amount - 1;
return ret >= 0 ? ret : 0;
}
/*-------------------------------------------------------------------------*\
* Unloads the library
\*-------------------------------------------------------------------------*/
static int global_unload(lua_State *L) {
(void) L;
socket_close();
return 0;
}
/*-------------------------------------------------------------------------*\
* Setup basic stuff.
\*-------------------------------------------------------------------------*/
static int base_open(lua_State *L) {
if (socket_open()) {
/* export functions (and leave namespace table on top of stack) */
luaL_openlib(L, "socket", func, 0);
#ifdef LUASOCKET_DEBUG
lua_pushstring(L, "_DEBUG");
lua_pushboolean(L, 1);
lua_rawset(L, -3);
#endif
/* make version string available to scripts */
lua_pushstring(L, "_VERSION");
lua_pushstring(L, LUASOCKET_VERSION);
lua_rawset(L, -3);
return 1;
} else {
lua_pushstring(L, "unable to initialize library");
lua_error(L);
return 0;
}
}
/*-------------------------------------------------------------------------*\
* Initializes all library modules.
\*-------------------------------------------------------------------------*/
LUASOCKET_API luaopen_socket_core(lua_State *L) {
int i;
base_open(L);
for (i = 0; mod[i].name; i++) mod[i].func(L);
return 1;
}
@@ -0,0 +1,32 @@
#ifndef LUASOCKET_H
#define LUASOCKET_H
/*=========================================================================*\
* LuaSocket toolkit
* Networking support for the Lua language
* Diego Nehab
* 9/11/1999
*
* RCS ID: $Id: luasocket.h,v 1.25 2007/06/11 23:44:54 diego Exp $
\*=========================================================================*/
#include "lua.h"
/*-------------------------------------------------------------------------*\
* Current socket library version
\*-------------------------------------------------------------------------*/
#define LUASOCKET_VERSION "LuaSocket 2.0.2"
#define LUASOCKET_COPYRIGHT "Copyright (C) 2004-2007 Diego Nehab"
#define LUASOCKET_AUTHORS "Diego Nehab"
/*-------------------------------------------------------------------------*\
* This macro prefixes all exported API functions
\*-------------------------------------------------------------------------*/
#ifndef LUASOCKET_API
#define LUASOCKET_API extern
#endif
/*-------------------------------------------------------------------------*\
* Initializes the library.
\*-------------------------------------------------------------------------*/
LUASOCKET_API int luaopen_socket_core(lua_State *L);
#endif /* LUASOCKET_H */
+711
View File
@@ -0,0 +1,711 @@
/*=========================================================================*\
* MIME support functions
* LuaSocket toolkit
*
* RCS ID: $Id: mime.c,v 1.28 2005/11/20 07:20:23 diego Exp $
\*=========================================================================*/
#include <string.h>
#include "lua.h"
#include "lauxlib.h"
#if !defined(LUA_VERSION_NUM) || (LUA_VERSION_NUM < 501)
#include "compat-5.1.h"
#endif
#include "mime.h"
/*=========================================================================*\
* Don't want to trust escape character constants
\*=========================================================================*/
typedef unsigned char UC;
static const char CRLF[] = "\r\n";
static const char EQCRLF[] = "=\r\n";
/*=========================================================================*\
* Internal function prototypes.
\*=========================================================================*/
static int mime_global_wrp(lua_State *L);
static int mime_global_b64(lua_State *L);
static int mime_global_unb64(lua_State *L);
static int mime_global_qp(lua_State *L);
static int mime_global_unqp(lua_State *L);
static int mime_global_qpwrp(lua_State *L);
static int mime_global_eol(lua_State *L);
static int mime_global_dot(lua_State *L);
static size_t dot(int c, size_t state, luaL_Buffer *buffer);
static void b64setup(UC *b64unbase);
static size_t b64encode(UC c, UC *input, size_t size, luaL_Buffer *buffer);
static size_t b64pad(const UC *input, size_t size, luaL_Buffer *buffer);
static size_t b64decode(UC c, UC *input, size_t size, luaL_Buffer *buffer);
static void qpsetup(UC *qpclass, UC *qpunbase);
static void qpquote(UC c, luaL_Buffer *buffer);
static size_t qpdecode(UC c, UC *input, size_t size, luaL_Buffer *buffer);
static size_t qpencode(UC c, UC *input, size_t size,
const char *marker, luaL_Buffer *buffer);
static size_t qppad(UC *input, size_t size, luaL_Buffer *buffer);
/* code support functions */
static luaL_reg func[] = {
{ "dot", mime_global_dot },
{ "b64", mime_global_b64 },
{ "eol", mime_global_eol },
{ "qp", mime_global_qp },
{ "qpwrp", mime_global_qpwrp },
{ "unb64", mime_global_unb64 },
{ "unqp", mime_global_unqp },
{ "wrp", mime_global_wrp },
{ NULL, NULL }
};
/*-------------------------------------------------------------------------*\
* Quoted-printable globals
\*-------------------------------------------------------------------------*/
static UC qpclass[256];
static UC qpbase[] = "0123456789ABCDEF";
static UC qpunbase[256];
enum {QP_PLAIN, QP_QUOTED, QP_CR, QP_IF_LAST};
/*-------------------------------------------------------------------------*\
* Base64 globals
\*-------------------------------------------------------------------------*/
static const UC b64base[] =
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
static UC b64unbase[256];
/*=========================================================================*\
* Exported functions
\*=========================================================================*/
/*-------------------------------------------------------------------------*\
* Initializes module
\*-------------------------------------------------------------------------*/
MIME_API int luaopen_mime_core(lua_State *L)
{
luaL_openlib(L, "mime", func, 0);
/* make version string available to scripts */
lua_pushstring(L, "_VERSION");
lua_pushstring(L, MIME_VERSION);
lua_rawset(L, -3);
/* initialize lookup tables */
qpsetup(qpclass, qpunbase);
b64setup(b64unbase);
return 1;
}
/*=========================================================================*\
* Global Lua functions
\*=========================================================================*/
/*-------------------------------------------------------------------------*\
* Incrementaly breaks a string into lines. The string can have CRLF breaks.
* A, n = wrp(l, B, length)
* A is a copy of B, broken into lines of at most 'length' bytes.
* 'l' is how many bytes are left for the first line of B.
* 'n' is the number of bytes left in the last line of A.
\*-------------------------------------------------------------------------*/
static int mime_global_wrp(lua_State *L)
{
size_t size = 0;
int left = (int) luaL_checknumber(L, 1);
const UC *input = (UC *) luaL_optlstring(L, 2, NULL, &size);
const UC *last = input + size;
int length = (int) luaL_optnumber(L, 3, 76);
luaL_Buffer buffer;
/* end of input black-hole */
if (!input) {
/* if last line has not been terminated, add a line break */
if (left < length) lua_pushstring(L, CRLF);
/* otherwise, we are done */
else lua_pushnil(L);
lua_pushnumber(L, length);
return 2;
}
luaL_buffinit(L, &buffer);
while (input < last) {
switch (*input) {
case '\r':
break;
case '\n':
luaL_addstring(&buffer, CRLF);
left = length;
break;
default:
if (left <= 0) {
left = length;
luaL_addstring(&buffer, CRLF);
}
luaL_putchar(&buffer, *input);
left--;
break;
}
input++;
}
luaL_pushresult(&buffer);
lua_pushnumber(L, left);
return 2;
}
/*-------------------------------------------------------------------------*\
* Fill base64 decode map.
\*-------------------------------------------------------------------------*/
static void b64setup(UC *b64unbase)
{
int i;
for (i = 0; i <= 255; i++) b64unbase[i] = (UC) 255;
for (i = 0; i < 64; i++) b64unbase[b64base[i]] = (UC) i;
b64unbase['='] = 0;
}
/*-------------------------------------------------------------------------*\
* Acumulates bytes in input buffer until 3 bytes are available.
* Translate the 3 bytes into Base64 form and append to buffer.
* Returns new number of bytes in buffer.
\*-------------------------------------------------------------------------*/
static size_t b64encode(UC c, UC *input, size_t size,
luaL_Buffer *buffer)
{
input[size++] = c;
if (size == 3) {
UC code[4];
unsigned long value = 0;
value += input[0]; value <<= 8;
value += input[1]; value <<= 8;
value += input[2];
code[3] = b64base[value & 0x3f]; value >>= 6;
code[2] = b64base[value & 0x3f]; value >>= 6;
code[1] = b64base[value & 0x3f]; value >>= 6;
code[0] = b64base[value];
luaL_addlstring(buffer, (char *) code, 4);
size = 0;
}
return size;
}
/*-------------------------------------------------------------------------*\
* Encodes the Base64 last 1 or 2 bytes and adds padding '='
* Result, if any, is appended to buffer.
* Returns 0.
\*-------------------------------------------------------------------------*/
static size_t b64pad(const UC *input, size_t size,
luaL_Buffer *buffer)
{
unsigned long value = 0;
UC code[4] = {'=', '=', '=', '='};
switch (size) {
case 1:
value = input[0] << 4;
code[1] = b64base[value & 0x3f]; value >>= 6;
code[0] = b64base[value];
luaL_addlstring(buffer, (char *) code, 4);
break;
case 2:
value = input[0]; value <<= 8;
value |= input[1]; value <<= 2;
code[2] = b64base[value & 0x3f]; value >>= 6;
code[1] = b64base[value & 0x3f]; value >>= 6;
code[0] = b64base[value];
luaL_addlstring(buffer, (char *) code, 4);
break;
default:
break;
}
return 0;
}
/*-------------------------------------------------------------------------*\
* Acumulates bytes in input buffer until 4 bytes are available.
* Translate the 4 bytes from Base64 form and append to buffer.
* Returns new number of bytes in buffer.
\*-------------------------------------------------------------------------*/
static size_t b64decode(UC c, UC *input, size_t size,
luaL_Buffer *buffer)
{
/* ignore invalid characters */
if (b64unbase[c] > 64) return size;
input[size++] = c;
/* decode atom */
if (size == 4) {
UC decoded[3];
int valid, value = 0;
value = b64unbase[input[0]]; value <<= 6;
value |= b64unbase[input[1]]; value <<= 6;
value |= b64unbase[input[2]]; value <<= 6;
value |= b64unbase[input[3]];
decoded[2] = (UC) (value & 0xff); value >>= 8;
decoded[1] = (UC) (value & 0xff); value >>= 8;
decoded[0] = (UC) value;
/* take care of paddding */
valid = (input[2] == '=') ? 1 : (input[3] == '=') ? 2 : 3;
luaL_addlstring(buffer, (char *) decoded, valid);
return 0;
/* need more data */
} else return size;
}
/*-------------------------------------------------------------------------*\
* Incrementally applies the Base64 transfer content encoding to a string
* A, B = b64(C, D)
* A is the encoded version of the largest prefix of C .. D that is
* divisible by 3. B has the remaining bytes of C .. D, *without* encoding.
* The easiest thing would be to concatenate the two strings and
* encode the result, but we can't afford that or Lua would dupplicate
* every chunk we received.
\*-------------------------------------------------------------------------*/
static int mime_global_b64(lua_State *L)
{
UC atom[3];
size_t isize = 0, asize = 0;
const UC *input = (UC *) luaL_optlstring(L, 1, NULL, &isize);
const UC *last = input + isize;
luaL_Buffer buffer;
/* end-of-input blackhole */
if (!input) {
lua_pushnil(L);
lua_pushnil(L);
return 2;
}
/* process first part of the input */
luaL_buffinit(L, &buffer);
while (input < last)
asize = b64encode(*input++, atom, asize, &buffer);
input = (UC *) luaL_optlstring(L, 2, NULL, &isize);
/* if second part is nil, we are done */
if (!input) {
asize = b64pad(atom, asize, &buffer);
luaL_pushresult(&buffer);
if (!(*lua_tostring(L, -1))) lua_pushnil(L);
lua_pushnil(L);
return 2;
}
/* otherwise process the second part */
last = input + isize;
while (input < last)
asize = b64encode(*input++, atom, asize, &buffer);
luaL_pushresult(&buffer);
lua_pushlstring(L, (char *) atom, asize);
return 2;
}
/*-------------------------------------------------------------------------*\
* Incrementally removes the Base64 transfer content encoding from a string
* A, B = b64(C, D)
* A is the encoded version of the largest prefix of C .. D that is
* divisible by 4. B has the remaining bytes of C .. D, *without* encoding.
\*-------------------------------------------------------------------------*/
static int mime_global_unb64(lua_State *L)
{
UC atom[4];
size_t isize = 0, asize = 0;
const UC *input = (UC *) luaL_optlstring(L, 1, NULL, &isize);
const UC *last = input + isize;
luaL_Buffer buffer;
/* end-of-input blackhole */
if (!input) {
lua_pushnil(L);
lua_pushnil(L);
return 2;
}
/* process first part of the input */
luaL_buffinit(L, &buffer);
while (input < last)
asize = b64decode(*input++, atom, asize, &buffer);
input = (UC *) luaL_optlstring(L, 2, NULL, &isize);
/* if second is nil, we are done */
if (!input) {
luaL_pushresult(&buffer);
if (!(*lua_tostring(L, -1))) lua_pushnil(L);
lua_pushnil(L);
return 2;
}
/* otherwise, process the rest of the input */
last = input + isize;
while (input < last)
asize = b64decode(*input++, atom, asize, &buffer);
luaL_pushresult(&buffer);
lua_pushlstring(L, (char *) atom, asize);
return 2;
}
/*-------------------------------------------------------------------------*\
* Quoted-printable encoding scheme
* all (except CRLF in text) can be =XX
* CLRL in not text must be =XX=XX
* 33 through 60 inclusive can be plain
* 62 through 126 inclusive can be plain
* 9 and 32 can be plain, unless in the end of a line, where must be =XX
* encoded lines must be no longer than 76 not counting CRLF
* soft line-break are =CRLF
* To encode one byte, we need to see the next two.
* Worst case is when we see a space, and wonder if a CRLF is comming
\*-------------------------------------------------------------------------*/
/*-------------------------------------------------------------------------*\
* Split quoted-printable characters into classes
* Precompute reverse map for encoding
\*-------------------------------------------------------------------------*/
static void qpsetup(UC *qpclass, UC *qpunbase)
{
int i;
for (i = 0; i < 256; i++) qpclass[i] = QP_QUOTED;
for (i = 33; i <= 60; i++) qpclass[i] = QP_PLAIN;
for (i = 62; i <= 126; i++) qpclass[i] = QP_PLAIN;
qpclass['\t'] = QP_IF_LAST;
qpclass[' '] = QP_IF_LAST;
qpclass['\r'] = QP_CR;
for (i = 0; i < 256; i++) qpunbase[i] = 255;
qpunbase['0'] = 0; qpunbase['1'] = 1; qpunbase['2'] = 2;
qpunbase['3'] = 3; qpunbase['4'] = 4; qpunbase['5'] = 5;
qpunbase['6'] = 6; qpunbase['7'] = 7; qpunbase['8'] = 8;
qpunbase['9'] = 9; qpunbase['A'] = 10; qpunbase['a'] = 10;
qpunbase['B'] = 11; qpunbase['b'] = 11; qpunbase['C'] = 12;
qpunbase['c'] = 12; qpunbase['D'] = 13; qpunbase['d'] = 13;
qpunbase['E'] = 14; qpunbase['e'] = 14; qpunbase['F'] = 15;
qpunbase['f'] = 15;
}
/*-------------------------------------------------------------------------*\
* Output one character in form =XX
\*-------------------------------------------------------------------------*/
static void qpquote(UC c, luaL_Buffer *buffer)
{
luaL_putchar(buffer, '=');
luaL_putchar(buffer, qpbase[c >> 4]);
luaL_putchar(buffer, qpbase[c & 0x0F]);
}
/*-------------------------------------------------------------------------*\
* Accumulate characters until we are sure about how to deal with them.
* Once we are sure, output to the buffer, in the correct form.
\*-------------------------------------------------------------------------*/
static size_t qpencode(UC c, UC *input, size_t size,
const char *marker, luaL_Buffer *buffer)
{
input[size++] = c;
/* deal with all characters we can have */
while (size > 0) {
switch (qpclass[input[0]]) {
/* might be the CR of a CRLF sequence */
case QP_CR:
if (size < 2) return size;
if (input[1] == '\n') {
luaL_addstring(buffer, marker);
return 0;
} else qpquote(input[0], buffer);
break;
/* might be a space and that has to be quoted if last in line */
case QP_IF_LAST:
if (size < 3) return size;
/* if it is the last, quote it and we are done */
if (input[1] == '\r' && input[2] == '\n') {
qpquote(input[0], buffer);
luaL_addstring(buffer, marker);
return 0;
} else luaL_putchar(buffer, input[0]);
break;
/* might have to be quoted always */
case QP_QUOTED:
qpquote(input[0], buffer);
break;
/* might never have to be quoted */
default:
luaL_putchar(buffer, input[0]);
break;
}
input[0] = input[1]; input[1] = input[2];
size--;
}
return 0;
}
/*-------------------------------------------------------------------------*\
* Deal with the final characters
\*-------------------------------------------------------------------------*/
static size_t qppad(UC *input, size_t size, luaL_Buffer *buffer)
{
size_t i;
for (i = 0; i < size; i++) {
if (qpclass[input[i]] == QP_PLAIN) luaL_putchar(buffer, input[i]);
else qpquote(input[i], buffer);
}
if (size > 0) luaL_addstring(buffer, EQCRLF);
return 0;
}
/*-------------------------------------------------------------------------*\
* Incrementally converts a string to quoted-printable
* A, B = qp(C, D, marker)
* Marker is the text to be used to replace CRLF sequences found in A.
* A is the encoded version of the largest prefix of C .. D that
* can be encoded without doubts.
* B has the remaining bytes of C .. D, *without* encoding.
\*-------------------------------------------------------------------------*/
static int mime_global_qp(lua_State *L)
{
size_t asize = 0, isize = 0;
UC atom[3];
const UC *input = (UC *) luaL_optlstring(L, 1, NULL, &isize);
const UC *last = input + isize;
const char *marker = luaL_optstring(L, 3, CRLF);
luaL_Buffer buffer;
/* end-of-input blackhole */
if (!input) {
lua_pushnil(L);
lua_pushnil(L);
return 2;
}
/* process first part of input */
luaL_buffinit(L, &buffer);
while (input < last)
asize = qpencode(*input++, atom, asize, marker, &buffer);
input = (UC *) luaL_optlstring(L, 2, NULL, &isize);
/* if second part is nil, we are done */
if (!input) {
asize = qppad(atom, asize, &buffer);
luaL_pushresult(&buffer);
if (!(*lua_tostring(L, -1))) lua_pushnil(L);
lua_pushnil(L);
return 2;
}
/* otherwise process rest of input */
last = input + isize;
while (input < last)
asize = qpencode(*input++, atom, asize, marker, &buffer);
luaL_pushresult(&buffer);
lua_pushlstring(L, (char *) atom, asize);
return 2;
}
/*-------------------------------------------------------------------------*\
* Accumulate characters until we are sure about how to deal with them.
* Once we are sure, output the to the buffer, in the correct form.
\*-------------------------------------------------------------------------*/
static size_t qpdecode(UC c, UC *input, size_t size, luaL_Buffer *buffer) {
int d;
input[size++] = c;
/* deal with all characters we can deal */
switch (input[0]) {
/* if we have an escape character */
case '=':
if (size < 3) return size;
/* eliminate soft line break */
if (input[1] == '\r' && input[2] == '\n') return 0;
/* decode quoted representation */
c = qpunbase[input[1]]; d = qpunbase[input[2]];
/* if it is an invalid, do not decode */
if (c > 15 || d > 15) luaL_addlstring(buffer, (char *)input, 3);
else luaL_putchar(buffer, (c << 4) + d);
return 0;
case '\r':
if (size < 2) return size;
if (input[1] == '\n') luaL_addlstring(buffer, (char *)input, 2);
return 0;
default:
if (input[0] == '\t' || (input[0] > 31 && input[0] < 127))
luaL_putchar(buffer, input[0]);
return 0;
}
}
/*-------------------------------------------------------------------------*\
* Incrementally decodes a string in quoted-printable
* A, B = qp(C, D)
* A is the decoded version of the largest prefix of C .. D that
* can be decoded without doubts.
* B has the remaining bytes of C .. D, *without* decoding.
\*-------------------------------------------------------------------------*/
static int mime_global_unqp(lua_State *L)
{
size_t asize = 0, isize = 0;
UC atom[3];
const UC *input = (UC *) luaL_optlstring(L, 1, NULL, &isize);
const UC *last = input + isize;
luaL_Buffer buffer;
/* end-of-input blackhole */
if (!input) {
lua_pushnil(L);
lua_pushnil(L);
return 2;
}
/* process first part of input */
luaL_buffinit(L, &buffer);
while (input < last)
asize = qpdecode(*input++, atom, asize, &buffer);
input = (UC *) luaL_optlstring(L, 2, NULL, &isize);
/* if second part is nil, we are done */
if (!input) {
luaL_pushresult(&buffer);
if (!(*lua_tostring(L, -1))) lua_pushnil(L);
lua_pushnil(L);
return 2;
}
/* otherwise process rest of input */
last = input + isize;
while (input < last)
asize = qpdecode(*input++, atom, asize, &buffer);
luaL_pushresult(&buffer);
lua_pushlstring(L, (char *) atom, asize);
return 2;
}
/*-------------------------------------------------------------------------*\
* Incrementally breaks a quoted-printed string into lines
* A, n = qpwrp(l, B, length)
* A is a copy of B, broken into lines of at most 'length' bytes.
* 'l' is how many bytes are left for the first line of B.
* 'n' is the number of bytes left in the last line of A.
* There are two complications: lines can't be broken in the middle
* of an encoded =XX, and there might be line breaks already
\*-------------------------------------------------------------------------*/
static int mime_global_qpwrp(lua_State *L)
{
size_t size = 0;
int left = (int) luaL_checknumber(L, 1);
const UC *input = (UC *) luaL_optlstring(L, 2, NULL, &size);
const UC *last = input + size;
int length = (int) luaL_optnumber(L, 3, 76);
luaL_Buffer buffer;
/* end-of-input blackhole */
if (!input) {
if (left < length) lua_pushstring(L, EQCRLF);
else lua_pushnil(L);
lua_pushnumber(L, length);
return 2;
}
/* process all input */
luaL_buffinit(L, &buffer);
while (input < last) {
switch (*input) {
case '\r':
break;
case '\n':
left = length;
luaL_addstring(&buffer, CRLF);
break;
case '=':
if (left <= 3) {
left = length;
luaL_addstring(&buffer, EQCRLF);
}
luaL_putchar(&buffer, *input);
left--;
break;
default:
if (left <= 1) {
left = length;
luaL_addstring(&buffer, EQCRLF);
}
luaL_putchar(&buffer, *input);
left--;
break;
}
input++;
}
luaL_pushresult(&buffer);
lua_pushnumber(L, left);
return 2;
}
/*-------------------------------------------------------------------------*\
* Here is what we do: \n, and \r are considered candidates for line
* break. We issue *one* new line marker if any of them is seen alone, or
* followed by a different one. That is, \n\n and \r\r will issue two
* end of line markers each, but \r\n, \n\r etc will only issue *one*
* marker. This covers Mac OS, Mac OS X, VMS, Unix and DOS, as well as
* probably other more obscure conventions.
*
* c is the current character being processed
* last is the previous character
\*-------------------------------------------------------------------------*/
#define eolcandidate(c) (c == '\r' || c == '\n')
static int eolprocess(int c, int last, const char *marker,
luaL_Buffer *buffer)
{
if (eolcandidate(c)) {
if (eolcandidate(last)) {
if (c == last) luaL_addstring(buffer, marker);
return 0;
} else {
luaL_addstring(buffer, marker);
return c;
}
} else {
luaL_putchar(buffer, c);
return 0;
}
}
/*-------------------------------------------------------------------------*\
* Converts a string to uniform EOL convention.
* A, n = eol(o, B, marker)
* A is the converted version of the largest prefix of B that can be
* converted unambiguously. 'o' is the context returned by the previous
* call. 'n' is the new context.
\*-------------------------------------------------------------------------*/
static int mime_global_eol(lua_State *L)
{
int ctx = luaL_checkint(L, 1);
size_t isize = 0;
const char *input = luaL_optlstring(L, 2, NULL, &isize);
const char *last = input + isize;
const char *marker = luaL_optstring(L, 3, CRLF);
luaL_Buffer buffer;
luaL_buffinit(L, &buffer);
/* end of input blackhole */
if (!input) {
lua_pushnil(L);
lua_pushnumber(L, 0);
return 2;
}
/* process all input */
while (input < last)
ctx = eolprocess(*input++, ctx, marker, &buffer);
luaL_pushresult(&buffer);
lua_pushnumber(L, ctx);
return 2;
}
/*-------------------------------------------------------------------------*\
* Takes one byte and stuff it if needed.
\*-------------------------------------------------------------------------*/
static size_t dot(int c, size_t state, luaL_Buffer *buffer)
{
luaL_putchar(buffer, c);
switch (c) {
case '\r':
return 1;
case '\n':
return (state == 1)? 2: 0;
case '.':
if (state == 2)
luaL_putchar(buffer, '.');
default:
return 0;
}
}
/*-------------------------------------------------------------------------*\
* Incrementally applies smtp stuffing to a string
* A, n = dot(l, D)
\*-------------------------------------------------------------------------*/
static int mime_global_dot(lua_State *L)
{
size_t isize = 0, state = (size_t) luaL_checknumber(L, 1);
const char *input = luaL_optlstring(L, 2, NULL, &isize);
const char *last = input + isize;
luaL_Buffer buffer;
/* end-of-input blackhole */
if (!input) {
lua_pushnil(L);
lua_pushnumber(L, 2);
return 2;
}
/* process all input */
luaL_buffinit(L, &buffer);
while (input < last)
state = dot(*input++, state, &buffer);
luaL_pushresult(&buffer);
lua_pushnumber(L, state);
return 2;
}
@@ -0,0 +1,31 @@
#ifndef MIME_H
#define MIME_H
/*=========================================================================*\
* Core MIME support
* LuaSocket toolkit
*
* This module provides functions to implement transfer content encodings
* and formatting conforming to RFC 2045. It is used by mime.lua, which
* provide a higher level interface to this functionality.
*
* RCS ID: $Id: mime.h,v 1.15 2007/06/11 23:44:54 diego Exp $
\*=========================================================================*/
#include "lua.h"
/*-------------------------------------------------------------------------*\
* Current MIME library version
\*-------------------------------------------------------------------------*/
#define MIME_VERSION "MIME 1.0.2"
#define MIME_COPYRIGHT "Copyright (C) 2004-2007 Diego Nehab"
#define MIME_AUTHORS "Diego Nehab"
/*-------------------------------------------------------------------------*\
* This macro prefixes all exported API functions
\*-------------------------------------------------------------------------*/
#ifndef MIME_API
#define MIME_API extern
#endif
MIME_API int luaopen_mime_core(lua_State *L);
#endif /* MIME_H */
@@ -0,0 +1,87 @@
-----------------------------------------------------------------------------
-- MIME support for the Lua language.
-- Author: Diego Nehab
-- Conforming to RFCs 2045-2049
-- RCS ID: $Id: mime.lua,v 1.29 2007/06/11 23:44:54 diego Exp $
-----------------------------------------------------------------------------
-----------------------------------------------------------------------------
-- Declare module and import dependencies
-----------------------------------------------------------------------------
local base = _G
local ltn12 = require("ltn12")
local mime = require("mime.core")
local io = require("io")
local string = require("string")
module("mime")
-- encode, decode and wrap algorithm tables
encodet = {}
decodet = {}
wrapt = {}
-- creates a function that chooses a filter by name from a given table
local function choose(table)
return function(name, opt1, opt2)
if base.type(name) ~= "string" then
name, opt1, opt2 = "default", name, opt1
end
local f = table[name or "nil"]
if not f then
base.error("unknown key (" .. base.tostring(name) .. ")", 3)
else return f(opt1, opt2) end
end
end
-- define the encoding filters
encodet['base64'] = function()
return ltn12.filter.cycle(b64, "")
end
encodet['quoted-printable'] = function(mode)
return ltn12.filter.cycle(qp, "",
(mode == "binary") and "=0D=0A" or "\r\n")
end
-- define the decoding filters
decodet['base64'] = function()
return ltn12.filter.cycle(unb64, "")
end
decodet['quoted-printable'] = function()
return ltn12.filter.cycle(unqp, "")
end
local function format(chunk)
if chunk then
if chunk == "" then return "''"
else return string.len(chunk) end
else return "nil" end
end
-- define the line-wrap filters
wrapt['text'] = function(length)
length = length or 76
return ltn12.filter.cycle(wrp, length, length)
end
wrapt['base64'] = wrapt['text']
wrapt['default'] = wrapt['text']
wrapt['quoted-printable'] = function()
return ltn12.filter.cycle(qpwrp, 76, 76)
end
-- function that choose the encoding, decoding or wrap algorithm
encode = choose(encodet)
decode = choose(decodet)
wrap = choose(wrapt)
-- define the end-of-line normalization filter
function normalize(marker)
return ltn12.filter.cycle(eol, 0, marker)
end
-- high level stuffing filter
function stuff()
return ltn12.filter.cycle(dot, 2)
end
@@ -0,0 +1,133 @@
/* code automatically generated by bin2c -- DO NOT EDIT */
{
/* #include'ing this file in a C program is equivalent to calling
if (luaL_loadfile(L,"mime.lua")==0) lua_call(L, 0, 0);
*/
/* mime.lua */
static const unsigned char B1[]={
45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45,
45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45,
45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45,
45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 10, 45, 45,
32, 77, 73, 77, 69, 32,115,117,112,112,111,114,116, 32,102,111,114, 32,116,104,
101, 32, 76,117, 97, 32,108, 97,110,103,117, 97,103,101, 46, 10, 45, 45, 32, 65,
117,116,104,111,114, 58, 32, 68,105,101,103,111, 32, 78,101,104, 97, 98, 10, 45,
45, 32, 67,111,110,102,111,114,109,105,110,103, 32,116,111, 32, 82, 70, 67,115,
32, 50, 48, 52, 53, 45, 50, 48, 52, 57, 10, 45, 45, 32, 82, 67, 83, 32, 73, 68,
58, 32, 36, 73,100, 58, 32,109,105,109,101, 46,108,117, 97, 44,118, 32, 49, 46,
50, 57, 32, 50, 48, 48, 55, 47, 48, 54, 47, 49, 49, 32, 50, 51, 58, 52, 52, 58,
53, 52, 32,100,105,101,103,111, 32, 69,120,112, 32, 36, 10, 45, 45, 45, 45, 45,
45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45,
45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45,
45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45,
45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 10, 10, 45, 45, 45, 45, 45, 45,
45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45,
45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45,
45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45,
45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 10, 45, 45, 32, 68,101, 99,108, 97,
114,101, 32,109,111,100,117,108,101, 32, 97,110,100, 32,105,109,112,111,114,116,
32,100,101,112,101,110,100,101,110, 99,105,101,115, 10, 45, 45, 45, 45, 45, 45,
45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45,
45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45,
45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45,
45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 10,108,111, 99, 97,108, 32, 98, 97,
115,101, 32, 61, 32, 95, 71, 10,108,111, 99, 97,108, 32,108,116,110, 49, 50, 32,
61, 32,114,101,113,117,105,114,101, 40, 34,108,116,110, 49, 50, 34, 41, 10,108,
111, 99, 97,108, 32,109,105,109,101, 32, 61, 32,114,101,113,117,105,114,101, 40,
34,109,105,109,101, 46, 99,111,114,101, 34, 41, 10,108,111, 99, 97,108, 32,105,
111, 32, 61, 32,114,101,113,117,105,114,101, 40, 34,105,111, 34, 41, 10,108,111,
99, 97,108, 32,115,116,114,105,110,103, 32, 61, 32,114,101,113,117,105,114,101,
40, 34,115,116,114,105,110,103, 34, 41, 10,109,111,100,117,108,101, 40, 34,109,
105,109,101, 34, 41, 10, 10, 45, 45, 32,101,110, 99,111,100,101, 44, 32,100,101,
99,111,100,101, 32, 97,110,100, 32,119,114, 97,112, 32, 97,108,103,111,114,105,
116,104,109, 32,116, 97, 98,108,101,115, 10,101,110, 99,111,100,101,116, 32, 61,
32,123,125, 10,100,101, 99,111,100,101,116, 32, 61, 32,123,125, 10,119,114, 97,
112,116, 32, 61, 32,123,125, 10, 10, 45, 45, 32, 99,114,101, 97,116,101,115, 32,
97, 32,102,117,110, 99,116,105,111,110, 32,116,104, 97,116, 32, 99,104,111,111,
115,101,115, 32, 97, 32,102,105,108,116,101,114, 32, 98,121, 32,110, 97,109,101,
32,102,114,111,109, 32, 97, 32,103,105,118,101,110, 32,116, 97, 98,108,101, 10,
108,111, 99, 97,108, 32,102,117,110, 99,116,105,111,110, 32, 99,104,111,111,115,
101, 40,116, 97, 98,108,101, 41, 10, 32, 32, 32, 32,114,101,116,117,114,110, 32,
102,117,110, 99,116,105,111,110, 40,110, 97,109,101, 44, 32,111,112,116, 49, 44,
32,111,112,116, 50, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32,105,102, 32, 98, 97,
115,101, 46,116,121,112,101, 40,110, 97,109,101, 41, 32,126, 61, 32, 34,115,116,
114,105,110,103, 34, 32,116,104,101,110, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32,
32, 32, 32,110, 97,109,101, 44, 32,111,112,116, 49, 44, 32,111,112,116, 50, 32,
61, 32, 34,100,101,102, 97,117,108,116, 34, 44, 32,110, 97,109,101, 44, 32,111,
112,116, 49, 10, 32, 32, 32, 32, 32, 32, 32, 32,101,110,100, 10, 32, 32, 32, 32,
32, 32, 32, 32,108,111, 99, 97,108, 32,102, 32, 61, 32,116, 97, 98,108,101, 91,
110, 97,109,101, 32,111,114, 32, 34,110,105,108, 34, 93, 10, 32, 32, 32, 32, 32,
32, 32, 32,105,102, 32,110,111,116, 32,102, 32,116,104,101,110, 32, 10, 32, 32,
32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 98, 97,115,101, 46,101,114,114,111,114,
40, 34,117,110,107,110,111,119,110, 32,107,101,121, 32, 40, 34, 32, 46, 46, 32,
98, 97,115,101, 46,116,111,115,116,114,105,110,103, 40,110, 97,109,101, 41, 32,
46, 46, 32, 34, 41, 34, 44, 32, 51, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32,101,
108,115,101, 32,114,101,116,117,114,110, 32,102, 40,111,112,116, 49, 44, 32,111,
112,116, 50, 41, 32,101,110,100, 10, 32, 32, 32, 32,101,110,100, 10,101,110,100,
10, 10, 45, 45, 32,100,101,102,105,110,101, 32,116,104,101, 32,101,110, 99,111,
100,105,110,103, 32,102,105,108,116,101,114,115, 10,101,110, 99,111,100,101,116,
91, 39, 98, 97,115,101, 54, 52, 39, 93, 32, 61, 32,102,117,110, 99,116,105,111,
110, 40, 41, 10, 32, 32, 32, 32,114,101,116,117,114,110, 32,108,116,110, 49, 50,
46,102,105,108,116,101,114, 46, 99,121, 99,108,101, 40, 98, 54, 52, 44, 32, 34,
34, 41, 10,101,110,100, 10, 10,101,110, 99,111,100,101,116, 91, 39,113,117,111,
116,101,100, 45,112,114,105,110,116, 97, 98,108,101, 39, 93, 32, 61, 32,102,117,
110, 99,116,105,111,110, 40,109,111,100,101, 41, 10, 32, 32, 32, 32,114,101,116,
117,114,110, 32,108,116,110, 49, 50, 46,102,105,108,116,101,114, 46, 99,121, 99,
108,101, 40,113,112, 44, 32, 34, 34, 44, 10, 32, 32, 32, 32, 32, 32, 32, 32, 40,
109,111,100,101, 32, 61, 61, 32, 34, 98,105,110, 97,114,121, 34, 41, 32, 97,110,
100, 32, 34, 61, 48, 68, 61, 48, 65, 34, 32,111,114, 32, 34, 92,114, 92,110, 34,
41, 10,101,110,100, 10, 10, 45, 45, 32,100,101,102,105,110,101, 32,116,104,101,
32,100,101, 99,111,100,105,110,103, 32,102,105,108,116,101,114,115, 10,100,101,
99,111,100,101,116, 91, 39, 98, 97,115,101, 54, 52, 39, 93, 32, 61, 32,102,117,
110, 99,116,105,111,110, 40, 41, 10, 32, 32, 32, 32,114,101,116,117,114,110, 32,
108,116,110, 49, 50, 46,102,105,108,116,101,114, 46, 99,121, 99,108,101, 40,117,
110, 98, 54, 52, 44, 32, 34, 34, 41, 10,101,110,100, 10, 10,100,101, 99,111,100,
101,116, 91, 39,113,117,111,116,101,100, 45,112,114,105,110,116, 97, 98,108,101,
39, 93, 32, 61, 32,102,117,110, 99,116,105,111,110, 40, 41, 10, 32, 32, 32, 32,
114,101,116,117,114,110, 32,108,116,110, 49, 50, 46,102,105,108,116,101,114, 46,
99,121, 99,108,101, 40,117,110,113,112, 44, 32, 34, 34, 41, 10,101,110,100, 10,
10,108,111, 99, 97,108, 32,102,117,110, 99,116,105,111,110, 32,102,111,114,109,
97,116, 40, 99,104,117,110,107, 41, 10, 32, 32, 32, 32,105,102, 32, 99,104,117,
110,107, 32,116,104,101,110, 10, 32, 32, 32, 32, 32, 32, 32, 32,105,102, 32, 99,
104,117,110,107, 32, 61, 61, 32, 34, 34, 32,116,104,101,110, 32,114,101,116,117,
114,110, 32, 34, 39, 39, 34, 10, 32, 32, 32, 32, 32, 32, 32, 32,101,108,115,101,
32,114,101,116,117,114,110, 32,115,116,114,105,110,103, 46,108,101,110, 40, 99,
104,117,110,107, 41, 32,101,110,100, 10, 32, 32, 32, 32,101,108,115,101, 32,114,
101,116,117,114,110, 32, 34,110,105,108, 34, 32,101,110,100, 10,101,110,100, 10,
10, 45, 45, 32,100,101,102,105,110,101, 32,116,104,101, 32,108,105,110,101, 45,
119,114, 97,112, 32,102,105,108,116,101,114,115, 10,119,114, 97,112,116, 91, 39,
116,101,120,116, 39, 93, 32, 61, 32,102,117,110, 99,116,105,111,110, 40,108,101,
110,103,116,104, 41, 10, 32, 32, 32, 32,108,101,110,103,116,104, 32, 61, 32,108,
101,110,103,116,104, 32,111,114, 32, 55, 54, 10, 32, 32, 32, 32,114,101,116,117,
114,110, 32,108,116,110, 49, 50, 46,102,105,108,116,101,114, 46, 99,121, 99,108,
101, 40,119,114,112, 44, 32,108,101,110,103,116,104, 44, 32,108,101,110,103,116,
104, 41, 10,101,110,100, 10,119,114, 97,112,116, 91, 39, 98, 97,115,101, 54, 52,
39, 93, 32, 61, 32,119,114, 97,112,116, 91, 39,116,101,120,116, 39, 93, 10,119,
114, 97,112,116, 91, 39,100,101,102, 97,117,108,116, 39, 93, 32, 61, 32,119,114,
97,112,116, 91, 39,116,101,120,116, 39, 93, 10, 10,119,114, 97,112,116, 91, 39,
113,117,111,116,101,100, 45,112,114,105,110,116, 97, 98,108,101, 39, 93, 32, 61,
32,102,117,110, 99,116,105,111,110, 40, 41, 10, 32, 32, 32, 32,114,101,116,117,
114,110, 32,108,116,110, 49, 50, 46,102,105,108,116,101,114, 46, 99,121, 99,108,
101, 40,113,112,119,114,112, 44, 32, 55, 54, 44, 32, 55, 54, 41, 10,101,110,100,
10, 10, 45, 45, 32,102,117,110, 99,116,105,111,110, 32,116,104, 97,116, 32, 99,
104,111,111,115,101, 32,116,104,101, 32,101,110, 99,111,100,105,110,103, 44, 32,
100,101, 99,111,100,105,110,103, 32,111,114, 32,119,114, 97,112, 32, 97,108,103,
111,114,105,116,104,109, 10,101,110, 99,111,100,101, 32, 61, 32, 99,104,111,111,
115,101, 40,101,110, 99,111,100,101,116, 41, 10,100,101, 99,111,100,101, 32, 61,
32, 99,104,111,111,115,101, 40,100,101, 99,111,100,101,116, 41, 10,119,114, 97,
112, 32, 61, 32, 99,104,111,111,115,101, 40,119,114, 97,112,116, 41, 10, 10, 45,
45, 32,100,101,102,105,110,101, 32,116,104,101, 32,101,110,100, 45,111,102, 45,
108,105,110,101, 32,110,111,114,109, 97,108,105,122, 97,116,105,111,110, 32,102,
105,108,116,101,114, 10,102,117,110, 99,116,105,111,110, 32,110,111,114,109, 97,
108,105,122,101, 40,109, 97,114,107,101,114, 41, 10, 32, 32, 32, 32,114,101,116,
117,114,110, 32,108,116,110, 49, 50, 46,102,105,108,116,101,114, 46, 99,121, 99,
108,101, 40,101,111,108, 44, 32, 48, 44, 32,109, 97,114,107,101,114, 41, 10,101,
110,100, 10, 10, 45, 45, 32,104,105,103,104, 32,108,101,118,101,108, 32,115,116,
117,102,102,105,110,103, 32,102,105,108,116,101,114, 10,102,117,110, 99,116,105,
111,110, 32,115,116,117,102,102, 40, 41, 10, 32, 32, 32, 32,114,101,116,117,114,
110, 32,108,116,110, 49, 50, 46,102,105,108,116,101,114, 46, 99,121, 99,108,101,
40,100,111,116, 44, 32, 50, 41, 10,101,110,100, 10,
};
if (luaL_loadbuffer(L,(const char*)B1,sizeof(B1),"mime.lua")==0) lua_call(L, 0, 0);
}
@@ -0,0 +1,149 @@
/*=========================================================================*\
* Common option interface
* LuaSocket toolkit
*
* RCS ID: $Id: options.c,v 1.6 2005/11/20 07:20:23 diego Exp $
\*=========================================================================*/
#include <string.h>
#include "lauxlib.h"
#include "auxiliar.h"
#include "options.h"
#include "inet.h"
/*=========================================================================*\
* Internal functions prototypes
\*=========================================================================*/
static int opt_setmembership(lua_State *L, p_socket ps, int level, int name);
static int opt_setboolean(lua_State *L, p_socket ps, int level, int name);
static int opt_set(lua_State *L, p_socket ps, int level, int name,
void *val, int len);
/*=========================================================================*\
* Exported functions
\*=========================================================================*/
/*-------------------------------------------------------------------------*\
* Calls appropriate option handler
\*-------------------------------------------------------------------------*/
int opt_meth_setoption(lua_State *L, p_opt opt, p_socket ps)
{
const char *name = luaL_checkstring(L, 2); /* obj, name, ... */
while (opt->name && strcmp(name, opt->name))
opt++;
if (!opt->func) {
char msg[45];
sprintf(msg, "unsupported option `%.35s'", name);
luaL_argerror(L, 2, msg);
}
return opt->func(L, ps);
}
/* enables reuse of local address */
int opt_reuseaddr(lua_State *L, p_socket ps)
{
return opt_setboolean(L, ps, SOL_SOCKET, SO_REUSEADDR);
}
/* disables the Naggle algorithm */
int opt_tcp_nodelay(lua_State *L, p_socket ps)
{
return opt_setboolean(L, ps, IPPROTO_TCP, TCP_NODELAY);
}
int opt_keepalive(lua_State *L, p_socket ps)
{
return opt_setboolean(L, ps, SOL_SOCKET, SO_KEEPALIVE);
}
int opt_dontroute(lua_State *L, p_socket ps)
{
return opt_setboolean(L, ps, SOL_SOCKET, SO_DONTROUTE);
}
int opt_broadcast(lua_State *L, p_socket ps)
{
return opt_setboolean(L, ps, SOL_SOCKET, SO_BROADCAST);
}
int opt_ip_multicast_loop(lua_State *L, p_socket ps)
{
return opt_setboolean(L, ps, IPPROTO_IP, IP_MULTICAST_LOOP);
}
int opt_linger(lua_State *L, p_socket ps)
{
struct linger li; /* obj, name, table */
if (!lua_istable(L, 3)) luaL_typerror(L, 3, lua_typename(L, LUA_TTABLE));
lua_pushstring(L, "on");
lua_gettable(L, 3);
if (!lua_isboolean(L, -1))
luaL_argerror(L, 3, "boolean 'on' field expected");
li.l_onoff = (u_short) lua_toboolean(L, -1);
lua_pushstring(L, "timeout");
lua_gettable(L, 3);
if (!lua_isnumber(L, -1))
luaL_argerror(L, 3, "number 'timeout' field expected");
li.l_linger = (u_short) lua_tonumber(L, -1);
return opt_set(L, ps, SOL_SOCKET, SO_LINGER, (char *) &li, sizeof(li));
}
int opt_ip_multicast_ttl(lua_State *L, p_socket ps)
{
int val = (int) luaL_checknumber(L, 3); /* obj, name, int */
return opt_set(L, ps, SOL_SOCKET, SO_LINGER, (char *) &val, sizeof(val));
}
int opt_ip_add_membership(lua_State *L, p_socket ps)
{
return opt_setmembership(L, ps, IPPROTO_IP, IP_ADD_MEMBERSHIP);
}
int opt_ip_drop_membersip(lua_State *L, p_socket ps)
{
return opt_setmembership(L, ps, IPPROTO_IP, IP_DROP_MEMBERSHIP);
}
/*=========================================================================*\
* Auxiliar functions
\*=========================================================================*/
static int opt_setmembership(lua_State *L, p_socket ps, int level, int name)
{
struct ip_mreq val; /* obj, name, table */
if (!lua_istable(L, 3)) luaL_typerror(L, 3, lua_typename(L, LUA_TTABLE));
lua_pushstring(L, "multiaddr");
lua_gettable(L, 3);
if (!lua_isstring(L, -1))
luaL_argerror(L, 3, "string 'multiaddr' field expected");
if (!inet_aton(lua_tostring(L, -1), &val.imr_multiaddr))
luaL_argerror(L, 3, "invalid 'multiaddr' ip address");
lua_pushstring(L, "interface");
lua_gettable(L, 3);
if (!lua_isstring(L, -1))
luaL_argerror(L, 3, "string 'interface' field expected");
val.imr_interface.s_addr = htonl(INADDR_ANY);
if (strcmp(lua_tostring(L, -1), "*") &&
!inet_aton(lua_tostring(L, -1), &val.imr_interface))
luaL_argerror(L, 3, "invalid 'interface' ip address");
return opt_set(L, ps, level, name, (char *) &val, sizeof(val));
}
static
int opt_set(lua_State *L, p_socket ps, int level, int name, void *val, int len)
{
if (setsockopt(*ps, level, name, (char *) val, len) < 0) {
lua_pushnil(L);
lua_pushstring(L, "setsockopt failed");
return 2;
}
lua_pushnumber(L, 1);
return 1;
}
static int opt_setboolean(lua_State *L, p_socket ps, int level, int name)
{
int val = auxiliar_checkboolean(L, 3); /* obj, name, bool */
return opt_set(L, ps, level, name, (char *) &val, sizeof(val));
}
@@ -0,0 +1,39 @@
#ifndef OPTIONS_H
#define OPTIONS_H
/*=========================================================================*\
* Common option interface
* LuaSocket toolkit
*
* This module provides a common interface to socket options, used mainly by
* modules UDP and TCP.
*
* RCS ID: $Id: options.h,v 1.4 2005/10/07 04:40:59 diego Exp $
\*=========================================================================*/
#include "lua.h"
#include "socket.h"
/* option registry */
typedef struct t_opt {
const char *name;
int (*func)(lua_State *L, p_socket ps);
} t_opt;
typedef t_opt *p_opt;
/* supported options */
int opt_dontroute(lua_State *L, p_socket ps);
int opt_broadcast(lua_State *L, p_socket ps);
int opt_reuseaddr(lua_State *L, p_socket ps);
int opt_tcp_nodelay(lua_State *L, p_socket ps);
int opt_keepalive(lua_State *L, p_socket ps);
int opt_linger(lua_State *L, p_socket ps);
int opt_reuseaddr(lua_State *L, p_socket ps);
int opt_ip_multicast_ttl(lua_State *L, p_socket ps);
int opt_ip_multicast_loop(lua_State *L, p_socket ps);
int opt_ip_add_membership(lua_State *L, p_socket ps);
int opt_ip_drop_membersip(lua_State *L, p_socket ps);
/* invokes the appropriate option handler */
int opt_meth_setoption(lua_State *L, p_opt opt, p_socket ps);
#endif
@@ -0,0 +1 @@
if not socket then error("No socket.") end
@@ -0,0 +1,200 @@
/*=========================================================================*\
* Select implementation
* LuaSocket toolkit
*
* RCS ID: $Id: select.c,v 1.22 2005/11/20 07:20:23 diego Exp $
\*=========================================================================*/
#include <string.h>
#include "lua.h"
#include "lauxlib.h"
#include "socket.h"
#include "timeout.h"
#include "select.h"
/*=========================================================================*\
* Internal function prototypes.
\*=========================================================================*/
static t_socket getfd(lua_State *L);
static int dirty(lua_State *L);
static t_socket collect_fd(lua_State *L, int tab, t_socket max_fd,
int itab, fd_set *set);
static int check_dirty(lua_State *L, int tab, int dtab, fd_set *set);
static void return_fd(lua_State *L, fd_set *set, t_socket max_fd,
int itab, int tab, int start);
static void make_assoc(lua_State *L, int tab);
static int global_select(lua_State *L);
/* functions in library namespace */
static luaL_reg func[] = {
{"select", global_select},
{NULL, NULL}
};
/*=========================================================================*\
* Exported functions
\*=========================================================================*/
/*-------------------------------------------------------------------------*\
* Initializes module
\*-------------------------------------------------------------------------*/
int select_open(lua_State *L) {
luaL_openlib(L, NULL, func, 0);
return 0;
}
/*=========================================================================*\
* Global Lua functions
\*=========================================================================*/
/*-------------------------------------------------------------------------*\
* Waits for a set of sockets until a condition is met or timeout.
\*-------------------------------------------------------------------------*/
static int global_select(lua_State *L) {
int rtab, wtab, itab, ret, ndirty;
t_socket max_fd;
fd_set rset, wset;
t_timeout tm;
double t = luaL_optnumber(L, 3, -1);
FD_ZERO(&rset); FD_ZERO(&wset);
lua_settop(L, 3);
lua_newtable(L); itab = lua_gettop(L);
lua_newtable(L); rtab = lua_gettop(L);
lua_newtable(L); wtab = lua_gettop(L);
max_fd = collect_fd(L, 1, SOCKET_INVALID, itab, &rset);
ndirty = check_dirty(L, 1, rtab, &rset);
t = ndirty > 0? 0.0: t;
timeout_init(&tm, t, -1);
timeout_markstart(&tm);
max_fd = collect_fd(L, 2, max_fd, itab, &wset);
ret = socket_select(max_fd+1, &rset, &wset, NULL, &tm);
if (ret > 0 || ndirty > 0) {
return_fd(L, &rset, max_fd+1, itab, rtab, ndirty);
return_fd(L, &wset, max_fd+1, itab, wtab, 0);
make_assoc(L, rtab);
make_assoc(L, wtab);
return 2;
} else if (ret == 0) {
lua_pushstring(L, "timeout");
return 3;
} else {
lua_pushstring(L, "error");
return 3;
}
}
/*=========================================================================*\
* Internal functions
\*=========================================================================*/
static t_socket getfd(lua_State *L) {
t_socket fd = SOCKET_INVALID;
lua_pushstring(L, "getfd");
lua_gettable(L, -2);
if (!lua_isnil(L, -1)) {
lua_pushvalue(L, -2);
lua_call(L, 1, 1);
if (lua_isnumber(L, -1))
fd = (t_socket) lua_tonumber(L, -1);
}
lua_pop(L, 1);
return fd;
}
static int dirty(lua_State *L) {
int is = 0;
lua_pushstring(L, "dirty");
lua_gettable(L, -2);
if (!lua_isnil(L, -1)) {
lua_pushvalue(L, -2);
lua_call(L, 1, 1);
is = lua_toboolean(L, -1);
}
lua_pop(L, 1);
return is;
}
static t_socket collect_fd(lua_State *L, int tab, t_socket max_fd,
int itab, fd_set *set) {
int i = 1;
if (lua_isnil(L, tab))
return max_fd;
while (1) {
t_socket fd;
lua_pushnumber(L, i);
lua_gettable(L, tab);
if (lua_isnil(L, -1)) {
lua_pop(L, 1);
break;
}
fd = getfd(L);
if (fd != SOCKET_INVALID) {
FD_SET(fd, set);
if (max_fd == SOCKET_INVALID || max_fd < fd)
max_fd = fd;
lua_pushnumber(L, fd);
lua_pushvalue(L, -2);
lua_settable(L, itab);
}
lua_pop(L, 1);
i = i + 1;
}
return max_fd;
}
static int check_dirty(lua_State *L, int tab, int dtab, fd_set *set) {
int ndirty = 0, i = 1;
if (lua_isnil(L, tab))
return 0;
while (1) {
t_socket fd;
lua_pushnumber(L, i);
lua_gettable(L, tab);
if (lua_isnil(L, -1)) {
lua_pop(L, 1);
break;
}
fd = getfd(L);
if (fd != SOCKET_INVALID && dirty(L)) {
lua_pushnumber(L, ++ndirty);
lua_pushvalue(L, -2);
lua_settable(L, dtab);
FD_CLR(fd, set);
}
lua_pop(L, 1);
i = i + 1;
}
return ndirty;
}
static void return_fd(lua_State *L, fd_set *set, t_socket max_fd,
int itab, int tab, int start) {
t_socket fd;
for (fd = 0; fd < max_fd; fd++) {
if (FD_ISSET(fd, set)) {
lua_pushnumber(L, ++start);
lua_pushnumber(L, fd);
lua_gettable(L, itab);
lua_settable(L, tab);
}
}
}
static void make_assoc(lua_State *L, int tab) {
int i = 1, atab;
lua_newtable(L); atab = lua_gettop(L);
while (1) {
lua_pushnumber(L, i);
lua_gettable(L, tab);
if (!lua_isnil(L, -1)) {
lua_pushnumber(L, i);
lua_pushvalue(L, -2);
lua_settable(L, atab);
lua_pushnumber(L, i);
lua_settable(L, atab);
} else {
lua_pop(L, 1);
break;
}
i = i+1;
}
}
@@ -0,0 +1,17 @@
#ifndef SELECT_H
#define SELECT_H
/*=========================================================================*\
* Select implementation
* LuaSocket toolkit
*
* Each object that can be passed to the select function has to export
* method getfd() which returns the descriptor to be passed to the
* underlying select function. Another method, dirty(), should return
* true if there is data ready for reading (required for buffered input).
*
* RCS ID: $Id: select.h,v 1.7 2004/06/16 01:02:07 diego Exp $
\*=========================================================================*/
int select_open(lua_State *L);
#endif /* SELECT_H */
@@ -0,0 +1,251 @@
-----------------------------------------------------------------------------
-- SMTP client support for the Lua language.
-- LuaSocket toolkit.
-- Author: Diego Nehab
-- RCS ID: $Id: smtp.lua,v 1.46 2007/03/12 04:08:40 diego Exp $
-----------------------------------------------------------------------------
-----------------------------------------------------------------------------
-- Declare module and import dependencies
-----------------------------------------------------------------------------
local base = _G
local coroutine = require("coroutine")
local string = require("string")
local math = require("math")
local os = require("os")
local socket = require("socket")
local tp = require("socket.tp")
local ltn12 = require("ltn12")
local mime = require("mime")
module("socket.smtp")
-----------------------------------------------------------------------------
-- Program constants
-----------------------------------------------------------------------------
-- timeout for connection
TIMEOUT = 60
-- default server used to send e-mails
SERVER = "localhost"
-- default port
PORT = 25
-- domain used in HELO command and default sendmail
-- If we are under a CGI, try to get from environment
DOMAIN = os.getenv("SERVER_NAME") or "localhost"
-- default time zone (means we don't know)
ZONE = "-0000"
---------------------------------------------------------------------------
-- Low level SMTP API
-----------------------------------------------------------------------------
local metat = { __index = {} }
function metat.__index:greet(domain)
self.try(self.tp:check("2.."))
self.try(self.tp:command("EHLO", domain or DOMAIN))
return socket.skip(1, self.try(self.tp:check("2..")))
end
function metat.__index:mail(from)
self.try(self.tp:command("MAIL", "FROM:" .. from))
return self.try(self.tp:check("2.."))
end
function metat.__index:rcpt(to)
self.try(self.tp:command("RCPT", "TO:" .. to))
return self.try(self.tp:check("2.."))
end
function metat.__index:data(src, step)
self.try(self.tp:command("DATA"))
self.try(self.tp:check("3.."))
self.try(self.tp:source(src, step))
self.try(self.tp:send("\r\n.\r\n"))
return self.try(self.tp:check("2.."))
end
function metat.__index:quit()
self.try(self.tp:command("QUIT"))
return self.try(self.tp:check("2.."))
end
function metat.__index:close()
return self.tp:close()
end
function metat.__index:login(user, password)
self.try(self.tp:command("AUTH", "LOGIN"))
self.try(self.tp:check("3.."))
self.try(self.tp:command(mime.b64(user)))
self.try(self.tp:check("3.."))
self.try(self.tp:command(mime.b64(password)))
return self.try(self.tp:check("2.."))
end
function metat.__index:plain(user, password)
local auth = "PLAIN " .. mime.b64("\0" .. user .. "\0" .. password)
self.try(self.tp:command("AUTH", auth))
return self.try(self.tp:check("2.."))
end
function metat.__index:auth(user, password, ext)
if not user or not password then return 1 end
if string.find(ext, "AUTH[^\n]+LOGIN") then
return self:login(user, password)
elseif string.find(ext, "AUTH[^\n]+PLAIN") then
return self:plain(user, password)
else
self.try(nil, "authentication not supported")
end
end
-- send message or throw an exception
function metat.__index:send(mailt)
self:mail(mailt.from)
if base.type(mailt.rcpt) == "table" then
for i,v in base.ipairs(mailt.rcpt) do
self:rcpt(v)
end
else
self:rcpt(mailt.rcpt)
end
self:data(ltn12.source.chain(mailt.source, mime.stuff()), mailt.step)
end
function open(server, port, create)
local tp = socket.try(tp.connect(server or SERVER, port or PORT,
TIMEOUT, create))
local s = base.setmetatable({tp = tp}, metat)
-- make sure tp is closed if we get an exception
s.try = socket.newtry(function()
s:close()
end)
return s
end
-- convert headers to lowercase
local function lower_headers(headers)
local lower = {}
for i,v in base.pairs(headers or lower) do
lower[string.lower(i)] = v
end
return lower
end
---------------------------------------------------------------------------
-- Multipart message source
-----------------------------------------------------------------------------
-- returns a hopefully unique mime boundary
local seqno = 0
local function newboundary()
seqno = seqno + 1
return string.format('%s%05d==%05u', os.date('%d%m%Y%H%M%S'),
math.random(0, 99999), seqno)
end
-- send_message forward declaration
local send_message
-- yield the headers all at once, it's faster
local function send_headers(headers)
local h = "\r\n"
for i,v in base.pairs(headers) do
h = i .. ': ' .. v .. "\r\n" .. h
end
coroutine.yield(h)
end
-- yield multipart message body from a multipart message table
local function send_multipart(mesgt)
-- make sure we have our boundary and send headers
local bd = newboundary()
local headers = lower_headers(mesgt.headers or {})
headers['content-type'] = headers['content-type'] or 'multipart/mixed'
headers['content-type'] = headers['content-type'] ..
'; boundary="' .. bd .. '"'
send_headers(headers)
-- send preamble
if mesgt.body.preamble then
coroutine.yield(mesgt.body.preamble)
coroutine.yield("\r\n")
end
-- send each part separated by a boundary
for i, m in base.ipairs(mesgt.body) do
coroutine.yield("\r\n--" .. bd .. "\r\n")
send_message(m)
end
-- send last boundary
coroutine.yield("\r\n--" .. bd .. "--\r\n\r\n")
-- send epilogue
if mesgt.body.epilogue then
coroutine.yield(mesgt.body.epilogue)
coroutine.yield("\r\n")
end
end
-- yield message body from a source
local function send_source(mesgt)
-- make sure we have a content-type
local headers = lower_headers(mesgt.headers or {})
headers['content-type'] = headers['content-type'] or
'text/plain; charset="iso-8859-1"'
send_headers(headers)
-- send body from source
while true do
local chunk, err = mesgt.body()
if err then coroutine.yield(nil, err)
elseif chunk then coroutine.yield(chunk)
else break end
end
end
-- yield message body from a string
local function send_string(mesgt)
-- make sure we have a content-type
local headers = lower_headers(mesgt.headers or {})
headers['content-type'] = headers['content-type'] or
'text/plain; charset="iso-8859-1"'
send_headers(headers)
-- send body from string
coroutine.yield(mesgt.body)
end
-- message source
function send_message(mesgt)
if base.type(mesgt.body) == "table" then send_multipart(mesgt)
elseif base.type(mesgt.body) == "function" then send_source(mesgt)
else send_string(mesgt) end
end
-- set defaul headers
local function adjust_headers(mesgt)
local lower = lower_headers(mesgt.headers)
lower["date"] = lower["date"] or
os.date("!%a, %d %b %Y %H:%M:%S ") .. (mesgt.zone or ZONE)
lower["x-mailer"] = lower["x-mailer"] or socket._VERSION
-- this can't be overriden
lower["mime-version"] = "1.0"
return lower
end
function message(mesgt)
mesgt.headers = adjust_headers(mesgt)
-- create and return message source
local co = coroutine.create(function() send_message(mesgt) end)
return function()
local ret, a, b = coroutine.resume(co)
if ret then return a, b
else return nil, a end
end
end
---------------------------------------------------------------------------
-- High level SMTP API
-----------------------------------------------------------------------------
send = socket.protect(function(mailt)
local s = open(mailt.server, mailt.port, mailt.create)
local ext = s:greet(mailt.domain)
s:auth(mailt.user, mailt.password, ext)
s:send(mailt)
s:quit()
return s:close()
end)
@@ -0,0 +1,410 @@
/* code automatically generated by bin2c -- DO NOT EDIT */
{
/* #include'ing this file in a C program is equivalent to calling
if (luaL_loadfile(L,"smtp.lua")==0) lua_call(L, 0, 0);
*/
/* smtp.lua */
static const unsigned char B1[]={
45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45,
45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45,
45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45,
45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 10, 45, 45,
32, 83, 77, 84, 80, 32, 99,108,105,101,110,116, 32,115,117,112,112,111,114,116,
32,102,111,114, 32,116,104,101, 32, 76,117, 97, 32,108, 97,110,103,117, 97,103,
101, 46, 10, 45, 45, 32, 76,117, 97, 83,111, 99,107,101,116, 32,116,111,111,108,
107,105,116, 46, 10, 45, 45, 32, 65,117,116,104,111,114, 58, 32, 68,105,101,103,
111, 32, 78,101,104, 97, 98, 10, 45, 45, 32, 82, 67, 83, 32, 73, 68, 58, 32, 36,
73,100, 58, 32,115,109,116,112, 46,108,117, 97, 44,118, 32, 49, 46, 52, 54, 32,
50, 48, 48, 55, 47, 48, 51, 47, 49, 50, 32, 48, 52, 58, 48, 56, 58, 52, 48, 32,
100,105,101,103,111, 32, 69,120,112, 32, 36, 10, 45, 45, 45, 45, 45, 45, 45, 45,
45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45,
45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45,
45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45,
45, 45, 45, 45, 45, 45, 45, 45, 45, 10, 10, 45, 45, 45, 45, 45, 45, 45, 45, 45,
45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45,
45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45,
45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45,
45, 45, 45, 45, 45, 45, 45, 45, 10, 45, 45, 32, 68,101, 99,108, 97,114,101, 32,
109,111,100,117,108,101, 32, 97,110,100, 32,105,109,112,111,114,116, 32,100,101,
112,101,110,100,101,110, 99,105,101,115, 10, 45, 45, 45, 45, 45, 45, 45, 45, 45,
45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45,
45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45,
45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45,
45, 45, 45, 45, 45, 45, 45, 45, 10,108,111, 99, 97,108, 32, 98, 97,115,101, 32,
61, 32, 95, 71, 10,108,111, 99, 97,108, 32, 99,111,114,111,117,116,105,110,101,
32, 61, 32,114,101,113,117,105,114,101, 40, 34, 99,111,114,111,117,116,105,110,
101, 34, 41, 10,108,111, 99, 97,108, 32,115,116,114,105,110,103, 32, 61, 32,114,
101,113,117,105,114,101, 40, 34,115,116,114,105,110,103, 34, 41, 10,108,111, 99,
97,108, 32,109, 97,116,104, 32, 61, 32,114,101,113,117,105,114,101, 40, 34,109,
97,116,104, 34, 41, 10,108,111, 99, 97,108, 32,111,115, 32, 61, 32,114,101,113,
117,105,114,101, 40, 34,111,115, 34, 41, 10,108,111, 99, 97,108, 32,115,111, 99,
107,101,116, 32, 61, 32,114,101,113,117,105,114,101, 40, 34,115,111, 99,107,101,
116, 34, 41, 10,108,111, 99, 97,108, 32,116,112, 32, 61, 32,114,101,113,117,105,
114,101, 40, 34,115,111, 99,107,101,116, 46,116,112, 34, 41, 10,108,111, 99, 97,
108, 32,108,116,110, 49, 50, 32, 61, 32,114,101,113,117,105,114,101, 40, 34,108,
116,110, 49, 50, 34, 41, 10,108,111, 99, 97,108, 32,109,105,109,101, 32, 61, 32,
114,101,113,117,105,114,101, 40, 34,109,105,109,101, 34, 41, 10,109,111,100,117,
108,101, 40, 34,115,111, 99,107,101,116, 46,115,109,116,112, 34, 41, 10, 10, 45,
45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45,
45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45,
45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45,
45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 10, 45, 45, 32,
80,114,111,103,114, 97,109, 32, 99,111,110,115,116, 97,110,116,115, 10, 45, 45,
45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45,
45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45,
45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45,
45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 10, 45, 45, 32,116,
105,109,101,111,117,116, 32,102,111,114, 32, 99,111,110,110,101, 99,116,105,111,
110, 10, 84, 73, 77, 69, 79, 85, 84, 32, 61, 32, 54, 48, 10, 45, 45, 32,100,101,
102, 97,117,108,116, 32,115,101,114,118,101,114, 32,117,115,101,100, 32,116,111,
32,115,101,110,100, 32,101, 45,109, 97,105,108,115, 10, 83, 69, 82, 86, 69, 82,
32, 61, 32, 34,108,111, 99, 97,108,104,111,115,116, 34, 10, 45, 45, 32,100,101,
102, 97,117,108,116, 32,112,111,114,116, 10, 80, 79, 82, 84, 32, 61, 32, 50, 53,
10, 45, 45, 32,100,111,109, 97,105,110, 32,117,115,101,100, 32,105,110, 32, 72,
69, 76, 79, 32, 99,111,109,109, 97,110,100, 32, 97,110,100, 32,100,101,102, 97,
117,108,116, 32,115,101,110,100,109, 97,105,108, 10, 45, 45, 32, 73,102, 32,119,
101, 32, 97,114,101, 32,117,110,100,101,114, 32, 97, 32, 67, 71, 73, 44, 32,116,
114,121, 32,116,111, 32,103,101,116, 32,102,114,111,109, 32,101,110,118,105,114,
111,110,109,101,110,116, 10, 68, 79, 77, 65, 73, 78, 32, 61, 32,111,115, 46,103,
101,116,101,110,118, 40, 34, 83, 69, 82, 86, 69, 82, 95, 78, 65, 77, 69, 34, 41,
32,111,114, 32, 34,108,111, 99, 97,108,104,111,115,116, 34, 10, 45, 45, 32,100,
101,102, 97,117,108,116, 32,116,105,109,101, 32,122,111,110,101, 32, 40,109,101,
97,110,115, 32,119,101, 32,100,111,110, 39,116, 32,107,110,111,119, 41, 10, 90,
79, 78, 69, 32, 61, 32, 34, 45, 48, 48, 48, 48, 34, 10, 10, 45, 45, 45, 45, 45,
45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45,
45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45,
45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45,
45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 10, 45, 45, 32, 76,111,119, 32,108,101,
118,101,108, 32, 83, 77, 84, 80, 32, 65, 80, 73, 10, 45, 45, 45, 45, 45, 45, 45,
45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45,
45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45,
45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45,
45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 10,108,111, 99, 97,108, 32,109,101,116,
97,116, 32, 61, 32,123, 32, 95, 95,105,110,100,101,120, 32, 61, 32,123,125, 32,
125, 10, 10,102,117,110, 99,116,105,111,110, 32,109,101,116, 97,116, 46, 95, 95,
105,110,100,101,120, 58,103,114,101,101,116, 40,100,111,109, 97,105,110, 41, 10,
32, 32, 32, 32,115,101,108,102, 46,116,114,121, 40,115,101,108,102, 46,116,112,
58, 99,104,101, 99,107, 40, 34, 50, 46, 46, 34, 41, 41, 10, 32, 32, 32, 32,115,
101,108,102, 46,116,114,121, 40,115,101,108,102, 46,116,112, 58, 99,111,109,109,
97,110,100, 40, 34, 69, 72, 76, 79, 34, 44, 32,100,111,109, 97,105,110, 32,111,
114, 32, 68, 79, 77, 65, 73, 78, 41, 41, 10, 32, 32, 32, 32,114,101,116,117,114,
110, 32,115,111, 99,107,101,116, 46,115,107,105,112, 40, 49, 44, 32,115,101,108,
102, 46,116,114,121, 40,115,101,108,102, 46,116,112, 58, 99,104,101, 99,107, 40,
34, 50, 46, 46, 34, 41, 41, 41, 10,101,110,100, 10, 10,102,117,110, 99,116,105,
111,110, 32,109,101,116, 97,116, 46, 95, 95,105,110,100,101,120, 58,109, 97,105,
108, 40,102,114,111,109, 41, 10, 32, 32, 32, 32,115,101,108,102, 46,116,114,121,
40,115,101,108,102, 46,116,112, 58, 99,111,109,109, 97,110,100, 40, 34, 77, 65,
73, 76, 34, 44, 32, 34, 70, 82, 79, 77, 58, 34, 32, 46, 46, 32,102,114,111,109,
41, 41, 10, 32, 32, 32, 32,114,101,116,117,114,110, 32,115,101,108,102, 46,116,
114,121, 40,115,101,108,102, 46,116,112, 58, 99,104,101, 99,107, 40, 34, 50, 46,
46, 34, 41, 41, 10,101,110,100, 10, 10,102,117,110, 99,116,105,111,110, 32,109,
101,116, 97,116, 46, 95, 95,105,110,100,101,120, 58,114, 99,112,116, 40,116,111,
41, 10, 32, 32, 32, 32,115,101,108,102, 46,116,114,121, 40,115,101,108,102, 46,
116,112, 58, 99,111,109,109, 97,110,100, 40, 34, 82, 67, 80, 84, 34, 44, 32, 34,
84, 79, 58, 34, 32, 46, 46, 32,116,111, 41, 41, 10, 32, 32, 32, 32,114,101,116,
117,114,110, 32,115,101,108,102, 46,116,114,121, 40,115,101,108,102, 46,116,112,
58, 99,104,101, 99,107, 40, 34, 50, 46, 46, 34, 41, 41, 10,101,110,100, 10, 10,
102,117,110, 99,116,105,111,110, 32,109,101,116, 97,116, 46, 95, 95,105,110,100,
101,120, 58,100, 97,116, 97, 40,115,114, 99, 44, 32,115,116,101,112, 41, 10, 32,
32, 32, 32,115,101,108,102, 46,116,114,121, 40,115,101,108,102, 46,116,112, 58,
99,111,109,109, 97,110,100, 40, 34, 68, 65, 84, 65, 34, 41, 41, 10, 32, 32, 32,
32,115,101,108,102, 46,116,114,121, 40,115,101,108,102, 46,116,112, 58, 99,104,
101, 99,107, 40, 34, 51, 46, 46, 34, 41, 41, 10, 32, 32, 32, 32,115,101,108,102,
46,116,114,121, 40,115,101,108,102, 46,116,112, 58,115,111,117,114, 99,101, 40,
115,114, 99, 44, 32,115,116,101,112, 41, 41, 10, 32, 32, 32, 32,115,101,108,102,
46,116,114,121, 40,115,101,108,102, 46,116,112, 58,115,101,110,100, 40, 34, 92,
114, 92,110, 46, 92,114, 92,110, 34, 41, 41, 10, 32, 32, 32, 32,114,101,116,117,
114,110, 32,115,101,108,102, 46,116,114,121, 40,115,101,108,102, 46,116,112, 58,
99,104,101, 99,107, 40, 34, 50, 46, 46, 34, 41, 41, 10,101,110,100, 10, 10,102,
117,110, 99,116,105,111,110, 32,109,101,116, 97,116, 46, 95, 95,105,110,100,101,
120, 58,113,117,105,116, 40, 41, 10, 32, 32, 32, 32,115,101,108,102, 46,116,114,
121, 40,115,101,108,102, 46,116,112, 58, 99,111,109,109, 97,110,100, 40, 34, 81,
85, 73, 84, 34, 41, 41, 10, 32, 32, 32, 32,114,101,116,117,114,110, 32,115,101,
108,102, 46,116,114,121, 40,115,101,108,102, 46,116,112, 58, 99,104,101, 99,107,
40, 34, 50, 46, 46, 34, 41, 41, 10,101,110,100, 10, 10,102,117,110, 99,116,105,
111,110, 32,109,101,116, 97,116, 46, 95, 95,105,110,100,101,120, 58, 99,108,111,
115,101, 40, 41, 10, 32, 32, 32, 32,114,101,116,117,114,110, 32,115,101,108,102,
46,116,112, 58, 99,108,111,115,101, 40, 41, 10,101,110,100, 10, 10,102,117,110,
99,116,105,111,110, 32,109,101,116, 97,116, 46, 95, 95,105,110,100,101,120, 58,
108,111,103,105,110, 40,117,115,101,114, 44, 32,112, 97,115,115,119,111,114,100,
41, 10, 32, 32, 32, 32,115,101,108,102, 46,116,114,121, 40,115,101,108,102, 46,
116,112, 58, 99,111,109,109, 97,110,100, 40, 34, 65, 85, 84, 72, 34, 44, 32, 34,
76, 79, 71, 73, 78, 34, 41, 41, 10, 32, 32, 32, 32,115,101,108,102, 46,116,114,
121, 40,115,101,108,102, 46,116,112, 58, 99,104,101, 99,107, 40, 34, 51, 46, 46,
34, 41, 41, 10, 32, 32, 32, 32,115,101,108,102, 46,116,114,121, 40,115,101,108,
102, 46,116,112, 58, 99,111,109,109, 97,110,100, 40,109,105,109,101, 46, 98, 54,
52, 40,117,115,101,114, 41, 41, 41, 10, 32, 32, 32, 32,115,101,108,102, 46,116,
114,121, 40,115,101,108,102, 46,116,112, 58, 99,104,101, 99,107, 40, 34, 51, 46,
46, 34, 41, 41, 10, 32, 32, 32, 32,115,101,108,102, 46,116,114,121, 40,115,101,
108,102, 46,116,112, 58, 99,111,109,109, 97,110,100, 40,109,105,109,101, 46, 98,
54, 52, 40,112, 97,115,115,119,111,114,100, 41, 41, 41, 10, 32, 32, 32, 32,114,
101,116,117,114,110, 32,115,101,108,102, 46,116,114,121, 40,115,101,108,102, 46,
116,112, 58, 99,104,101, 99,107, 40, 34, 50, 46, 46, 34, 41, 41, 10,101,110,100,
10, 10,102,117,110, 99,116,105,111,110, 32,109,101,116, 97,116, 46, 95, 95,105,
110,100,101,120, 58,112,108, 97,105,110, 40,117,115,101,114, 44, 32,112, 97,115,
115,119,111,114,100, 41, 10, 32, 32, 32, 32,108,111, 99, 97,108, 32, 97,117,116,
104, 32, 61, 32, 34, 80, 76, 65, 73, 78, 32, 34, 32, 46, 46, 32,109,105,109,101,
46, 98, 54, 52, 40, 34, 92, 48, 34, 32, 46, 46, 32,117,115,101,114, 32, 46, 46,
32, 34, 92, 48, 34, 32, 46, 46, 32,112, 97,115,115,119,111,114,100, 41, 10, 32,
32, 32, 32,115,101,108,102, 46,116,114,121, 40,115,101,108,102, 46,116,112, 58,
99,111,109,109, 97,110,100, 40, 34, 65, 85, 84, 72, 34, 44, 32, 97,117,116,104,
41, 41, 10, 32, 32, 32, 32,114,101,116,117,114,110, 32,115,101,108,102, 46,116,
114,121, 40,115,101,108,102, 46,116,112, 58, 99,104,101, 99,107, 40, 34, 50, 46,
46, 34, 41, 41, 10,101,110,100, 10, 10,102,117,110, 99,116,105,111,110, 32,109,
101,116, 97,116, 46, 95, 95,105,110,100,101,120, 58, 97,117,116,104, 40,117,115,
101,114, 44, 32,112, 97,115,115,119,111,114,100, 44, 32,101,120,116, 41, 10, 32,
32, 32, 32,105,102, 32,110,111,116, 32,117,115,101,114, 32,111,114, 32,110,111,
116, 32,112, 97,115,115,119,111,114,100, 32,116,104,101,110, 32,114,101,116,117,
114,110, 32, 49, 32,101,110,100, 10, 32, 32, 32, 32,105,102, 32,115,116,114,105,
110,103, 46,102,105,110,100, 40,101,120,116, 44, 32, 34, 65, 85, 84, 72, 91, 94,
92,110, 93, 43, 76, 79, 71, 73, 78, 34, 41, 32,116,104,101,110, 10, 32, 32, 32,
32, 32, 32, 32, 32,114,101,116,117,114,110, 32,115,101,108,102, 58,108,111,103,
105,110, 40,117,115,101,114, 44, 32,112, 97,115,115,119,111,114,100, 41, 10, 32,
32, 32, 32,101,108,115,101,105,102, 32,115,116,114,105,110,103, 46,102,105,110,
100, 40,101,120,116, 44, 32, 34, 65, 85, 84, 72, 91, 94, 92,110, 93, 43, 80, 76,
65, 73, 78, 34, 41, 32,116,104,101,110, 10, 32, 32, 32, 32, 32, 32, 32, 32,114,
101,116,117,114,110, 32,115,101,108,102, 58,112,108, 97,105,110, 40,117,115,101,
114, 44, 32,112, 97,115,115,119,111,114,100, 41, 10, 32, 32, 32, 32,101,108,115,
101, 10, 32, 32, 32, 32, 32, 32, 32, 32,115,101,108,102, 46,116,114,121, 40,110,
105,108, 44, 32, 34, 97,117,116,104,101,110,116,105, 99, 97,116,105,111,110, 32,
110,111,116, 32,115,117,112,112,111,114,116,101,100, 34, 41, 10, 32, 32, 32, 32,
101,110,100, 10,101,110,100, 10, 10, 45, 45, 32,115,101,110,100, 32,109,101,115,
115, 97,103,101, 32,111,114, 32,116,104,114,111,119, 32, 97,110, 32,101,120, 99,
101,112,116,105,111,110, 10,102,117,110, 99,116,105,111,110, 32,109,101,116, 97,
116, 46, 95, 95,105,110,100,101,120, 58,115,101,110,100, 40,109, 97,105,108,116,
41, 10, 32, 32, 32, 32,115,101,108,102, 58,109, 97,105,108, 40,109, 97,105,108,
116, 46,102,114,111,109, 41, 10, 32, 32, 32, 32,105,102, 32, 98, 97,115,101, 46,
116,121,112,101, 40,109, 97,105,108,116, 46,114, 99,112,116, 41, 32, 61, 61, 32,
34,116, 97, 98,108,101, 34, 32,116,104,101,110, 10, 32, 32, 32, 32, 32, 32, 32,
32,102,111,114, 32,105, 44,118, 32,105,110, 32, 98, 97,115,101, 46,105,112, 97,
105,114,115, 40,109, 97,105,108,116, 46,114, 99,112,116, 41, 32,100,111, 10, 32,
32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,115,101,108,102, 58,114, 99,112,116,
40,118, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32,101,110,100, 10, 32, 32, 32, 32,
101,108,115,101, 10, 32, 32, 32, 32, 32, 32, 32, 32,115,101,108,102, 58,114, 99,
112,116, 40,109, 97,105,108,116, 46,114, 99,112,116, 41, 10, 32, 32, 32, 32,101,
110,100, 10, 32, 32, 32, 32,115,101,108,102, 58,100, 97,116, 97, 40,108,116,110,
49, 50, 46,115,111,117,114, 99,101, 46, 99,104, 97,105,110, 40,109, 97,105,108,
116, 46,115,111,117,114, 99,101, 44, 32,109,105,109,101, 46,115,116,117,102,102,
40, 41, 41, 44, 32,109, 97,105,108,116, 46,115,116,101,112, 41, 10,101,110,100,
10, 10,102,117,110, 99,116,105,111,110, 32,111,112,101,110, 40,115,101,114,118,
101,114, 44, 32,112,111,114,116, 44, 32, 99,114,101, 97,116,101, 41, 10, 32, 32,
32, 32,108,111, 99, 97,108, 32,116,112, 32, 61, 32,115,111, 99,107,101,116, 46,
116,114,121, 40,116,112, 46, 99,111,110,110,101, 99,116, 40,115,101,114,118,101,
114, 32,111,114, 32, 83, 69, 82, 86, 69, 82, 44, 32,112,111,114,116, 32,111,114,
32, 80, 79, 82, 84, 44, 10, 32, 32, 32, 32, 32, 32, 32, 32, 84, 73, 77, 69, 79,
85, 84, 44, 32, 99,114,101, 97,116,101, 41, 41, 10, 32, 32, 32, 32,108,111, 99,
97,108, 32,115, 32, 61, 32, 98, 97,115,101, 46,115,101,116,109,101,116, 97,116,
97, 98,108,101, 40,123,116,112, 32, 61, 32,116,112,125, 44, 32,109,101,116, 97,
116, 41, 10, 32, 32, 32, 32, 45, 45, 32,109, 97,107,101, 32,115,117,114,101, 32,
116,112, 32,105,115, 32, 99,108,111,115,101,100, 32,105,102, 32,119,101, 32,103,
101,116, 32, 97,110, 32,101,120, 99,101,112,116,105,111,110, 10, 32, 32, 32, 32,
115, 46,116,114,121, 32, 61, 32,115,111, 99,107,101,116, 46,110,101,119,116,114,
121, 40,102,117,110, 99,116,105,111,110, 40, 41, 10, 32, 32, 32, 32, 32, 32, 32,
32,115, 58, 99,108,111,115,101, 40, 41, 10, 32, 32, 32, 32,101,110,100, 41, 10,
32, 32, 32, 32,114,101,116,117,114,110, 32,115, 10,101,110,100, 10, 10, 45, 45,
32, 99,111,110,118,101,114,116, 32,104,101, 97,100,101,114,115, 32,116,111, 32,
108,111,119,101,114, 99, 97,115,101, 10,108,111, 99, 97,108, 32,102,117,110, 99,
116,105,111,110, 32,108,111,119,101,114, 95,104,101, 97,100,101,114,115, 40,104,
101, 97,100,101,114,115, 41, 10, 32, 32, 32, 32,108,111, 99, 97,108, 32,108,111,
119,101,114, 32, 61, 32,123,125, 10, 32, 32, 32, 32,102,111,114, 32,105, 44,118,
32,105,110, 32, 98, 97,115,101, 46,112, 97,105,114,115, 40,104,101, 97,100,101,
114,115, 32,111,114, 32,108,111,119,101,114, 41, 32,100,111, 10, 32, 32, 32, 32,
32, 32, 32, 32,108,111,119,101,114, 91,115,116,114,105,110,103, 46,108,111,119,
101,114, 40,105, 41, 93, 32, 61, 32,118, 10, 32, 32, 32, 32,101,110,100, 10, 32,
32, 32, 32,114,101,116,117,114,110, 32,108,111,119,101,114, 10,101,110,100, 10,
10, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45,
45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45,
45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45,
45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 10, 45, 45, 32,
77,117,108,116,105,112, 97,114,116, 32,109,101,115,115, 97,103,101, 32,115,111,
117,114, 99,101, 10, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45,
45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45,
45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45,
45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45,
45, 45, 10, 45, 45, 32,114,101,116,117,114,110,115, 32, 97, 32,104,111,112,101,
102,117,108,108,121, 32,117,110,105,113,117,101, 32,109,105,109,101, 32, 98,111,
117,110,100, 97,114,121, 10,108,111, 99, 97,108, 32,115,101,113,110,111, 32, 61,
32, 48, 10,108,111, 99, 97,108, 32,102,117,110, 99,116,105,111,110, 32,110,101,
119, 98,111,117,110,100, 97,114,121, 40, 41, 10, 32, 32, 32, 32,115,101,113,110,
111, 32, 61, 32,115,101,113,110,111, 32, 43, 32, 49, 10, 32, 32, 32, 32,114,101,
116,117,114,110, 32,115,116,114,105,110,103, 46,102,111,114,109, 97,116, 40, 39,
37,115, 37, 48, 53,100, 61, 61, 37, 48, 53,117, 39, 44, 32,111,115, 46,100, 97,
116,101, 40, 39, 37,100, 37,109, 37, 89, 37, 72, 37, 77, 37, 83, 39, 41, 44, 10,
32, 32, 32, 32, 32, 32, 32, 32,109, 97,116,104, 46,114, 97,110,100,111,109, 40,
48, 44, 32, 57, 57, 57, 57, 57, 41, 44, 32,115,101,113,110,111, 41, 10,101,110,
100, 10, 10, 45, 45, 32,115,101,110,100, 95,109,101,115,115, 97,103,101, 32,102,
111,114,119, 97,114,100, 32,100,101, 99,108, 97,114, 97,116,105,111,110, 10,108,
111, 99, 97,108, 32,115,101,110,100, 95,109,101,115,115, 97,103,101, 10, 10, 45,
45, 32,121,105,101,108,100, 32,116,104,101, 32,104,101, 97,100,101,114,115, 32,
97,108,108, 32, 97,116, 32,111,110, 99,101, 44, 32,105,116, 39,115, 32,102, 97,
115,116,101,114, 10,108,111, 99, 97,108, 32,102,117,110, 99,116,105,111,110, 32,
115,101,110,100, 95,104,101, 97,100,101,114,115, 40,104,101, 97,100,101,114,115,
41, 10, 32, 32, 32, 32,108,111, 99, 97,108, 32,104, 32, 61, 32, 34, 92,114, 92,
110, 34, 10, 32, 32, 32, 32,102,111,114, 32,105, 44,118, 32,105,110, 32, 98, 97,
115,101, 46,112, 97,105,114,115, 40,104,101, 97,100,101,114,115, 41, 32,100,111,
10, 32, 32, 32, 32, 32, 32, 32, 32,104, 32, 61, 32,105, 32, 46, 46, 32, 39, 58,
32, 39, 32, 46, 46, 32,118, 32, 46, 46, 32, 34, 92,114, 92,110, 34, 32, 46, 46,
32,104, 10, 32, 32, 32, 32,101,110,100, 10, 32, 32, 32, 32, 99,111,114,111,117,
116,105,110,101, 46,121,105,101,108,100, 40,104, 41, 10,101,110,100, 10, 10, 45,
45, 32,121,105,101,108,100, 32,109,117,108,116,105,112, 97,114,116, 32,109,101,
115,115, 97,103,101, 32, 98,111,100,121, 32,102,114,111,109, 32, 97, 32,109,117,
108,116,105,112, 97,114,116, 32,109,101,115,115, 97,103,101, 32,116, 97, 98,108,
101, 10,108,111, 99, 97,108, 32,102,117,110, 99,116,105,111,110, 32,115,101,110,
100, 95,109,117,108,116,105,112, 97,114,116, 40,109,101,115,103,116, 41, 10, 32,
32, 32, 32, 45, 45, 32,109, 97,107,101, 32,115,117,114,101, 32,119,101, 32,104,
97,118,101, 32,111,117,114, 32, 98,111,117,110,100, 97,114,121, 32, 97,110,100,
32,115,101,110,100, 32,104,101, 97,100,101,114,115, 10, 32, 32, 32, 32,108,111,
99, 97,108, 32, 98,100, 32, 61, 32,110,101,119, 98,111,117,110,100, 97,114,121,
40, 41, 10, 32, 32, 32, 32,108,111, 99, 97,108, 32,104,101, 97,100,101,114,115,
32, 61, 32,108,111,119,101,114, 95,104,101, 97,100,101,114,115, 40,109,101,115,
103,116, 46,104,101, 97,100,101,114,115, 32,111,114, 32,123,125, 41, 10, 32, 32,
32, 32,104,101, 97,100,101,114,115, 91, 39, 99,111,110,116,101,110,116, 45,116,
121,112,101, 39, 93, 32, 61, 32,104,101, 97,100,101,114,115, 91, 39, 99,111,110,
116,101,110,116, 45,116,121,112,101, 39, 93, 32,111,114, 32, 39,109,117,108,116,
105,112, 97,114,116, 47,109,105,120,101,100, 39, 10, 32, 32, 32, 32,104,101, 97,
100,101,114,115, 91, 39, 99,111,110,116,101,110,116, 45,116,121,112,101, 39, 93,
32, 61, 32,104,101, 97,100,101,114,115, 91, 39, 99,111,110,116,101,110,116, 45,
116,121,112,101, 39, 93, 32, 46, 46, 10, 32, 32, 32, 32, 32, 32, 32, 32, 39, 59,
32, 98,111,117,110,100, 97,114,121, 61, 34, 39, 32, 46, 46, 32, 32, 98,100, 32,
46, 46, 32, 39, 34, 39, 10, 32, 32, 32, 32,115,101,110,100, 95,104,101, 97,100,
101,114,115, 40,104,101, 97,100,101,114,115, 41, 10, 32, 32, 32, 32, 45, 45, 32,
115,101,110,100, 32,112,114,101, 97,109, 98,108,101, 10, 32, 32, 32, 32,105,102,
32,109,101,115,103,116, 46, 98,111,100,121, 46,112,114,101, 97,109, 98,108,101,
32,116,104,101,110, 10, 32, 32, 32, 32, 32, 32, 32, 32, 99,111,114,111,117,116,
105,110,101, 46,121,105,101,108,100, 40,109,101,115,103,116, 46, 98,111,100,121,
46,112,114,101, 97,109, 98,108,101, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 99,
111,114,111,117,116,105,110,101, 46,121,105,101,108,100, 40, 34, 92,114, 92,110,
34, 41, 10, 32, 32, 32, 32,101,110,100, 10, 32, 32, 32, 32, 45, 45, 32,115,101,
110,100, 32,101, 97, 99,104, 32,112, 97,114,116, 32,115,101,112, 97,114, 97,116,
101,100, 32, 98,121, 32, 97, 32, 98,111,117,110,100, 97,114,121, 10, 32, 32, 32,
32,102,111,114, 32,105, 44, 32,109, 32,105,110, 32, 98, 97,115,101, 46,105,112,
97,105,114,115, 40,109,101,115,103,116, 46, 98,111,100,121, 41, 32,100,111, 10,
32, 32, 32, 32, 32, 32, 32, 32, 99,111,114,111,117,116,105,110,101, 46,121,105,
101,108,100, 40, 34, 92,114, 92,110, 45, 45, 34, 32, 46, 46, 32, 98,100, 32, 46,
46, 32, 34, 92,114, 92,110, 34, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32,115,101,
110,100, 95,109,101,115,115, 97,103,101, 40,109, 41, 10, 32, 32, 32, 32,101,110,
100, 10, 32, 32, 32, 32, 45, 45, 32,115,101,110,100, 32,108, 97,115,116, 32, 98,
111,117,110,100, 97,114,121, 10, 32, 32, 32, 32, 99,111,114,111,117,116,105,110,
101, 46,121,105,101,108,100, 40, 34, 92,114, 92,110, 45, 45, 34, 32, 46, 46, 32,
98,100, 32, 46, 46, 32, 34, 45, 45, 92,114, 92,110, 92,114, 92,110, 34, 41, 10,
32, 32, 32, 32, 45, 45, 32,115,101,110,100, 32,101,112,105,108,111,103,117,101,
10, 32, 32, 32, 32,105,102, 32,109,101,115,103,116, 46, 98,111,100,121, 46,101,
112,105,108,111,103,117,101, 32,116,104,101,110, 10, 32, 32, 32, 32, 32, 32, 32,
32, 99,111,114,111,117,116,105,110,101, 46,121,105,101,108,100, 40,109,101,115,
103,116, 46, 98,111,100,121, 46,101,112,105,108,111,103,117,101, 41, 10, 32, 32,
32, 32, 32, 32, 32, 32, 99,111,114,111,117,116,105,110,101, 46,121,105,101,108,
100, 40, 34, 92,114, 92,110, 34, 41, 10, 32, 32, 32, 32,101,110,100, 10,101,110,
100, 10, 10, 45, 45, 32,121,105,101,108,100, 32,109,101,115,115, 97,103,101, 32,
98,111,100,121, 32,102,114,111,109, 32, 97, 32,115,111,117,114, 99,101, 10,108,
111, 99, 97,108, 32,102,117,110, 99,116,105,111,110, 32,115,101,110,100, 95,115,
111,117,114, 99,101, 40,109,101,115,103,116, 41, 10, 32, 32, 32, 32, 45, 45, 32,
109, 97,107,101, 32,115,117,114,101, 32,119,101, 32,104, 97,118,101, 32, 97, 32,
99,111,110,116,101,110,116, 45,116,121,112,101, 10, 32, 32, 32, 32,108,111, 99,
97,108, 32,104,101, 97,100,101,114,115, 32, 61, 32,108,111,119,101,114, 95,104,
101, 97,100,101,114,115, 40,109,101,115,103,116, 46,104,101, 97,100,101,114,115,
32,111,114, 32,123,125, 41, 10, 32, 32, 32, 32,104,101, 97,100,101,114,115, 91,
39, 99,111,110,116,101,110,116, 45,116,121,112,101, 39, 93, 32, 61, 32,104,101,
97,100,101,114,115, 91, 39, 99,111,110,116,101,110,116, 45,116,121,112,101, 39,
93, 32,111,114, 10, 32, 32, 32, 32, 32, 32, 32, 32, 39,116,101,120,116, 47,112,
108, 97,105,110, 59, 32, 99,104, 97,114,115,101,116, 61, 34,105,115,111, 45, 56,
56, 53, 57, 45, 49, 34, 39, 10, 32, 32, 32, 32,115,101,110,100, 95,104,101, 97,
100,101,114,115, 40,104,101, 97,100,101,114,115, 41, 10, 32, 32, 32, 32, 45, 45,
32,115,101,110,100, 32, 98,111,100,121, 32,102,114,111,109, 32,115,111,117,114,
99,101, 10, 32, 32, 32, 32,119,104,105,108,101, 32,116,114,117,101, 32,100,111,
10, 32, 32, 32, 32, 32, 32, 32, 32,108,111, 99, 97,108, 32, 99,104,117,110,107,
44, 32,101,114,114, 32, 61, 32,109,101,115,103,116, 46, 98,111,100,121, 40, 41,
10, 32, 32, 32, 32, 32, 32, 32, 32,105,102, 32,101,114,114, 32,116,104,101,110,
32, 99,111,114,111,117,116,105,110,101, 46,121,105,101,108,100, 40,110,105,108,
44, 32,101,114,114, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32,101,108,115,101,105,
102, 32, 99,104,117,110,107, 32,116,104,101,110, 32, 99,111,114,111,117,116,105,
110,101, 46,121,105,101,108,100, 40, 99,104,117,110,107, 41, 10, 32, 32, 32, 32,
32, 32, 32, 32,101,108,115,101, 32, 98,114,101, 97,107, 32,101,110,100, 10, 32,
32, 32, 32,101,110,100, 10,101,110,100, 10, 10, 45, 45, 32,121,105,101,108,100,
32,109,101,115,115, 97,103,101, 32, 98,111,100,121, 32,102,114,111,109, 32, 97,
32,115,116,114,105,110,103, 10,108,111, 99, 97,108, 32,102,117,110, 99,116,105,
111,110, 32,115,101,110,100, 95,115,116,114,105,110,103, 40,109,101,115,103,116,
41, 10, 32, 32, 32, 32, 45, 45, 32,109, 97,107,101, 32,115,117,114,101, 32,119,
101, 32,104, 97,118,101, 32, 97, 32, 99,111,110,116,101,110,116, 45,116,121,112,
101, 10, 32, 32, 32, 32,108,111, 99, 97,108, 32,104,101, 97,100,101,114,115, 32,
61, 32,108,111,119,101,114, 95,104,101, 97,100,101,114,115, 40,109,101,115,103,
116, 46,104,101, 97,100,101,114,115, 32,111,114, 32,123,125, 41, 10, 32, 32, 32,
32,104,101, 97,100,101,114,115, 91, 39, 99,111,110,116,101,110,116, 45,116,121,
112,101, 39, 93, 32, 61, 32,104,101, 97,100,101,114,115, 91, 39, 99,111,110,116,
101,110,116, 45,116,121,112,101, 39, 93, 32,111,114, 10, 32, 32, 32, 32, 32, 32,
32, 32, 39,116,101,120,116, 47,112,108, 97,105,110, 59, 32, 99,104, 97,114,115,
101,116, 61, 34,105,115,111, 45, 56, 56, 53, 57, 45, 49, 34, 39, 10, 32, 32, 32,
32,115,101,110,100, 95,104,101, 97,100,101,114,115, 40,104,101, 97,100,101,114,
115, 41, 10, 32, 32, 32, 32, 45, 45, 32,115,101,110,100, 32, 98,111,100,121, 32,
102,114,111,109, 32,115,116,114,105,110,103, 10, 32, 32, 32, 32, 99,111,114,111,
117,116,105,110,101, 46,121,105,101,108,100, 40,109,101,115,103,116, 46, 98,111,
100,121, 41, 10,101,110,100, 10, 10, 45, 45, 32,109,101,115,115, 97,103,101, 32,
115,111,117,114, 99,101, 10,102,117,110, 99,116,105,111,110, 32,115,101,110,100,
95,109,101,115,115, 97,103,101, 40,109,101,115,103,116, 41, 10, 32, 32, 32, 32,
105,102, 32, 98, 97,115,101, 46,116,121,112,101, 40,109,101,115,103,116, 46, 98,
111,100,121, 41, 32, 61, 61, 32, 34,116, 97, 98,108,101, 34, 32,116,104,101,110,
32,115,101,110,100, 95,109,117,108,116,105,112, 97,114,116, 40,109,101,115,103,
116, 41, 10, 32, 32, 32, 32,101,108,115,101,105,102, 32, 98, 97,115,101, 46,116,
121,112,101, 40,109,101,115,103,116, 46, 98,111,100,121, 41, 32, 61, 61, 32, 34,
102,117,110, 99,116,105,111,110, 34, 32,116,104,101,110, 32,115,101,110,100, 95,
115,111,117,114, 99,101, 40,109,101,115,103,116, 41, 10, 32, 32, 32, 32,101,108,
115,101, 32,115,101,110,100, 95,115,116,114,105,110,103, 40,109,101,115,103,116,
41, 32,101,110,100, 10,101,110,100, 10, 10, 45, 45, 32,115,101,116, 32,100,101,
102, 97,117,108, 32,104,101, 97,100,101,114,115, 10,108,111, 99, 97,108, 32,102,
117,110, 99,116,105,111,110, 32, 97,100,106,117,115,116, 95,104,101, 97,100,101,
114,115, 40,109,101,115,103,116, 41, 10, 32, 32, 32, 32,108,111, 99, 97,108, 32,
108,111,119,101,114, 32, 61, 32,108,111,119,101,114, 95,104,101, 97,100,101,114,
115, 40,109,101,115,103,116, 46,104,101, 97,100,101,114,115, 41, 10, 32, 32, 32,
32,108,111,119,101,114, 91, 34,100, 97,116,101, 34, 93, 32, 61, 32,108,111,119,
101,114, 91, 34,100, 97,116,101, 34, 93, 32,111,114, 10, 32, 32, 32, 32, 32, 32,
32, 32,111,115, 46,100, 97,116,101, 40, 34, 33, 37, 97, 44, 32, 37,100, 32, 37,
98, 32, 37, 89, 32, 37, 72, 58, 37, 77, 58, 37, 83, 32, 34, 41, 32, 46, 46, 32,
40,109,101,115,103,116, 46,122,111,110,101, 32,111,114, 32, 90, 79, 78, 69, 41,
10, 32, 32, 32, 32,108,111,119,101,114, 91, 34,120, 45,109, 97,105,108,101,114,
34, 93, 32, 61, 32,108,111,119,101,114, 91, 34,120, 45,109, 97,105,108,101,114,
34, 93, 32,111,114, 32,115,111, 99,107,101,116, 46, 95, 86, 69, 82, 83, 73, 79,
78, 10, 32, 32, 32, 32, 45, 45, 32,116,104,105,115, 32, 99, 97,110, 39,116, 32,
98,101, 32,111,118,101,114,114,105,100,101,110, 10, 32, 32, 32, 32,108,111,119,
101,114, 91, 34,109,105,109,101, 45,118,101,114,115,105,111,110, 34, 93, 32, 61,
32, 34, 49, 46, 48, 34, 10, 32, 32, 32, 32,114,101,116,117,114,110, 32,108,111,
119,101,114, 10,101,110,100, 10, 10,102,117,110, 99,116,105,111,110, 32,109,101,
115,115, 97,103,101, 40,109,101,115,103,116, 41, 10, 32, 32, 32, 32,109,101,115,
103,116, 46,104,101, 97,100,101,114,115, 32, 61, 32, 97,100,106,117,115,116, 95,
104,101, 97,100,101,114,115, 40,109,101,115,103,116, 41, 10, 32, 32, 32, 32, 45,
45, 32, 99,114,101, 97,116,101, 32, 97,110,100, 32,114,101,116,117,114,110, 32,
109,101,115,115, 97,103,101, 32,115,111,117,114, 99,101, 10, 32, 32, 32, 32,108,
111, 99, 97,108, 32, 99,111, 32, 61, 32, 99,111,114,111,117,116,105,110,101, 46,
99,114,101, 97,116,101, 40,102,117,110, 99,116,105,111,110, 40, 41, 32,115,101,
110,100, 95,109,101,115,115, 97,103,101, 40,109,101,115,103,116, 41, 32,101,110,
100, 41, 10, 32, 32, 32, 32,114,101,116,117,114,110, 32,102,117,110, 99,116,105,
111,110, 40, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32,108,111, 99, 97,108, 32,114,
101,116, 44, 32, 97, 44, 32, 98, 32, 61, 32, 99,111,114,111,117,116,105,110,101,
46,114,101,115,117,109,101, 40, 99,111, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32,
105,102, 32,114,101,116, 32,116,104,101,110, 32,114,101,116,117,114,110, 32, 97,
44, 32, 98, 10, 32, 32, 32, 32, 32, 32, 32, 32,101,108,115,101, 32,114,101,116,
117,114,110, 32,110,105,108, 44, 32, 97, 32,101,110,100, 10, 32, 32, 32, 32,101,
110,100, 10,101,110,100, 10, 10, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45,
45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45,
45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45,
45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45,
45, 45, 45, 10, 45, 45, 32, 72,105,103,104, 32,108,101,118,101,108, 32, 83, 77,
84, 80, 32, 65, 80, 73, 10, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45,
45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45,
45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45,
45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45,
45, 45, 45, 45, 10,115,101,110,100, 32, 61, 32,115,111, 99,107,101,116, 46,112,
114,111,116,101, 99,116, 40,102,117,110, 99,116,105,111,110, 40,109, 97,105,108,
116, 41, 10, 32, 32, 32, 32,108,111, 99, 97,108, 32,115, 32, 61, 32,111,112,101,
110, 40,109, 97,105,108,116, 46,115,101,114,118,101,114, 44, 32,109, 97,105,108,
116, 46,112,111,114,116, 44, 32,109, 97,105,108,116, 46, 99,114,101, 97,116,101,
41, 10, 32, 32, 32, 32,108,111, 99, 97,108, 32,101,120,116, 32, 61, 32,115, 58,
103,114,101,101,116, 40,109, 97,105,108,116, 46,100,111,109, 97,105,110, 41, 10,
32, 32, 32, 32,115, 58, 97,117,116,104, 40,109, 97,105,108,116, 46,117,115,101,
114, 44, 32,109, 97,105,108,116, 46,112, 97,115,115,119,111,114,100, 44, 32,101,
120,116, 41, 10, 32, 32, 32, 32,115, 58,115,101,110,100, 40,109, 97,105,108,116,
41, 10, 32, 32, 32, 32,115, 58,113,117,105,116, 40, 41, 10, 32, 32, 32, 32,114,
101,116,117,114,110, 32,115, 58, 99,108,111,115,101, 40, 41, 10,101,110,100, 41,
10,
};
if (luaL_loadbuffer(L,(const char*)B1,sizeof(B1),"smtp.lua")==0) lua_call(L, 0, 0);
}
@@ -0,0 +1,76 @@
#ifndef SOCKET_H
#define SOCKET_H
/*=========================================================================*\
* Socket compatibilization module
* LuaSocket toolkit
*
* BSD Sockets and WinSock are similar, but there are a few irritating
* differences. Also, not all *nix platforms behave the same. This module
* (and the associated usocket.h and wsocket.h) factor these differences and
* creates a interface compatible with the io.h module.
*
* RCS ID: $Id: socket.h,v 1.20 2005/11/20 07:20:23 diego Exp $
\*=========================================================================*/
#include "io.h"
/*=========================================================================*\
* Platform specific compatibilization
\*=========================================================================*/
#ifdef _WIN32
#include "wsocket.h"
#else
#include "usocket.h"
#endif
/*=========================================================================*\
* The connect and accept functions accept a timeout and their
* implementations are somewhat complicated. We chose to move
* the timeout control into this module for these functions in
* order to simplify the modules that use them.
\*=========================================================================*/
#include "timeout.h"
/* we are lazy... */
typedef struct sockaddr SA;
/*=========================================================================*\
* Functions bellow implement a comfortable platform independent
* interface to sockets
\*=========================================================================*/
int socket_open(void);
int socket_close(void);
void socket_destroy(p_socket ps);
void socket_shutdown(p_socket ps, int how);
int socket_sendto(p_socket ps, const char *data, size_t count,
size_t *sent, SA *addr, socklen_t addr_len, p_timeout tm);
int socket_recvfrom(p_socket ps, char *data, size_t count,
size_t *got, SA *addr, socklen_t *addr_len, p_timeout tm);
void socket_setnonblocking(p_socket ps);
void socket_setblocking(p_socket ps);
int socket_waitfd(p_socket ps, int sw, p_timeout tm);
int socket_select(t_socket n, fd_set *rfds, fd_set *wfds, fd_set *efds,
p_timeout tm);
int socket_connect(p_socket ps, SA *addr, socklen_t addr_len, p_timeout tm);
int socket_create(p_socket ps, int domain, int type, int protocol);
int socket_bind(p_socket ps, SA *addr, socklen_t addr_len);
int socket_listen(p_socket ps, int backlog);
int socket_accept(p_socket ps, p_socket pa, SA *addr,
socklen_t *addr_len, p_timeout tm);
const char *socket_hoststrerror(int err);
const char *socket_strerror(int err);
/* these are perfect to use with the io abstraction module
and the buffered input module */
int socket_send(p_socket ps, const char *data, size_t count,
size_t *sent, p_timeout tm);
int socket_recv(p_socket ps, char *data, size_t count, size_t *got, p_timeout tm);
const char *socket_ioerror(p_socket ps, int err);
int socket_gethostbyaddr(const char *addr, socklen_t len, struct hostent **hp);
int socket_gethostbyname(const char *addr, struct hostent **hp);
#endif /* SOCKET_H */
@@ -0,0 +1,133 @@
-----------------------------------------------------------------------------
-- LuaSocket helper module
-- Author: Diego Nehab
-- RCS ID: $Id: socket.lua,v 1.22 2005/11/22 08:33:29 diego Exp $
-----------------------------------------------------------------------------
-----------------------------------------------------------------------------
-- Declare module and import dependencies
-----------------------------------------------------------------------------
local base = _G
local string = require("string")
local math = require("math")
local socket = require("socket.core")
module("socket")
-----------------------------------------------------------------------------
-- Exported auxiliar functions
-----------------------------------------------------------------------------
function connect(address, port, laddress, lport)
local sock, err = socket.tcp()
if not sock then return nil, err end
if laddress then
local res, err = sock:bind(laddress, lport, -1)
if not res then return nil, err end
end
local res, err = sock:connect(address, port)
if not res then return nil, err end
return sock
end
function bind(host, port, backlog)
local sock, err = socket.tcp()
if not sock then return nil, err end
sock:setoption("reuseaddr", true)
local res, err = sock:bind(host, port)
if not res then return nil, err end
res, err = sock:listen(backlog)
if not res then return nil, err end
return sock
end
try = newtry()
function choose(table)
return function(name, opt1, opt2)
if base.type(name) ~= "string" then
name, opt1, opt2 = "default", name, opt1
end
local f = table[name or "nil"]
if not f then base.error("unknown key (".. base.tostring(name) ..")", 3)
else return f(opt1, opt2) end
end
end
-----------------------------------------------------------------------------
-- Socket sources and sinks, conforming to LTN12
-----------------------------------------------------------------------------
-- create namespaces inside LuaSocket namespace
sourcet = {}
sinkt = {}
BLOCKSIZE = 2048
sinkt["close-when-done"] = function(sock)
return base.setmetatable({
getfd = function() return sock:getfd() end,
dirty = function() return sock:dirty() end
}, {
__call = function(self, chunk, err)
if not chunk then
sock:close()
return 1
else return sock:send(chunk) end
end
})
end
sinkt["keep-open"] = function(sock)
return base.setmetatable({
getfd = function() return sock:getfd() end,
dirty = function() return sock:dirty() end
}, {
__call = function(self, chunk, err)
if chunk then return sock:send(chunk)
else return 1 end
end
})
end
sinkt["default"] = sinkt["keep-open"]
sink = choose(sinkt)
sourcet["by-length"] = function(sock, length)
return base.setmetatable({
getfd = function() return sock:getfd() end,
dirty = function() return sock:dirty() end
}, {
__call = function()
if length <= 0 then return nil end
local size = math.min(socket.BLOCKSIZE, length)
local chunk, err = sock:receive(size)
if err then return nil, err end
length = length - string.len(chunk)
return chunk
end
})
end
sourcet["until-closed"] = function(sock)
local done
return base.setmetatable({
getfd = function() return sock:getfd() end,
dirty = function() return sock:dirty() end
}, {
__call = function()
if done then return nil end
local chunk, err, partial = sock:receive(socket.BLOCKSIZE)
if not err then return chunk
elseif err == "closed" then
sock:close()
done = 1
return partial
else return nil, err end
end
})
end
sourcet["default"] = sourcet["until-closed"]
source = choose(sourcet)
@@ -0,0 +1,215 @@
/* code automatically generated by bin2c -- DO NOT EDIT */
{
/* #include'ing this file in a C program is equivalent to calling
if (luaL_loadfile(L,"socket.lua")==0) lua_call(L, 0, 0);
*/
/* socket.lua */
static const unsigned char B1[]={
45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45,
45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45,
45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45,
45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 10, 45, 45,
32, 76,117, 97, 83,111, 99,107,101,116, 32,104,101,108,112,101,114, 32,109,111,
100,117,108,101, 10, 45, 45, 32, 65,117,116,104,111,114, 58, 32, 68,105,101,103,
111, 32, 78,101,104, 97, 98, 10, 45, 45, 32, 82, 67, 83, 32, 73, 68, 58, 32, 36,
73,100, 58, 32,115,111, 99,107,101,116, 46,108,117, 97, 44,118, 32, 49, 46, 50,
50, 32, 50, 48, 48, 53, 47, 49, 49, 47, 50, 50, 32, 48, 56, 58, 51, 51, 58, 50,
57, 32,100,105,101,103,111, 32, 69,120,112, 32, 36, 10, 45, 45, 45, 45, 45, 45,
45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45,
45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45,
45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45,
45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 10, 10, 45, 45, 45, 45, 45, 45, 45,
45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45,
45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45,
45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45,
45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 10, 45, 45, 32, 68,101, 99,108, 97,114,
101, 32,109,111,100,117,108,101, 32, 97,110,100, 32,105,109,112,111,114,116, 32,
100,101,112,101,110,100,101,110, 99,105,101,115, 10, 45, 45, 45, 45, 45, 45, 45,
45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45,
45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45,
45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45,
45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 10,108,111, 99, 97,108, 32, 98, 97,115,
101, 32, 61, 32, 95, 71, 10,108,111, 99, 97,108, 32,115,116,114,105,110,103, 32,
61, 32,114,101,113,117,105,114,101, 40, 34,115,116,114,105,110,103, 34, 41, 10,
108,111, 99, 97,108, 32,109, 97,116,104, 32, 61, 32,114,101,113,117,105,114,101,
40, 34,109, 97,116,104, 34, 41, 10,108,111, 99, 97,108, 32,115,111, 99,107,101,
116, 32, 61, 32,114,101,113,117,105,114,101, 40, 34,115,111, 99,107,101,116, 46,
99,111,114,101, 34, 41, 10,109,111,100,117,108,101, 40, 34,115,111, 99,107,101,
116, 34, 41, 10, 10, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45,
45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45,
45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45,
45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45,
45, 45, 10, 45, 45, 32, 69,120,112,111,114,116,101,100, 32, 97,117,120,105,108,
105, 97,114, 32,102,117,110, 99,116,105,111,110,115, 10, 45, 45, 45, 45, 45, 45,
45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45,
45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45,
45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45,
45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 10,102,117,110, 99,116,105,111,110,
32, 99,111,110,110,101, 99,116, 40, 97,100,100,114,101,115,115, 44, 32,112,111,
114,116, 44, 32,108, 97,100,100,114,101,115,115, 44, 32,108,112,111,114,116, 41,
10, 32, 32, 32, 32,108,111, 99, 97,108, 32,115,111, 99,107, 44, 32,101,114,114,
32, 61, 32,115,111, 99,107,101,116, 46,116, 99,112, 40, 41, 10, 32, 32, 32, 32,
105,102, 32,110,111,116, 32,115,111, 99,107, 32,116,104,101,110, 32,114,101,116,
117,114,110, 32,110,105,108, 44, 32,101,114,114, 32,101,110,100, 10, 32, 32, 32,
32,105,102, 32,108, 97,100,100,114,101,115,115, 32,116,104,101,110, 10, 32, 32,
32, 32, 32, 32, 32, 32,108,111, 99, 97,108, 32,114,101,115, 44, 32,101,114,114,
32, 61, 32,115,111, 99,107, 58, 98,105,110,100, 40,108, 97,100,100,114,101,115,
115, 44, 32,108,112,111,114,116, 44, 32, 45, 49, 41, 10, 32, 32, 32, 32, 32, 32,
32, 32,105,102, 32,110,111,116, 32,114,101,115, 32,116,104,101,110, 32,114,101,
116,117,114,110, 32,110,105,108, 44, 32,101,114,114, 32,101,110,100, 10, 32, 32,
32, 32,101,110,100, 10, 32, 32, 32, 32,108,111, 99, 97,108, 32,114,101,115, 44,
32,101,114,114, 32, 61, 32,115,111, 99,107, 58, 99,111,110,110,101, 99,116, 40,
97,100,100,114,101,115,115, 44, 32,112,111,114,116, 41, 10, 32, 32, 32, 32,105,
102, 32,110,111,116, 32,114,101,115, 32,116,104,101,110, 32,114,101,116,117,114,
110, 32,110,105,108, 44, 32,101,114,114, 32,101,110,100, 10, 32, 32, 32, 32,114,
101,116,117,114,110, 32,115,111, 99,107, 10,101,110,100, 10, 10,102,117,110, 99,
116,105,111,110, 32, 98,105,110,100, 40,104,111,115,116, 44, 32,112,111,114,116,
44, 32, 98, 97, 99,107,108,111,103, 41, 10, 32, 32, 32, 32,108,111, 99, 97,108,
32,115,111, 99,107, 44, 32,101,114,114, 32, 61, 32,115,111, 99,107,101,116, 46,
116, 99,112, 40, 41, 10, 32, 32, 32, 32,105,102, 32,110,111,116, 32,115,111, 99,
107, 32,116,104,101,110, 32,114,101,116,117,114,110, 32,110,105,108, 44, 32,101,
114,114, 32,101,110,100, 10, 32, 32, 32, 32,115,111, 99,107, 58,115,101,116,111,
112,116,105,111,110, 40, 34,114,101,117,115,101, 97,100,100,114, 34, 44, 32,116,
114,117,101, 41, 10, 32, 32, 32, 32,108,111, 99, 97,108, 32,114,101,115, 44, 32,
101,114,114, 32, 61, 32,115,111, 99,107, 58, 98,105,110,100, 40,104,111,115,116,
44, 32,112,111,114,116, 41, 10, 32, 32, 32, 32,105,102, 32,110,111,116, 32,114,
101,115, 32,116,104,101,110, 32,114,101,116,117,114,110, 32,110,105,108, 44, 32,
101,114,114, 32,101,110,100, 10, 32, 32, 32, 32,114,101,115, 44, 32,101,114,114,
32, 61, 32,115,111, 99,107, 58,108,105,115,116,101,110, 40, 98, 97, 99,107,108,
111,103, 41, 10, 32, 32, 32, 32,105,102, 32,110,111,116, 32,114,101,115, 32,116,
104,101,110, 32,114,101,116,117,114,110, 32,110,105,108, 44, 32,101,114,114, 32,
101,110,100, 10, 32, 32, 32, 32,114,101,116,117,114,110, 32,115,111, 99,107, 10,
101,110,100, 10, 10,116,114,121, 32, 61, 32,110,101,119,116,114,121, 40, 41, 10,
10,102,117,110, 99,116,105,111,110, 32, 99,104,111,111,115,101, 40,116, 97, 98,
108,101, 41, 10, 32, 32, 32, 32,114,101,116,117,114,110, 32,102,117,110, 99,116,
105,111,110, 40,110, 97,109,101, 44, 32,111,112,116, 49, 44, 32,111,112,116, 50,
41, 10, 32, 32, 32, 32, 32, 32, 32, 32,105,102, 32, 98, 97,115,101, 46,116,121,
112,101, 40,110, 97,109,101, 41, 32,126, 61, 32, 34,115,116,114,105,110,103, 34,
32,116,104,101,110, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,110, 97,
109,101, 44, 32,111,112,116, 49, 44, 32,111,112,116, 50, 32, 61, 32, 34,100,101,
102, 97,117,108,116, 34, 44, 32,110, 97,109,101, 44, 32,111,112,116, 49, 10, 32,
32, 32, 32, 32, 32, 32, 32,101,110,100, 10, 32, 32, 32, 32, 32, 32, 32, 32,108,
111, 99, 97,108, 32,102, 32, 61, 32,116, 97, 98,108,101, 91,110, 97,109,101, 32,
111,114, 32, 34,110,105,108, 34, 93, 10, 32, 32, 32, 32, 32, 32, 32, 32,105,102,
32,110,111,116, 32,102, 32,116,104,101,110, 32, 98, 97,115,101, 46,101,114,114,
111,114, 40, 34,117,110,107,110,111,119,110, 32,107,101,121, 32, 40, 34, 46, 46,
32, 98, 97,115,101, 46,116,111,115,116,114,105,110,103, 40,110, 97,109,101, 41,
32, 46, 46, 34, 41, 34, 44, 32, 51, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32,101,
108,115,101, 32,114,101,116,117,114,110, 32,102, 40,111,112,116, 49, 44, 32,111,
112,116, 50, 41, 32,101,110,100, 10, 32, 32, 32, 32,101,110,100, 10,101,110,100,
10, 10, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45,
45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45,
45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45,
45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 10,
45, 45, 32, 83,111, 99,107,101,116, 32,115,111,117,114, 99,101,115, 32, 97,110,
100, 32,115,105,110,107,115, 44, 32, 99,111,110,102,111,114,109,105,110,103, 32,
116,111, 32, 76, 84, 78, 49, 50, 10, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45,
45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45,
45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45,
45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45,
45, 45, 45, 45, 45, 45, 10, 45, 45, 32, 99,114,101, 97,116,101, 32,110, 97,109,
101,115,112, 97, 99,101,115, 32,105,110,115,105,100,101, 32, 76,117, 97, 83,111,
99,107,101,116, 32,110, 97,109,101,115,112, 97, 99,101, 10,115,111,117,114, 99,
101,116, 32, 61, 32,123,125, 10,115,105,110,107,116, 32, 61, 32,123,125, 10, 10,
66, 76, 79, 67, 75, 83, 73, 90, 69, 32, 61, 32, 50, 48, 52, 56, 10, 10,115,105,
110,107,116, 91, 34, 99,108,111,115,101, 45,119,104,101,110, 45,100,111,110,101,
34, 93, 32, 61, 32,102,117,110, 99,116,105,111,110, 40,115,111, 99,107, 41, 10,
32, 32, 32, 32,114,101,116,117,114,110, 32, 98, 97,115,101, 46,115,101,116,109,
101,116, 97,116, 97, 98,108,101, 40,123, 10, 32, 32, 32, 32, 32, 32, 32, 32,103,
101,116,102,100, 32, 61, 32,102,117,110, 99,116,105,111,110, 40, 41, 32,114,101,
116,117,114,110, 32,115,111, 99,107, 58,103,101,116,102,100, 40, 41, 32,101,110,
100, 44, 10, 32, 32, 32, 32, 32, 32, 32, 32,100,105,114,116,121, 32, 61, 32,102,
117,110, 99,116,105,111,110, 40, 41, 32,114,101,116,117,114,110, 32,115,111, 99,
107, 58,100,105,114,116,121, 40, 41, 32,101,110,100, 10, 32, 32, 32, 32,125, 44,
32,123, 10, 32, 32, 32, 32, 32, 32, 32, 32, 95, 95, 99, 97,108,108, 32, 61, 32,
102,117,110, 99,116,105,111,110, 40,115,101,108,102, 44, 32, 99,104,117,110,107,
44, 32,101,114,114, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,105,
102, 32,110,111,116, 32, 99,104,117,110,107, 32,116,104,101,110, 10, 32, 32, 32,
32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,115,111, 99,107, 58, 99,108,
111,115,101, 40, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
32, 32,114,101,116,117,114,110, 32, 49, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32,
32, 32, 32,101,108,115,101, 32,114,101,116,117,114,110, 32,115,111, 99,107, 58,
115,101,110,100, 40, 99,104,117,110,107, 41, 32,101,110,100, 10, 32, 32, 32, 32,
32, 32, 32, 32,101,110,100, 10, 32, 32, 32, 32,125, 41, 10,101,110,100, 10, 10,
115,105,110,107,116, 91, 34,107,101,101,112, 45,111,112,101,110, 34, 93, 32, 61,
32,102,117,110, 99,116,105,111,110, 40,115,111, 99,107, 41, 10, 32, 32, 32, 32,
114,101,116,117,114,110, 32, 98, 97,115,101, 46,115,101,116,109,101,116, 97,116,
97, 98,108,101, 40,123, 10, 32, 32, 32, 32, 32, 32, 32, 32,103,101,116,102,100,
32, 61, 32,102,117,110, 99,116,105,111,110, 40, 41, 32,114,101,116,117,114,110,
32,115,111, 99,107, 58,103,101,116,102,100, 40, 41, 32,101,110,100, 44, 10, 32,
32, 32, 32, 32, 32, 32, 32,100,105,114,116,121, 32, 61, 32,102,117,110, 99,116,
105,111,110, 40, 41, 32,114,101,116,117,114,110, 32,115,111, 99,107, 58,100,105,
114,116,121, 40, 41, 32,101,110,100, 10, 32, 32, 32, 32,125, 44, 32,123, 10, 32,
32, 32, 32, 32, 32, 32, 32, 95, 95, 99, 97,108,108, 32, 61, 32,102,117,110, 99,
116,105,111,110, 40,115,101,108,102, 44, 32, 99,104,117,110,107, 44, 32,101,114,
114, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,105,102, 32, 99,104,
117,110,107, 32,116,104,101,110, 32,114,101,116,117,114,110, 32,115,111, 99,107,
58,115,101,110,100, 40, 99,104,117,110,107, 41, 10, 32, 32, 32, 32, 32, 32, 32,
32, 32, 32, 32, 32,101,108,115,101, 32,114,101,116,117,114,110, 32, 49, 32,101,
110,100, 10, 32, 32, 32, 32, 32, 32, 32, 32,101,110,100, 10, 32, 32, 32, 32,125,
41, 10,101,110,100, 10, 10,115,105,110,107,116, 91, 34,100,101,102, 97,117,108,
116, 34, 93, 32, 61, 32,115,105,110,107,116, 91, 34,107,101,101,112, 45,111,112,
101,110, 34, 93, 10, 10,115,105,110,107, 32, 61, 32, 99,104,111,111,115,101, 40,
115,105,110,107,116, 41, 10, 10,115,111,117,114, 99,101,116, 91, 34, 98,121, 45,
108,101,110,103,116,104, 34, 93, 32, 61, 32,102,117,110, 99,116,105,111,110, 40,
115,111, 99,107, 44, 32,108,101,110,103,116,104, 41, 10, 32, 32, 32, 32,114,101,
116,117,114,110, 32, 98, 97,115,101, 46,115,101,116,109,101,116, 97,116, 97, 98,
108,101, 40,123, 10, 32, 32, 32, 32, 32, 32, 32, 32,103,101,116,102,100, 32, 61,
32,102,117,110, 99,116,105,111,110, 40, 41, 32,114,101,116,117,114,110, 32,115,
111, 99,107, 58,103,101,116,102,100, 40, 41, 32,101,110,100, 44, 10, 32, 32, 32,
32, 32, 32, 32, 32,100,105,114,116,121, 32, 61, 32,102,117,110, 99,116,105,111,
110, 40, 41, 32,114,101,116,117,114,110, 32,115,111, 99,107, 58,100,105,114,116,
121, 40, 41, 32,101,110,100, 10, 32, 32, 32, 32,125, 44, 32,123, 10, 32, 32, 32,
32, 32, 32, 32, 32, 95, 95, 99, 97,108,108, 32, 61, 32,102,117,110, 99,116,105,
111,110, 40, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,105,102, 32,
108,101,110,103,116,104, 32, 60, 61, 32, 48, 32,116,104,101,110, 32,114,101,116,
117,114,110, 32,110,105,108, 32,101,110,100, 10, 32, 32, 32, 32, 32, 32, 32, 32,
32, 32, 32, 32,108,111, 99, 97,108, 32,115,105,122,101, 32, 61, 32,109, 97,116,
104, 46,109,105,110, 40,115,111, 99,107,101,116, 46, 66, 76, 79, 67, 75, 83, 73,
90, 69, 44, 32,108,101,110,103,116,104, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32,
32, 32, 32, 32,108,111, 99, 97,108, 32, 99,104,117,110,107, 44, 32,101,114,114,
32, 61, 32,115,111, 99,107, 58,114,101, 99,101,105,118,101, 40,115,105,122,101,
41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,105,102, 32,101,114,114,
32,116,104,101,110, 32,114,101,116,117,114,110, 32,110,105,108, 44, 32,101,114,
114, 32,101,110,100, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,108,101,
110,103,116,104, 32, 61, 32,108,101,110,103,116,104, 32, 45, 32,115,116,114,105,
110,103, 46,108,101,110, 40, 99,104,117,110,107, 41, 10, 32, 32, 32, 32, 32, 32,
32, 32, 32, 32, 32, 32,114,101,116,117,114,110, 32, 99,104,117,110,107, 10, 32,
32, 32, 32, 32, 32, 32, 32,101,110,100, 10, 32, 32, 32, 32,125, 41, 10,101,110,
100, 10, 10,115,111,117,114, 99,101,116, 91, 34,117,110,116,105,108, 45, 99,108,
111,115,101,100, 34, 93, 32, 61, 32,102,117,110, 99,116,105,111,110, 40,115,111,
99,107, 41, 10, 32, 32, 32, 32,108,111, 99, 97,108, 32,100,111,110,101, 10, 32,
32, 32, 32,114,101,116,117,114,110, 32, 98, 97,115,101, 46,115,101,116,109,101,
116, 97,116, 97, 98,108,101, 40,123, 10, 32, 32, 32, 32, 32, 32, 32, 32,103,101,
116,102,100, 32, 61, 32,102,117,110, 99,116,105,111,110, 40, 41, 32,114,101,116,
117,114,110, 32,115,111, 99,107, 58,103,101,116,102,100, 40, 41, 32,101,110,100,
44, 10, 32, 32, 32, 32, 32, 32, 32, 32,100,105,114,116,121, 32, 61, 32,102,117,
110, 99,116,105,111,110, 40, 41, 32,114,101,116,117,114,110, 32,115,111, 99,107,
58,100,105,114,116,121, 40, 41, 32,101,110,100, 10, 32, 32, 32, 32,125, 44, 32,
123, 10, 32, 32, 32, 32, 32, 32, 32, 32, 95, 95, 99, 97,108,108, 32, 61, 32,102,
117,110, 99,116,105,111,110, 40, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
32, 32,105,102, 32,100,111,110,101, 32,116,104,101,110, 32,114,101,116,117,114,
110, 32,110,105,108, 32,101,110,100, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
32, 32,108,111, 99, 97,108, 32, 99,104,117,110,107, 44, 32,101,114,114, 44, 32,
112, 97,114,116,105, 97,108, 32, 61, 32,115,111, 99,107, 58,114,101, 99,101,105,
118,101, 40,115,111, 99,107,101,116, 46, 66, 76, 79, 67, 75, 83, 73, 90, 69, 41,
10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,105,102, 32,110,111,116, 32,
101,114,114, 32,116,104,101,110, 32,114,101,116,117,114,110, 32, 99,104,117,110,
107, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,101,108,115,101,105,102,
32,101,114,114, 32, 61, 61, 32, 34, 99,108,111,115,101,100, 34, 32,116,104,101,
110, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,115,111,
99,107, 58, 99,108,111,115,101, 40, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32,
32, 32, 32, 32, 32, 32, 32,100,111,110,101, 32, 61, 32, 49, 10, 32, 32, 32, 32,
32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,114,101,116,117,114,110, 32,112,
97,114,116,105, 97,108, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,101,
108,115,101, 32,114,101,116,117,114,110, 32,110,105,108, 44, 32,101,114,114, 32,
101,110,100, 10, 32, 32, 32, 32, 32, 32, 32, 32,101,110,100, 10, 32, 32, 32, 32,
125, 41, 10,101,110,100, 10, 10, 10,115,111,117,114, 99,101,116, 91, 34,100,101,
102, 97,117,108,116, 34, 93, 32, 61, 32,115,111,117,114, 99,101,116, 91, 34,117,
110,116,105,108, 45, 99,108,111,115,101,100, 34, 93, 10, 10,115,111,117,114, 99,
101, 32, 61, 32, 99,104,111,111,115,101, 40,115,111,117,114, 99,101,116, 41, 10,
10,
};
if (luaL_loadbuffer(L,(const char*)B1,sizeof(B1),"socket.lua")==0) lua_call(L, 0, 0);
}
+339
View File
@@ -0,0 +1,339 @@
/*=========================================================================*\
* TCP object
* LuaSocket toolkit
*
* RCS ID: $Id: tcp.c,v 1.41 2005/10/07 04:40:59 diego Exp $
\*=========================================================================*/
#include <string.h>
#include "lua.h"
#include "lauxlib.h"
#include "auxiliar.h"
#include "socket.h"
#include "inet.h"
#include "options.h"
#include "tcp.h"
/*=========================================================================*\
* Internal function prototypes
\*=========================================================================*/
static int global_create(lua_State *L);
static int meth_connect(lua_State *L);
static int meth_listen(lua_State *L);
static int meth_bind(lua_State *L);
static int meth_send(lua_State *L);
static int meth_getstats(lua_State *L);
static int meth_setstats(lua_State *L);
static int meth_getsockname(lua_State *L);
static int meth_getpeername(lua_State *L);
static int meth_shutdown(lua_State *L);
static int meth_receive(lua_State *L);
static int meth_accept(lua_State *L);
static int meth_close(lua_State *L);
static int meth_setoption(lua_State *L);
static int meth_settimeout(lua_State *L);
static int meth_getfd(lua_State *L);
static int meth_setfd(lua_State *L);
static int meth_dirty(lua_State *L);
/* tcp object methods */
static luaL_reg tcp[] = {
{"__gc", meth_close},
{"__tostring", auxiliar_tostring},
{"accept", meth_accept},
{"bind", meth_bind},
{"close", meth_close},
{"connect", meth_connect},
{"dirty", meth_dirty},
{"getfd", meth_getfd},
{"getpeername", meth_getpeername},
{"getsockname", meth_getsockname},
{"getstats", meth_getstats},
{"setstats", meth_setstats},
{"listen", meth_listen},
{"receive", meth_receive},
{"send", meth_send},
{"setfd", meth_setfd},
{"setoption", meth_setoption},
{"setpeername", meth_connect},
{"setsockname", meth_bind},
{"settimeout", meth_settimeout},
{"shutdown", meth_shutdown},
{NULL, NULL}
};
/* socket option handlers */
static t_opt opt[] = {
{"keepalive", opt_keepalive},
{"reuseaddr", opt_reuseaddr},
{"tcp-nodelay", opt_tcp_nodelay},
{"linger", opt_linger},
{NULL, NULL}
};
/* functions in library namespace */
static luaL_reg func[] = {
{"tcp", global_create},
{NULL, NULL}
};
/*-------------------------------------------------------------------------*\
* Initializes module
\*-------------------------------------------------------------------------*/
int tcp_open(lua_State *L)
{
/* create classes */
auxiliar_newclass(L, "tcp{master}", tcp);
auxiliar_newclass(L, "tcp{client}", tcp);
auxiliar_newclass(L, "tcp{server}", tcp);
/* create class groups */
auxiliar_add2group(L, "tcp{master}", "tcp{any}");
auxiliar_add2group(L, "tcp{client}", "tcp{any}");
auxiliar_add2group(L, "tcp{server}", "tcp{any}");
/* define library functions */
luaL_openlib(L, NULL, func, 0);
return 0;
}
/*=========================================================================*\
* Lua methods
\*=========================================================================*/
/*-------------------------------------------------------------------------*\
* Just call buffered IO methods
\*-------------------------------------------------------------------------*/
static int meth_send(lua_State *L) {
p_tcp tcp = (p_tcp) auxiliar_checkclass(L, "tcp{client}", 1);
return buffer_meth_send(L, &tcp->buf);
}
static int meth_receive(lua_State *L) {
p_tcp tcp = (p_tcp) auxiliar_checkclass(L, "tcp{client}", 1);
return buffer_meth_receive(L, &tcp->buf);
}
static int meth_getstats(lua_State *L) {
p_tcp tcp = (p_tcp) auxiliar_checkclass(L, "tcp{client}", 1);
return buffer_meth_getstats(L, &tcp->buf);
}
static int meth_setstats(lua_State *L) {
p_tcp tcp = (p_tcp) auxiliar_checkclass(L, "tcp{client}", 1);
return buffer_meth_setstats(L, &tcp->buf);
}
/*-------------------------------------------------------------------------*\
* Just call option handler
\*-------------------------------------------------------------------------*/
static int meth_setoption(lua_State *L)
{
p_tcp tcp = (p_tcp) auxiliar_checkgroup(L, "tcp{any}", 1);
return opt_meth_setoption(L, opt, &tcp->sock);
}
/*-------------------------------------------------------------------------*\
* Select support methods
\*-------------------------------------------------------------------------*/
static int meth_getfd(lua_State *L)
{
p_tcp tcp = (p_tcp) auxiliar_checkgroup(L, "tcp{any}", 1);
lua_pushnumber(L, (int) tcp->sock);
return 1;
}
/* this is very dangerous, but can be handy for those that are brave enough */
static int meth_setfd(lua_State *L)
{
p_tcp tcp = (p_tcp) auxiliar_checkgroup(L, "tcp{any}", 1);
tcp->sock = (t_socket) luaL_checknumber(L, 2);
return 0;
}
static int meth_dirty(lua_State *L)
{
p_tcp tcp = (p_tcp) auxiliar_checkgroup(L, "tcp{any}", 1);
lua_pushboolean(L, !buffer_isempty(&tcp->buf));
return 1;
}
/*-------------------------------------------------------------------------*\
* Waits for and returns a client object attempting connection to the
* server object
\*-------------------------------------------------------------------------*/
static int meth_accept(lua_State *L)
{
p_tcp server = (p_tcp) auxiliar_checkclass(L, "tcp{server}", 1);
p_timeout tm = timeout_markstart(&server->tm);
t_socket sock;
int err = socket_accept(&server->sock, &sock, NULL, NULL, tm);
/* if successful, push client socket */
if (err == IO_DONE) {
p_tcp clnt = (p_tcp) lua_newuserdata(L, sizeof(t_tcp));
auxiliar_setclass(L, "tcp{client}", -1);
/* initialize structure fields */
socket_setnonblocking(&sock);
clnt->sock = sock;
io_init(&clnt->io, (p_send) socket_send, (p_recv) socket_recv,
(p_error) socket_ioerror, &clnt->sock);
timeout_init(&clnt->tm, -1, -1);
buffer_init(&clnt->buf, &clnt->io, &clnt->tm);
return 1;
} else {
lua_pushnil(L);
lua_pushstring(L, socket_strerror(err));
return 2;
}
}
/*-------------------------------------------------------------------------*\
* Binds an object to an address
\*-------------------------------------------------------------------------*/
static int meth_bind(lua_State *L)
{
p_tcp tcp = (p_tcp) auxiliar_checkclass(L, "tcp{master}", 1);
const char *address = luaL_checkstring(L, 2);
unsigned short port = (unsigned short) luaL_checknumber(L, 3);
const char *err = inet_trybind(&tcp->sock, address, port);
if (err) {
lua_pushnil(L);
lua_pushstring(L, err);
return 2;
}
lua_pushnumber(L, 1);
return 1;
}
/*-------------------------------------------------------------------------*\
* Turns a master tcp object into a client object.
\*-------------------------------------------------------------------------*/
static int meth_connect(lua_State *L)
{
p_tcp tcp = (p_tcp) auxiliar_checkgroup(L, "tcp{any}", 1);
const char *address = luaL_checkstring(L, 2);
unsigned short port = (unsigned short) luaL_checknumber(L, 3);
p_timeout tm = timeout_markstart(&tcp->tm);
const char *err = inet_tryconnect(&tcp->sock, address, port, tm);
/* have to set the class even if it failed due to non-blocking connects */
auxiliar_setclass(L, "tcp{client}", 1);
if (err) {
lua_pushnil(L);
lua_pushstring(L, err);
return 2;
}
/* turn master object into a client object */
lua_pushnumber(L, 1);
return 1;
}
/*-------------------------------------------------------------------------*\
* Closes socket used by object
\*-------------------------------------------------------------------------*/
static int meth_close(lua_State *L)
{
p_tcp tcp = (p_tcp) auxiliar_checkgroup(L, "tcp{any}", 1);
socket_destroy(&tcp->sock);
lua_pushnumber(L, 1);
return 1;
}
/*-------------------------------------------------------------------------*\
* Puts the sockt in listen mode
\*-------------------------------------------------------------------------*/
static int meth_listen(lua_State *L)
{
p_tcp tcp = (p_tcp) auxiliar_checkclass(L, "tcp{master}", 1);
int backlog = (int) luaL_optnumber(L, 2, 32);
int err = socket_listen(&tcp->sock, backlog);
if (err != IO_DONE) {
lua_pushnil(L);
lua_pushstring(L, socket_strerror(err));
return 2;
}
/* turn master object into a server object */
auxiliar_setclass(L, "tcp{server}", 1);
lua_pushnumber(L, 1);
return 1;
}
/*-------------------------------------------------------------------------*\
* Shuts the connection down partially
\*-------------------------------------------------------------------------*/
static int meth_shutdown(lua_State *L)
{
p_tcp tcp = (p_tcp) auxiliar_checkclass(L, "tcp{client}", 1);
const char *how = luaL_optstring(L, 2, "both");
switch (how[0]) {
case 'b':
if (strcmp(how, "both")) goto error;
socket_shutdown(&tcp->sock, 2);
break;
case 's':
if (strcmp(how, "send")) goto error;
socket_shutdown(&tcp->sock, 1);
break;
case 'r':
if (strcmp(how, "receive")) goto error;
socket_shutdown(&tcp->sock, 0);
break;
}
lua_pushnumber(L, 1);
return 1;
error:
luaL_argerror(L, 2, "invalid shutdown method");
return 0;
}
/*-------------------------------------------------------------------------*\
* Just call inet methods
\*-------------------------------------------------------------------------*/
static int meth_getpeername(lua_State *L)
{
p_tcp tcp = (p_tcp) auxiliar_checkgroup(L, "tcp{any}", 1);
return inet_meth_getpeername(L, &tcp->sock);
}
static int meth_getsockname(lua_State *L)
{
p_tcp tcp = (p_tcp) auxiliar_checkgroup(L, "tcp{any}", 1);
return inet_meth_getsockname(L, &tcp->sock);
}
/*-------------------------------------------------------------------------*\
* Just call tm methods
\*-------------------------------------------------------------------------*/
static int meth_settimeout(lua_State *L)
{
p_tcp tcp = (p_tcp) auxiliar_checkgroup(L, "tcp{any}", 1);
return timeout_meth_settimeout(L, &tcp->tm);
}
/*=========================================================================*\
* Library functions
\*=========================================================================*/
/*-------------------------------------------------------------------------*\
* Creates a master tcp object
\*-------------------------------------------------------------------------*/
static int global_create(lua_State *L)
{
t_socket sock;
const char *err = inet_trycreate(&sock, SOCK_STREAM);
/* try to allocate a system socket */
if (!err) {
/* allocate tcp object */
p_tcp tcp = (p_tcp) lua_newuserdata(L, sizeof(t_tcp));
/* set its type as master object */
auxiliar_setclass(L, "tcp{master}", -1);
/* initialize remaining structure fields */
socket_setnonblocking(&sock);
tcp->sock = sock;
io_init(&tcp->io, (p_send) socket_send, (p_recv) socket_recv,
(p_error) socket_ioerror, &tcp->sock);
timeout_init(&tcp->tm, -1, -1);
buffer_init(&tcp->buf, &tcp->io, &tcp->tm);
return 1;
} else {
lua_pushnil(L);
lua_pushstring(L, err);
return 2;
}
}
@@ -0,0 +1,36 @@
#ifndef TCP_H
#define TCP_H
/*=========================================================================*\
* TCP object
* LuaSocket toolkit
*
* The tcp.h module is basicly a glue that puts together modules buffer.h,
* timeout.h socket.h and inet.h to provide the LuaSocket TCP (AF_INET,
* SOCK_STREAM) support.
*
* Three classes are defined: master, client and server. The master class is
* a newly created tcp object, that has not been bound or connected. Server
* objects are tcp objects bound to some local address. Client objects are
* tcp objects either connected to some address or returned by the accept
* method of a server object.
*
* RCS ID: $Id: tcp.h,v 1.7 2005/10/07 04:40:59 diego Exp $
\*=========================================================================*/
#include "lua.h"
#include "buffer.h"
#include "timeout.h"
#include "socket.h"
typedef struct t_tcp_ {
t_socket sock;
t_io io;
t_buffer buf;
t_timeout tm;
} t_tcp;
typedef t_tcp *p_tcp;
int tcp_open(lua_State *L);
#endif /* TCP_H */
@@ -0,0 +1,207 @@
/*=========================================================================*\
* Timeout management functions
* LuaSocket toolkit
*
* RCS ID: $Id: timeout.c,v 1.30 2005/10/07 04:40:59 diego Exp $
\*=========================================================================*/
#include <stdio.h>
#include "lua.h"
#include "lauxlib.h"
#include "auxiliar.h"
#include "timeout.h"
#ifdef _WIN32
#include <windows.h>
#else
#include <time.h>
#include <sys/time.h>
#endif
/* min and max macros */
#ifndef MIN
#define MIN(x, y) ((x) < (y) ? x : y)
#endif
#ifndef MAX
#define MAX(x, y) ((x) > (y) ? x : y)
#endif
/*=========================================================================*\
* Internal function prototypes
\*=========================================================================*/
static int timeout_lua_gettime(lua_State *L);
static int timeout_lua_sleep(lua_State *L);
static luaL_reg func[] = {
{ "gettime", timeout_lua_gettime },
{ "sleep", timeout_lua_sleep },
{ NULL, NULL }
};
/*=========================================================================*\
* Exported functions.
\*=========================================================================*/
/*-------------------------------------------------------------------------*\
* Initialize structure
\*-------------------------------------------------------------------------*/
void timeout_init(p_timeout tm, double block, double total) {
tm->block = block;
tm->total = total;
}
/*-------------------------------------------------------------------------*\
* Determines how much time we have left for the next system call,
* if the previous call was successful
* Input
* tm: timeout control structure
* Returns
* the number of ms left or -1 if there is no time limit
\*-------------------------------------------------------------------------*/
double timeout_get(p_timeout tm) {
if (tm->block < 0.0 && tm->total < 0.0) {
return -1;
} else if (tm->block < 0.0) {
double t = tm->total - timeout_gettime() + tm->start;
return MAX(t, 0.0);
} else if (tm->total < 0.0) {
return tm->block;
} else {
double t = tm->total - timeout_gettime() + tm->start;
return MIN(tm->block, MAX(t, 0.0));
}
}
/*-------------------------------------------------------------------------*\
* Returns time since start of operation
* Input
* tm: timeout control structure
* Returns
* start field of structure
\*-------------------------------------------------------------------------*/
double timeout_getstart(p_timeout tm) {
return tm->start;
}
/*-------------------------------------------------------------------------*\
* Determines how much time we have left for the next system call,
* if the previous call was a failure
* Input
* tm: timeout control structure
* Returns
* the number of ms left or -1 if there is no time limit
\*-------------------------------------------------------------------------*/
double timeout_getretry(p_timeout tm) {
if (tm->block < 0.0 && tm->total < 0.0) {
return -1;
} else if (tm->block < 0.0) {
double t = tm->total - timeout_gettime() + tm->start;
return MAX(t, 0.0);
} else if (tm->total < 0.0) {
double t = tm->block - timeout_gettime() + tm->start;
return MAX(t, 0.0);
} else {
double t = tm->total - timeout_gettime() + tm->start;
return MIN(tm->block, MAX(t, 0.0));
}
}
/*-------------------------------------------------------------------------*\
* Marks the operation start time in structure
* Input
* tm: timeout control structure
\*-------------------------------------------------------------------------*/
p_timeout timeout_markstart(p_timeout tm) {
tm->start = timeout_gettime();
return tm;
}
/*-------------------------------------------------------------------------*\
* Gets time in s, relative to January 1, 1970 (UTC)
* Returns
* time in s.
\*-------------------------------------------------------------------------*/
#ifdef _WIN32
double timeout_gettime(void) {
FILETIME ft;
double t;
GetSystemTimeAsFileTime(&ft);
/* Windows file time (time since January 1, 1601 (UTC)) */
t = ft.dwLowDateTime/1.0e7 + ft.dwHighDateTime*(4294967296.0/1.0e7);
/* convert to Unix Epoch time (time since January 1, 1970 (UTC)) */
return (t - 11644473600.0);
}
#else
double timeout_gettime(void) {
struct timeval v;
gettimeofday(&v, (struct timezone *) NULL);
/* Unix Epoch time (time since January 1, 1970 (UTC)) */
return v.tv_sec + v.tv_usec/1.0e6;
}
#endif
/*-------------------------------------------------------------------------*\
* Initializes module
\*-------------------------------------------------------------------------*/
int timeout_open(lua_State *L) {
luaL_openlib(L, NULL, func, 0);
return 0;
}
/*-------------------------------------------------------------------------*\
* Sets timeout values for IO operations
* Lua Input: base, time [, mode]
* time: time out value in seconds
* mode: "b" for block timeout, "t" for total timeout. (default: b)
\*-------------------------------------------------------------------------*/
int timeout_meth_settimeout(lua_State *L, p_timeout tm) {
double t = luaL_optnumber(L, 2, -1);
const char *mode = luaL_optstring(L, 3, "b");
switch (*mode) {
case 'b':
tm->block = t;
break;
case 'r': case 't':
tm->total = t;
break;
default:
luaL_argcheck(L, 0, 3, "invalid timeout mode");
break;
}
lua_pushnumber(L, 1);
return 1;
}
/*=========================================================================*\
* Test support functions
\*=========================================================================*/
/*-------------------------------------------------------------------------*\
* Returns the time the system has been up, in secconds.
\*-------------------------------------------------------------------------*/
static int timeout_lua_gettime(lua_State *L)
{
lua_pushnumber(L, timeout_gettime());
return 1;
}
/*-------------------------------------------------------------------------*\
* Sleep for n seconds.
\*-------------------------------------------------------------------------*/
int timeout_lua_sleep(lua_State *L)
{
double n = luaL_checknumber(L, 1);
#ifdef _WIN32
Sleep((int)(n*1000));
#else
struct timespec t, r;
t.tv_sec = (int) n;
n -= t.tv_sec;
t.tv_nsec = (int) (n * 1000000000);
if (t.tv_nsec >= 1000000000) t.tv_nsec = 999999999;
while (nanosleep(&t, &r) != 0) {
t.tv_sec = r.tv_sec;
t.tv_nsec = r.tv_nsec;
}
#endif
return 0;
}
@@ -0,0 +1,30 @@
#ifndef TIMEOUT_H
#define TIMEOUT_H
/*=========================================================================*\
* Timeout management functions
* LuaSocket toolkit
*
* RCS ID: $Id: timeout.h,v 1.14 2005/10/07 04:40:59 diego Exp $
\*=========================================================================*/
#include "lua.h"
/* timeout control structure */
typedef struct t_timeout_ {
double block; /* maximum time for blocking calls */
double total; /* total number of miliseconds for operation */
double start; /* time of start of operation */
} t_timeout;
typedef t_timeout *p_timeout;
int timeout_open(lua_State *L);
void timeout_init(p_timeout tm, double block, double total);
double timeout_get(p_timeout tm);
double timeout_getretry(p_timeout tm);
p_timeout timeout_markstart(p_timeout tm);
double timeout_getstart(p_timeout tm);
double timeout_gettime(void);
int timeout_meth_settimeout(lua_State *L, p_timeout tm);
#define timeout_iszero(tm) ((tm)->block == 0.0)
#endif /* TIMEOUT_H */
+123
View File
@@ -0,0 +1,123 @@
-----------------------------------------------------------------------------
-- Unified SMTP/FTP subsystem
-- LuaSocket toolkit.
-- Author: Diego Nehab
-- RCS ID: $Id: tp.lua,v 1.22 2006/03/14 09:04:15 diego Exp $
-----------------------------------------------------------------------------
-----------------------------------------------------------------------------
-- Declare module and import dependencies
-----------------------------------------------------------------------------
local base = _G
local string = require("string")
local socket = require("socket")
local ltn12 = require("ltn12")
module("socket.tp")
-----------------------------------------------------------------------------
-- Program constants
-----------------------------------------------------------------------------
TIMEOUT = 60
-----------------------------------------------------------------------------
-- Implementation
-----------------------------------------------------------------------------
-- gets server reply (works for SMTP and FTP)
local function get_reply(c)
local code, current, sep
local line, err = c:receive()
local reply = line
if err then return nil, err end
code, sep = socket.skip(2, string.find(line, "^(%d%d%d)(.?)"))
if not code then return nil, "invalid server reply" end
if sep == "-" then -- reply is multiline
repeat
line, err = c:receive()
if err then return nil, err end
current, sep = socket.skip(2, string.find(line, "^(%d%d%d)(.?)"))
reply = reply .. "\n" .. line
-- reply ends with same code
until code == current and sep == " "
end
return code, reply
end
-- metatable for sock object
local metat = { __index = {} }
function metat.__index:check(ok)
local code, reply = get_reply(self.c)
if not code then return nil, reply end
if base.type(ok) ~= "function" then
if base.type(ok) == "table" then
for i, v in base.ipairs(ok) do
if string.find(code, v) then
return base.tonumber(code), reply
end
end
return nil, reply
else
if string.find(code, ok) then return base.tonumber(code), reply
else return nil, reply end
end
else return ok(base.tonumber(code), reply) end
end
function metat.__index:command(cmd, arg)
if arg then
return self.c:send(cmd .. " " .. arg.. "\r\n")
else
return self.c:send(cmd .. "\r\n")
end
end
function metat.__index:sink(snk, pat)
local chunk, err = c:receive(pat)
return snk(chunk, err)
end
function metat.__index:send(data)
return self.c:send(data)
end
function metat.__index:receive(pat)
return self.c:receive(pat)
end
function metat.__index:getfd()
return self.c:getfd()
end
function metat.__index:dirty()
return self.c:dirty()
end
function metat.__index:getcontrol()
return self.c
end
function metat.__index:source(source, step)
local sink = socket.sink("keep-open", self.c)
local ret, err = ltn12.pump.all(source, sink, step or ltn12.pump.step)
return ret, err
end
-- closes the underlying c
function metat.__index:close()
self.c:close()
return 1
end
-- connect with server and return c object
function connect(host, port, timeout, create)
local c, e = (create or socket.tcp)()
if not c then return nil, e end
c:settimeout(timeout or TIMEOUT)
local r, e = c:connect(host, port)
if not r then
c:close()
return nil, e
end
return base.setmetatable({c = c}, metat)
end
@@ -0,0 +1,192 @@
/* code automatically generated by bin2c -- DO NOT EDIT */
{
/* #include'ing this file in a C program is equivalent to calling
if (luaL_loadfile(L,"tp.lua")==0) lua_call(L, 0, 0);
*/
/* tp.lua */
static const unsigned char B1[]={
45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45,
45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45,
45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45,
45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 10, 45, 45,
32, 85,110,105,102,105,101,100, 32, 83, 77, 84, 80, 47, 70, 84, 80, 32,115,117,
98,115,121,115,116,101,109, 10, 45, 45, 32, 76,117, 97, 83,111, 99,107,101,116,
32,116,111,111,108,107,105,116, 46, 10, 45, 45, 32, 65,117,116,104,111,114, 58,
32, 68,105,101,103,111, 32, 78,101,104, 97, 98, 10, 45, 45, 32, 82, 67, 83, 32,
73, 68, 58, 32, 36, 73,100, 58, 32,116,112, 46,108,117, 97, 44,118, 32, 49, 46,
50, 50, 32, 50, 48, 48, 54, 47, 48, 51, 47, 49, 52, 32, 48, 57, 58, 48, 52, 58,
49, 53, 32,100,105,101,103,111, 32, 69,120,112, 32, 36, 10, 45, 45, 45, 45, 45,
45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45,
45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45,
45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45,
45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 10, 10, 45, 45, 45, 45, 45, 45,
45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45,
45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45,
45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45,
45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 10, 45, 45, 32, 68,101, 99,108, 97,
114,101, 32,109,111,100,117,108,101, 32, 97,110,100, 32,105,109,112,111,114,116,
32,100,101,112,101,110,100,101,110, 99,105,101,115, 10, 45, 45, 45, 45, 45, 45,
45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45,
45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45,
45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45,
45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 10,108,111, 99, 97,108, 32, 98, 97,
115,101, 32, 61, 32, 95, 71, 10,108,111, 99, 97,108, 32,115,116,114,105,110,103,
32, 61, 32,114,101,113,117,105,114,101, 40, 34,115,116,114,105,110,103, 34, 41,
10,108,111, 99, 97,108, 32,115,111, 99,107,101,116, 32, 61, 32,114,101,113,117,
105,114,101, 40, 34,115,111, 99,107,101,116, 34, 41, 10,108,111, 99, 97,108, 32,
108,116,110, 49, 50, 32, 61, 32,114,101,113,117,105,114,101, 40, 34,108,116,110,
49, 50, 34, 41, 10,109,111,100,117,108,101, 40, 34,115,111, 99,107,101,116, 46,
116,112, 34, 41, 10, 10, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45,
45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45,
45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45,
45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45,
45, 45, 45, 10, 45, 45, 32, 80,114,111,103,114, 97,109, 32, 99,111,110,115,116,
97,110,116,115, 10, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45,
45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45,
45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45,
45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45,
45, 45, 10, 84, 73, 77, 69, 79, 85, 84, 32, 61, 32, 54, 48, 10, 10, 45, 45, 45,
45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45,
45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45,
45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45,
45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 10, 45, 45, 32, 73,109,
112,108,101,109,101,110,116, 97,116,105,111,110, 10, 45, 45, 45, 45, 45, 45, 45,
45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45,
45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45,
45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45,
45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 10, 45, 45, 32,103,101,116,115, 32,115,
101,114,118,101,114, 32,114,101,112,108,121, 32, 40,119,111,114,107,115, 32,102,
111,114, 32, 83, 77, 84, 80, 32, 97,110,100, 32, 70, 84, 80, 41, 10,108,111, 99,
97,108, 32,102,117,110, 99,116,105,111,110, 32,103,101,116, 95,114,101,112,108,
121, 40, 99, 41, 10, 32, 32, 32, 32,108,111, 99, 97,108, 32, 99,111,100,101, 44,
32, 99,117,114,114,101,110,116, 44, 32,115,101,112, 10, 32, 32, 32, 32,108,111,
99, 97,108, 32,108,105,110,101, 44, 32,101,114,114, 32, 61, 32, 99, 58,114,101,
99,101,105,118,101, 40, 41, 10, 32, 32, 32, 32,108,111, 99, 97,108, 32,114,101,
112,108,121, 32, 61, 32,108,105,110,101, 10, 32, 32, 32, 32,105,102, 32,101,114,
114, 32,116,104,101,110, 32,114,101,116,117,114,110, 32,110,105,108, 44, 32,101,
114,114, 32,101,110,100, 10, 32, 32, 32, 32, 99,111,100,101, 44, 32,115,101,112,
32, 61, 32,115,111, 99,107,101,116, 46,115,107,105,112, 40, 50, 44, 32,115,116,
114,105,110,103, 46,102,105,110,100, 40,108,105,110,101, 44, 32, 34, 94, 40, 37,
100, 37,100, 37,100, 41, 40, 46, 63, 41, 34, 41, 41, 10, 32, 32, 32, 32,105,102,
32,110,111,116, 32, 99,111,100,101, 32,116,104,101,110, 32,114,101,116,117,114,
110, 32,110,105,108, 44, 32, 34,105,110,118, 97,108,105,100, 32,115,101,114,118,
101,114, 32,114,101,112,108,121, 34, 32,101,110,100, 10, 32, 32, 32, 32,105,102,
32,115,101,112, 32, 61, 61, 32, 34, 45, 34, 32,116,104,101,110, 32, 45, 45, 32,
114,101,112,108,121, 32,105,115, 32,109,117,108,116,105,108,105,110,101, 10, 32,
32, 32, 32, 32, 32, 32, 32,114,101,112,101, 97,116, 10, 32, 32, 32, 32, 32, 32,
32, 32, 32, 32, 32, 32,108,105,110,101, 44, 32,101,114,114, 32, 61, 32, 99, 58,
114,101, 99,101,105,118,101, 40, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
32, 32,105,102, 32,101,114,114, 32,116,104,101,110, 32,114,101,116,117,114,110,
32,110,105,108, 44, 32,101,114,114, 32,101,110,100, 10, 32, 32, 32, 32, 32, 32,
32, 32, 32, 32, 32, 32, 99,117,114,114,101,110,116, 44, 32,115,101,112, 32, 61,
32,115,111, 99,107,101,116, 46,115,107,105,112, 40, 50, 44, 32,115,116,114,105,
110,103, 46,102,105,110,100, 40,108,105,110,101, 44, 32, 34, 94, 40, 37,100, 37,
100, 37,100, 41, 40, 46, 63, 41, 34, 41, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32,
32, 32, 32, 32,114,101,112,108,121, 32, 61, 32,114,101,112,108,121, 32, 46, 46,
32, 34, 92,110, 34, 32, 46, 46, 32,108,105,110,101, 10, 32, 32, 32, 32, 32, 32,
32, 32, 45, 45, 32,114,101,112,108,121, 32,101,110,100,115, 32,119,105,116,104,
32,115, 97,109,101, 32, 99,111,100,101, 10, 32, 32, 32, 32, 32, 32, 32, 32,117,
110,116,105,108, 32, 99,111,100,101, 32, 61, 61, 32, 99,117,114,114,101,110,116,
32, 97,110,100, 32,115,101,112, 32, 61, 61, 32, 34, 32, 34, 10, 32, 32, 32, 32,
101,110,100, 10, 32, 32, 32, 32,114,101,116,117,114,110, 32, 99,111,100,101, 44,
32,114,101,112,108,121, 10,101,110,100, 10, 10, 45, 45, 32,109,101,116, 97,116,
97, 98,108,101, 32,102,111,114, 32,115,111, 99,107, 32,111, 98,106,101, 99,116,
10,108,111, 99, 97,108, 32,109,101,116, 97,116, 32, 61, 32,123, 32, 95, 95,105,
110,100,101,120, 32, 61, 32,123,125, 32,125, 10, 10,102,117,110, 99,116,105,111,
110, 32,109,101,116, 97,116, 46, 95, 95,105,110,100,101,120, 58, 99,104,101, 99,
107, 40,111,107, 41, 10, 32, 32, 32, 32,108,111, 99, 97,108, 32, 99,111,100,101,
44, 32,114,101,112,108,121, 32, 61, 32,103,101,116, 95,114,101,112,108,121, 40,
115,101,108,102, 46, 99, 41, 10, 32, 32, 32, 32,105,102, 32,110,111,116, 32, 99,
111,100,101, 32,116,104,101,110, 32,114,101,116,117,114,110, 32,110,105,108, 44,
32,114,101,112,108,121, 32,101,110,100, 10, 32, 32, 32, 32,105,102, 32, 98, 97,
115,101, 46,116,121,112,101, 40,111,107, 41, 32,126, 61, 32, 34,102,117,110, 99,
116,105,111,110, 34, 32,116,104,101,110, 10, 32, 32, 32, 32, 32, 32, 32, 32,105,
102, 32, 98, 97,115,101, 46,116,121,112,101, 40,111,107, 41, 32, 61, 61, 32, 34,
116, 97, 98,108,101, 34, 32,116,104,101,110, 10, 32, 32, 32, 32, 32, 32, 32, 32,
32, 32, 32, 32,102,111,114, 32,105, 44, 32,118, 32,105,110, 32, 98, 97,115,101,
46,105,112, 97,105,114,115, 40,111,107, 41, 32,100,111, 10, 32, 32, 32, 32, 32,
32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,105,102, 32,115,116,114,105,110,103,
46,102,105,110,100, 40, 99,111,100,101, 44, 32,118, 41, 32,116,104,101,110, 10,
32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
114,101,116,117,114,110, 32, 98, 97,115,101, 46,116,111,110,117,109, 98,101,114,
40, 99,111,100,101, 41, 44, 32,114,101,112,108,121, 10, 32, 32, 32, 32, 32, 32,
32, 32, 32, 32, 32, 32, 32, 32, 32, 32,101,110,100, 10, 32, 32, 32, 32, 32, 32,
32, 32, 32, 32, 32, 32,101,110,100, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
32, 32,114,101,116,117,114,110, 32,110,105,108, 44, 32,114,101,112,108,121, 10,
32, 32, 32, 32, 32, 32, 32, 32,101,108,115,101, 10, 32, 32, 32, 32, 32, 32, 32,
32, 32, 32, 32, 32,105,102, 32,115,116,114,105,110,103, 46,102,105,110,100, 40,
99,111,100,101, 44, 32,111,107, 41, 32,116,104,101,110, 32,114,101,116,117,114,
110, 32, 98, 97,115,101, 46,116,111,110,117,109, 98,101,114, 40, 99,111,100,101,
41, 44, 32,114,101,112,108,121, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
32,101,108,115,101, 32,114,101,116,117,114,110, 32,110,105,108, 44, 32,114,101,
112,108,121, 32,101,110,100, 10, 32, 32, 32, 32, 32, 32, 32, 32,101,110,100, 10,
32, 32, 32, 32,101,108,115,101, 32,114,101,116,117,114,110, 32,111,107, 40, 98,
97,115,101, 46,116,111,110,117,109, 98,101,114, 40, 99,111,100,101, 41, 44, 32,
114,101,112,108,121, 41, 32,101,110,100, 10,101,110,100, 10, 10,102,117,110, 99,
116,105,111,110, 32,109,101,116, 97,116, 46, 95, 95,105,110,100,101,120, 58, 99,
111,109,109, 97,110,100, 40, 99,109,100, 44, 32, 97,114,103, 41, 10, 32, 32, 32,
32,105,102, 32, 97,114,103, 32,116,104,101,110, 10, 32, 32, 32, 32, 32, 32, 32,
32,114,101,116,117,114,110, 32,115,101,108,102, 46, 99, 58,115,101,110,100, 40,
99,109,100, 32, 46, 46, 32, 34, 32, 34, 32, 46, 46, 32, 97,114,103, 46, 46, 32,
34, 92,114, 92,110, 34, 41, 10, 32, 32, 32, 32,101,108,115,101, 10, 32, 32, 32,
32, 32, 32, 32, 32,114,101,116,117,114,110, 32,115,101,108,102, 46, 99, 58,115,
101,110,100, 40, 99,109,100, 32, 46, 46, 32, 34, 92,114, 92,110, 34, 41, 10, 32,
32, 32, 32,101,110,100, 10,101,110,100, 10, 10,102,117,110, 99,116,105,111,110,
32,109,101,116, 97,116, 46, 95, 95,105,110,100,101,120, 58,115,105,110,107, 40,
115,110,107, 44, 32,112, 97,116, 41, 10, 32, 32, 32, 32,108,111, 99, 97,108, 32,
99,104,117,110,107, 44, 32,101,114,114, 32, 61, 32, 99, 58,114,101, 99,101,105,
118,101, 40,112, 97,116, 41, 10, 32, 32, 32, 32,114,101,116,117,114,110, 32,115,
110,107, 40, 99,104,117,110,107, 44, 32,101,114,114, 41, 10,101,110,100, 10, 10,
102,117,110, 99,116,105,111,110, 32,109,101,116, 97,116, 46, 95, 95,105,110,100,
101,120, 58,115,101,110,100, 40,100, 97,116, 97, 41, 10, 32, 32, 32, 32,114,101,
116,117,114,110, 32,115,101,108,102, 46, 99, 58,115,101,110,100, 40,100, 97,116,
97, 41, 10,101,110,100, 10, 10,102,117,110, 99,116,105,111,110, 32,109,101,116,
97,116, 46, 95, 95,105,110,100,101,120, 58,114,101, 99,101,105,118,101, 40,112,
97,116, 41, 10, 32, 32, 32, 32,114,101,116,117,114,110, 32,115,101,108,102, 46,
99, 58,114,101, 99,101,105,118,101, 40,112, 97,116, 41, 10,101,110,100, 10, 10,
102,117,110, 99,116,105,111,110, 32,109,101,116, 97,116, 46, 95, 95,105,110,100,
101,120, 58,103,101,116,102,100, 40, 41, 10, 32, 32, 32, 32,114,101,116,117,114,
110, 32,115,101,108,102, 46, 99, 58,103,101,116,102,100, 40, 41, 10,101,110,100,
10, 10,102,117,110, 99,116,105,111,110, 32,109,101,116, 97,116, 46, 95, 95,105,
110,100,101,120, 58,100,105,114,116,121, 40, 41, 10, 32, 32, 32, 32,114,101,116,
117,114,110, 32,115,101,108,102, 46, 99, 58,100,105,114,116,121, 40, 41, 10,101,
110,100, 10, 10,102,117,110, 99,116,105,111,110, 32,109,101,116, 97,116, 46, 95,
95,105,110,100,101,120, 58,103,101,116, 99,111,110,116,114,111,108, 40, 41, 10,
32, 32, 32, 32,114,101,116,117,114,110, 32,115,101,108,102, 46, 99, 10,101,110,
100, 10, 10,102,117,110, 99,116,105,111,110, 32,109,101,116, 97,116, 46, 95, 95,
105,110,100,101,120, 58,115,111,117,114, 99,101, 40,115,111,117,114, 99,101, 44,
32,115,116,101,112, 41, 10, 32, 32, 32, 32,108,111, 99, 97,108, 32,115,105,110,
107, 32, 61, 32,115,111, 99,107,101,116, 46,115,105,110,107, 40, 34,107,101,101,
112, 45,111,112,101,110, 34, 44, 32,115,101,108,102, 46, 99, 41, 10, 32, 32, 32,
32,108,111, 99, 97,108, 32,114,101,116, 44, 32,101,114,114, 32, 61, 32,108,116,
110, 49, 50, 46,112,117,109,112, 46, 97,108,108, 40,115,111,117,114, 99,101, 44,
32,115,105,110,107, 44, 32,115,116,101,112, 32,111,114, 32,108,116,110, 49, 50,
46,112,117,109,112, 46,115,116,101,112, 41, 10, 32, 32, 32, 32,114,101,116,117,
114,110, 32,114,101,116, 44, 32,101,114,114, 10,101,110,100, 10, 10, 45, 45, 32,
99,108,111,115,101,115, 32,116,104,101, 32,117,110,100,101,114,108,121,105,110,
103, 32, 99, 10,102,117,110, 99,116,105,111,110, 32,109,101,116, 97,116, 46, 95,
95,105,110,100,101,120, 58, 99,108,111,115,101, 40, 41, 10, 32, 32, 32, 32,115,
101,108,102, 46, 99, 58, 99,108,111,115,101, 40, 41, 10, 9,114,101,116,117,114,
110, 32, 49, 10,101,110,100, 10, 10, 45, 45, 32, 99,111,110,110,101, 99,116, 32,
119,105,116,104, 32,115,101,114,118,101,114, 32, 97,110,100, 32,114,101,116,117,
114,110, 32, 99, 32,111, 98,106,101, 99,116, 10,102,117,110, 99,116,105,111,110,
32, 99,111,110,110,101, 99,116, 40,104,111,115,116, 44, 32,112,111,114,116, 44,
32,116,105,109,101,111,117,116, 44, 32, 99,114,101, 97,116,101, 41, 10, 32, 32,
32, 32,108,111, 99, 97,108, 32, 99, 44, 32,101, 32, 61, 32, 40, 99,114,101, 97,
116,101, 32,111,114, 32,115,111, 99,107,101,116, 46,116, 99,112, 41, 40, 41, 10,
32, 32, 32, 32,105,102, 32,110,111,116, 32, 99, 32,116,104,101,110, 32,114,101,
116,117,114,110, 32,110,105,108, 44, 32,101, 32,101,110,100, 10, 32, 32, 32, 32,
99, 58,115,101,116,116,105,109,101,111,117,116, 40,116,105,109,101,111,117,116,
32,111,114, 32, 84, 73, 77, 69, 79, 85, 84, 41, 10, 32, 32, 32, 32,108,111, 99,
97,108, 32,114, 44, 32,101, 32, 61, 32, 99, 58, 99,111,110,110,101, 99,116, 40,
104,111,115,116, 44, 32,112,111,114,116, 41, 10, 32, 32, 32, 32,105,102, 32,110,
111,116, 32,114, 32,116,104,101,110, 10, 32, 32, 32, 32, 32, 32, 32, 32, 99, 58,
99,108,111,115,101, 40, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32,114,101,116,117,
114,110, 32,110,105,108, 44, 32,101, 10, 32, 32, 32, 32,101,110,100, 10, 32, 32,
32, 32,114,101,116,117,114,110, 32, 98, 97,115,101, 46,115,101,116,109,101,116,
97,116, 97, 98,108,101, 40,123, 99, 32, 61, 32, 99,125, 44, 32,109,101,116, 97,
116, 41, 10,101,110,100, 10, 10,
};
if (luaL_loadbuffer(L,(const char*)B1,sizeof(B1),"tp.lua")==0) lua_call(L, 0, 0);
}
+336
View File
@@ -0,0 +1,336 @@
/*=========================================================================*\
* UDP object
* LuaSocket toolkit
*
* RCS ID: $Id: udp.c,v 1.29 2005/10/07 04:40:59 diego Exp $
\*=========================================================================*/
#include <string.h>
#include "lua.h"
#include "lauxlib.h"
#include "auxiliar.h"
#include "socket.h"
#include "inet.h"
#include "options.h"
#include "udp.h"
/* min and max macros */
#ifndef MIN
#define MIN(x, y) ((x) < (y) ? x : y)
#endif
#ifndef MAX
#define MAX(x, y) ((x) > (y) ? x : y)
#endif
/*=========================================================================*\
* Internal function prototypes
\*=========================================================================*/
static int global_create(lua_State *L);
static int meth_send(lua_State *L);
static int meth_sendto(lua_State *L);
static int meth_receive(lua_State *L);
static int meth_receivefrom(lua_State *L);
static int meth_getsockname(lua_State *L);
static int meth_getpeername(lua_State *L);
static int meth_setsockname(lua_State *L);
static int meth_setpeername(lua_State *L);
static int meth_close(lua_State *L);
static int meth_setoption(lua_State *L);
static int meth_settimeout(lua_State *L);
static int meth_getfd(lua_State *L);
static int meth_setfd(lua_State *L);
static int meth_dirty(lua_State *L);
/* udp object methods */
static luaL_reg udp[] = {
{"__gc", meth_close},
{"__tostring", auxiliar_tostring},
{"close", meth_close},
{"dirty", meth_dirty},
{"getfd", meth_getfd},
{"getpeername", meth_getpeername},
{"getsockname", meth_getsockname},
{"receive", meth_receive},
{"receivefrom", meth_receivefrom},
{"send", meth_send},
{"sendto", meth_sendto},
{"setfd", meth_setfd},
{"setoption", meth_setoption},
{"setpeername", meth_setpeername},
{"setsockname", meth_setsockname},
{"settimeout", meth_settimeout},
{NULL, NULL}
};
/* socket options */
static t_opt opt[] = {
{"dontroute", opt_dontroute},
{"broadcast", opt_broadcast},
{"reuseaddr", opt_reuseaddr},
{"ip-multicast-ttl", opt_ip_multicast_ttl},
{"ip-multicast-loop", opt_ip_multicast_loop},
{"ip-add-membership", opt_ip_add_membership},
{"ip-drop-membership", opt_ip_drop_membersip},
{NULL, NULL}
};
/* functions in library namespace */
static luaL_reg func[] = {
{"udp", global_create},
{NULL, NULL}
};
/*-------------------------------------------------------------------------*\
* Initializes module
\*-------------------------------------------------------------------------*/
int udp_open(lua_State *L)
{
/* create classes */
auxiliar_newclass(L, "udp{connected}", udp);
auxiliar_newclass(L, "udp{unconnected}", udp);
/* create class groups */
auxiliar_add2group(L, "udp{connected}", "udp{any}");
auxiliar_add2group(L, "udp{unconnected}", "udp{any}");
auxiliar_add2group(L, "udp{connected}", "select{able}");
auxiliar_add2group(L, "udp{unconnected}", "select{able}");
/* define library functions */
luaL_openlib(L, NULL, func, 0);
return 0;
}
/*=========================================================================*\
* Lua methods
\*=========================================================================*/
const char *udp_strerror(int err) {
/* a 'closed' error on an unconnected means the target address was not
* accepted by the transport layer */
if (err == IO_CLOSED) return "refused";
else return socket_strerror(err);
}
/*-------------------------------------------------------------------------*\
* Send data through connected udp socket
\*-------------------------------------------------------------------------*/
static int meth_send(lua_State *L) {
p_udp udp = (p_udp) auxiliar_checkclass(L, "udp{connected}", 1);
p_timeout tm = &udp->tm;
size_t count, sent = 0;
int err;
const char *data = luaL_checklstring(L, 2, &count);
timeout_markstart(tm);
err = socket_send(&udp->sock, data, count, &sent, tm);
if (err != IO_DONE) {
lua_pushnil(L);
lua_pushstring(L, udp_strerror(err));
return 2;
}
lua_pushnumber(L, sent);
return 1;
}
/*-------------------------------------------------------------------------*\
* Send data through unconnected udp socket
\*-------------------------------------------------------------------------*/
static int meth_sendto(lua_State *L) {
p_udp udp = (p_udp) auxiliar_checkclass(L, "udp{unconnected}", 1);
size_t count, sent = 0;
const char *data = luaL_checklstring(L, 2, &count);
const char *ip = luaL_checkstring(L, 3);
unsigned short port = (unsigned short) luaL_checknumber(L, 4);
p_timeout tm = &udp->tm;
struct sockaddr_in addr;
int err;
memset(&addr, 0, sizeof(addr));
if (!inet_aton(ip, &addr.sin_addr))
luaL_argerror(L, 3, "invalid ip address");
addr.sin_family = AF_INET;
addr.sin_port = htons(port);
timeout_markstart(tm);
err = socket_sendto(&udp->sock, data, count, &sent,
(SA *) &addr, sizeof(addr), tm);
if (err != IO_DONE) {
lua_pushnil(L);
lua_pushstring(L, udp_strerror(err));
return 2;
}
lua_pushnumber(L, sent);
return 1;
}
/*-------------------------------------------------------------------------*\
* Receives data from a UDP socket
\*-------------------------------------------------------------------------*/
static int meth_receive(lua_State *L) {
p_udp udp = (p_udp) auxiliar_checkgroup(L, "udp{any}", 1);
char buffer[UDP_DATAGRAMSIZE];
size_t got, count = (size_t) luaL_optnumber(L, 2, sizeof(buffer));
int err;
p_timeout tm = &udp->tm;
count = MIN(count, sizeof(buffer));
timeout_markstart(tm);
err = socket_recv(&udp->sock, buffer, count, &got, tm);
if (err != IO_DONE) {
lua_pushnil(L);
lua_pushstring(L, udp_strerror(err));
return 2;
}
lua_pushlstring(L, buffer, got);
return 1;
}
/*-------------------------------------------------------------------------*\
* Receives data and sender from a UDP socket
\*-------------------------------------------------------------------------*/
static int meth_receivefrom(lua_State *L) {
p_udp udp = (p_udp) auxiliar_checkclass(L, "udp{unconnected}", 1);
struct sockaddr_in addr;
socklen_t addr_len = sizeof(addr);
char buffer[UDP_DATAGRAMSIZE];
size_t got, count = (size_t) luaL_optnumber(L, 2, sizeof(buffer));
int err;
p_timeout tm = &udp->tm;
timeout_markstart(tm);
count = MIN(count, sizeof(buffer));
err = socket_recvfrom(&udp->sock, buffer, count, &got,
(SA *) &addr, &addr_len, tm);
if (err == IO_DONE) {
lua_pushlstring(L, buffer, got);
lua_pushstring(L, inet_ntoa(addr.sin_addr));
lua_pushnumber(L, ntohs(addr.sin_port));
return 3;
} else {
lua_pushnil(L);
lua_pushstring(L, udp_strerror(err));
return 2;
}
}
/*-------------------------------------------------------------------------*\
* Select support methods
\*-------------------------------------------------------------------------*/
static int meth_getfd(lua_State *L) {
p_udp udp = (p_udp) auxiliar_checkgroup(L, "udp{any}", 1);
lua_pushnumber(L, (int) udp->sock);
return 1;
}
/* this is very dangerous, but can be handy for those that are brave enough */
static int meth_setfd(lua_State *L) {
p_udp udp = (p_udp) auxiliar_checkgroup(L, "udp{any}", 1);
udp->sock = (t_socket) luaL_checknumber(L, 2);
return 0;
}
static int meth_dirty(lua_State *L) {
p_udp udp = (p_udp) auxiliar_checkgroup(L, "udp{any}", 1);
(void) udp;
lua_pushboolean(L, 0);
return 1;
}
/*-------------------------------------------------------------------------*\
* Just call inet methods
\*-------------------------------------------------------------------------*/
static int meth_getpeername(lua_State *L) {
p_udp udp = (p_udp) auxiliar_checkclass(L, "udp{connected}", 1);
return inet_meth_getpeername(L, &udp->sock);
}
static int meth_getsockname(lua_State *L) {
p_udp udp = (p_udp) auxiliar_checkgroup(L, "udp{any}", 1);
return inet_meth_getsockname(L, &udp->sock);
}
/*-------------------------------------------------------------------------*\
* Just call option handler
\*-------------------------------------------------------------------------*/
static int meth_setoption(lua_State *L) {
p_udp udp = (p_udp) auxiliar_checkgroup(L, "udp{any}", 1);
return opt_meth_setoption(L, opt, &udp->sock);
}
/*-------------------------------------------------------------------------*\
* Just call tm methods
\*-------------------------------------------------------------------------*/
static int meth_settimeout(lua_State *L) {
p_udp udp = (p_udp) auxiliar_checkgroup(L, "udp{any}", 1);
return timeout_meth_settimeout(L, &udp->tm);
}
/*-------------------------------------------------------------------------*\
* Turns a master udp object into a client object.
\*-------------------------------------------------------------------------*/
static int meth_setpeername(lua_State *L) {
p_udp udp = (p_udp) auxiliar_checkgroup(L, "udp{any}", 1);
p_timeout tm = &udp->tm;
const char *address = luaL_checkstring(L, 2);
int connecting = strcmp(address, "*");
unsigned short port = connecting ?
(unsigned short) luaL_checknumber(L, 3) :
(unsigned short) luaL_optnumber(L, 3, 0);
const char *err = inet_tryconnect(&udp->sock, address, port, tm);
if (err) {
lua_pushnil(L);
lua_pushstring(L, err);
return 2;
}
/* change class to connected or unconnected depending on address */
if (connecting) auxiliar_setclass(L, "udp{connected}", 1);
else auxiliar_setclass(L, "udp{unconnected}", 1);
lua_pushnumber(L, 1);
return 1;
}
/*-------------------------------------------------------------------------*\
* Closes socket used by object
\*-------------------------------------------------------------------------*/
static int meth_close(lua_State *L) {
p_udp udp = (p_udp) auxiliar_checkgroup(L, "udp{any}", 1);
socket_destroy(&udp->sock);
lua_pushnumber(L, 1);
return 1;
}
/*-------------------------------------------------------------------------*\
* Turns a master object into a server object
\*-------------------------------------------------------------------------*/
static int meth_setsockname(lua_State *L) {
p_udp udp = (p_udp) auxiliar_checkclass(L, "udp{unconnected}", 1);
const char *address = luaL_checkstring(L, 2);
unsigned short port = (unsigned short) luaL_checknumber(L, 3);
const char *err = inet_trybind(&udp->sock, address, port);
if (err) {
lua_pushnil(L);
lua_pushstring(L, err);
return 2;
}
lua_pushnumber(L, 1);
return 1;
}
/*=========================================================================*\
* Library functions
\*=========================================================================*/
/*-------------------------------------------------------------------------*\
* Creates a master udp object
\*-------------------------------------------------------------------------*/
static int global_create(lua_State *L) {
t_socket sock;
const char *err = inet_trycreate(&sock, SOCK_DGRAM);
/* try to allocate a system socket */
if (!err) {
/* allocate tcp object */
p_udp udp = (p_udp) lua_newuserdata(L, sizeof(t_udp));
auxiliar_setclass(L, "udp{unconnected}", -1);
/* initialize remaining structure fields */
socket_setnonblocking(&sock);
udp->sock = sock;
timeout_init(&udp->tm, -1, -1);
return 1;
} else {
lua_pushnil(L);
lua_pushstring(L, err);
return 2;
}
}
@@ -0,0 +1,33 @@
#ifndef UDP_H
#define UDP_H
/*=========================================================================*\
* UDP object
* LuaSocket toolkit
*
* The udp.h module provides LuaSocket with support for UDP protocol
* (AF_INET, SOCK_DGRAM).
*
* Two classes are defined: connected and unconnected. UDP objects are
* originally unconnected. They can be "connected" to a given address
* with a call to the setpeername function. The same function can be used to
* break the connection.
*
* RCS ID: $Id: udp.h,v 1.10 2005/10/07 04:40:59 diego Exp $
\*=========================================================================*/
#include "lua.h"
#include "timeout.h"
#include "socket.h"
/* can't be larger than wsocket.c MAXCHUNK!!! */
#define UDP_DATAGRAMSIZE 8192
typedef struct t_udp_ {
t_socket sock;
t_timeout tm;
} t_udp;
typedef t_udp *p_udp;
int udp_open(lua_State *L);
#endif /* UDP_H */
+356
View File
@@ -0,0 +1,356 @@
/*=========================================================================*\
* Unix domain socket
* LuaSocket toolkit
*
* RCS ID: $Id: unix.c,v 1.13 2006/03/13 07:16:39 diego Exp $
\*=========================================================================*/
#include <string.h>
#include "lua.h"
#include "lauxlib.h"
#include "auxiliar.h"
#include "socket.h"
#include "options.h"
#include "unix.h"
#include <sys/un.h>
/*=========================================================================*\
* Internal function prototypes
\*=========================================================================*/
static int global_create(lua_State *L);
static int meth_connect(lua_State *L);
static int meth_listen(lua_State *L);
static int meth_bind(lua_State *L);
static int meth_send(lua_State *L);
static int meth_shutdown(lua_State *L);
static int meth_receive(lua_State *L);
static int meth_accept(lua_State *L);
static int meth_close(lua_State *L);
static int meth_setoption(lua_State *L);
static int meth_settimeout(lua_State *L);
static int meth_getfd(lua_State *L);
static int meth_setfd(lua_State *L);
static int meth_dirty(lua_State *L);
static int meth_getstats(lua_State *L);
static int meth_setstats(lua_State *L);
static const char *unix_tryconnect(p_unix un, const char *path);
static const char *unix_trybind(p_unix un, const char *path);
/* unix object methods */
static luaL_reg un[] = {
{"__gc", meth_close},
{"__tostring", auxiliar_tostring},
{"accept", meth_accept},
{"bind", meth_bind},
{"close", meth_close},
{"connect", meth_connect},
{"dirty", meth_dirty},
{"getfd", meth_getfd},
{"getstats", meth_getstats},
{"setstats", meth_setstats},
{"listen", meth_listen},
{"receive", meth_receive},
{"send", meth_send},
{"setfd", meth_setfd},
{"setoption", meth_setoption},
{"setpeername", meth_connect},
{"setsockname", meth_bind},
{"settimeout", meth_settimeout},
{"shutdown", meth_shutdown},
{NULL, NULL}
};
/* socket option handlers */
static t_opt opt[] = {
{"keepalive", opt_keepalive},
{"reuseaddr", opt_reuseaddr},
{"linger", opt_linger},
{NULL, NULL}
};
/* our socket creation function */
static luaL_reg func[] = {
{"unix", global_create},
{NULL, NULL}
};
/*-------------------------------------------------------------------------*\
* Initializes module
\*-------------------------------------------------------------------------*/
int luaopen_socket_unix(lua_State *L) {
/* create classes */
auxiliar_newclass(L, "unix{master}", un);
auxiliar_newclass(L, "unix{client}", un);
auxiliar_newclass(L, "unix{server}", un);
/* create class groups */
auxiliar_add2group(L, "unix{master}", "unix{any}");
auxiliar_add2group(L, "unix{client}", "unix{any}");
auxiliar_add2group(L, "unix{server}", "unix{any}");
/* make sure the function ends up in the package table */
luaL_openlib(L, "socket", func, 0);
/* return the function instead of the 'socket' table */
lua_pushstring(L, "unix");
lua_gettable(L, -2);
return 1;
}
/*=========================================================================*\
* Lua methods
\*=========================================================================*/
/*-------------------------------------------------------------------------*\
* Just call buffered IO methods
\*-------------------------------------------------------------------------*/
static int meth_send(lua_State *L) {
p_unix un = (p_unix) auxiliar_checkclass(L, "unix{client}", 1);
return buffer_meth_send(L, &un->buf);
}
static int meth_receive(lua_State *L) {
p_unix un = (p_unix) auxiliar_checkclass(L, "unix{client}", 1);
return buffer_meth_receive(L, &un->buf);
}
static int meth_getstats(lua_State *L) {
p_unix un = (p_unix) auxiliar_checkclass(L, "unix{client}", 1);
return buffer_meth_getstats(L, &un->buf);
}
static int meth_setstats(lua_State *L) {
p_unix un = (p_unix) auxiliar_checkclass(L, "unix{client}", 1);
return buffer_meth_setstats(L, &un->buf);
}
/*-------------------------------------------------------------------------*\
* Just call option handler
\*-------------------------------------------------------------------------*/
static int meth_setoption(lua_State *L) {
p_unix un = (p_unix) auxiliar_checkgroup(L, "unix{any}", 1);
return opt_meth_setoption(L, opt, &un->sock);
}
/*-------------------------------------------------------------------------*\
* Select support methods
\*-------------------------------------------------------------------------*/
static int meth_getfd(lua_State *L) {
p_unix un = (p_unix) auxiliar_checkgroup(L, "unix{any}", 1);
lua_pushnumber(L, (int) un->sock);
return 1;
}
/* this is very dangerous, but can be handy for those that are brave enough */
static int meth_setfd(lua_State *L) {
p_unix un = (p_unix) auxiliar_checkgroup(L, "unix{any}", 1);
un->sock = (t_socket) luaL_checknumber(L, 2);
return 0;
}
static int meth_dirty(lua_State *L) {
p_unix un = (p_unix) auxiliar_checkgroup(L, "unix{any}", 1);
lua_pushboolean(L, !buffer_isempty(&un->buf));
return 1;
}
/*-------------------------------------------------------------------------*\
* Waits for and returns a client object attempting connection to the
* server object
\*-------------------------------------------------------------------------*/
static int meth_accept(lua_State *L) {
p_unix server = (p_unix) auxiliar_checkclass(L, "unix{server}", 1);
p_timeout tm = timeout_markstart(&server->tm);
t_socket sock;
int err = socket_accept(&server->sock, &sock, NULL, NULL, tm);
/* if successful, push client socket */
if (err == IO_DONE) {
p_unix clnt = (p_unix) lua_newuserdata(L, sizeof(t_unix));
auxiliar_setclass(L, "unix{client}", -1);
/* initialize structure fields */
socket_setnonblocking(&sock);
clnt->sock = sock;
io_init(&clnt->io, (p_send)socket_send, (p_recv)socket_recv,
(p_error) socket_ioerror, &clnt->sock);
timeout_init(&clnt->tm, -1, -1);
buffer_init(&clnt->buf, &clnt->io, &clnt->tm);
return 1;
} else {
lua_pushnil(L);
lua_pushstring(L, socket_strerror(err));
return 2;
}
}
/*-------------------------------------------------------------------------*\
* Binds an object to an address
\*-------------------------------------------------------------------------*/
static const char *unix_trybind(p_unix un, const char *path) {
struct sockaddr_un local;
size_t len = strlen(path);
int err;
if (len >= sizeof(local.sun_path)) return "path too long";
memset(&local, 0, sizeof(local));
strcpy(local.sun_path, path);
local.sun_family = AF_UNIX;
#ifdef UNIX_HAS_SUN_LEN
local.sun_len = sizeof(local.sun_family) + sizeof(local.sun_len)
+ len + 1;
err = socket_bind(&un->sock, (SA *) &local, local.sun_len);
#else
err = socket_bind(&un->sock, (SA *) &local,
sizeof(local.sun_family) + len);
#endif
if (err != IO_DONE) socket_destroy(&un->sock);
return socket_strerror(err);
}
static int meth_bind(lua_State *L) {
p_unix un = (p_unix) auxiliar_checkclass(L, "unix{master}", 1);
const char *path = luaL_checkstring(L, 2);
const char *err = unix_trybind(un, path);
if (err) {
lua_pushnil(L);
lua_pushstring(L, err);
return 2;
}
lua_pushnumber(L, 1);
return 1;
}
/*-------------------------------------------------------------------------*\
* Turns a master unix object into a client object.
\*-------------------------------------------------------------------------*/
static const char *unix_tryconnect(p_unix un, const char *path)
{
struct sockaddr_un remote;
int err;
size_t len = strlen(path);
if (len >= sizeof(remote.sun_path)) return "path too long";
memset(&remote, 0, sizeof(remote));
strcpy(remote.sun_path, path);
remote.sun_family = AF_UNIX;
timeout_markstart(&un->tm);
#ifdef UNIX_HAS_SUN_LEN
remote.sun_len = sizeof(remote.sun_family) + sizeof(remote.sun_len)
+ len + 1;
err = socket_connect(&un->sock, (SA *) &remote, remote.sun_len, &un->tm);
#else
err = socket_connect(&un->sock, (SA *) &remote,
sizeof(remote.sun_family) + len, &un->tm);
#endif
if (err != IO_DONE) socket_destroy(&un->sock);
return socket_strerror(err);
}
static int meth_connect(lua_State *L)
{
p_unix un = (p_unix) auxiliar_checkclass(L, "unix{master}", 1);
const char *path = luaL_checkstring(L, 2);
const char *err = unix_tryconnect(un, path);
if (err) {
lua_pushnil(L);
lua_pushstring(L, err);
return 2;
}
/* turn master object into a client object */
auxiliar_setclass(L, "unix{client}", 1);
lua_pushnumber(L, 1);
return 1;
}
/*-------------------------------------------------------------------------*\
* Closes socket used by object
\*-------------------------------------------------------------------------*/
static int meth_close(lua_State *L)
{
p_unix un = (p_unix) auxiliar_checkgroup(L, "unix{any}", 1);
socket_destroy(&un->sock);
lua_pushnumber(L, 1);
return 1;
}
/*-------------------------------------------------------------------------*\
* Puts the sockt in listen mode
\*-------------------------------------------------------------------------*/
static int meth_listen(lua_State *L)
{
p_unix un = (p_unix) auxiliar_checkclass(L, "unix{master}", 1);
int backlog = (int) luaL_optnumber(L, 2, 32);
int err = socket_listen(&un->sock, backlog);
if (err != IO_DONE) {
lua_pushnil(L);
lua_pushstring(L, socket_strerror(err));
return 2;
}
/* turn master object into a server object */
auxiliar_setclass(L, "unix{server}", 1);
lua_pushnumber(L, 1);
return 1;
}
/*-------------------------------------------------------------------------*\
* Shuts the connection down partially
\*-------------------------------------------------------------------------*/
static int meth_shutdown(lua_State *L)
{
p_unix un = (p_unix) auxiliar_checkclass(L, "unix{client}", 1);
const char *how = luaL_optstring(L, 2, "both");
switch (how[0]) {
case 'b':
if (strcmp(how, "both")) goto error;
socket_shutdown(&un->sock, 2);
break;
case 's':
if (strcmp(how, "send")) goto error;
socket_shutdown(&un->sock, 1);
break;
case 'r':
if (strcmp(how, "receive")) goto error;
socket_shutdown(&un->sock, 0);
break;
}
lua_pushnumber(L, 1);
return 1;
error:
luaL_argerror(L, 2, "invalid shutdown method");
return 0;
}
/*-------------------------------------------------------------------------*\
* Just call tm methods
\*-------------------------------------------------------------------------*/
static int meth_settimeout(lua_State *L) {
p_unix un = (p_unix) auxiliar_checkgroup(L, "unix{any}", 1);
return timeout_meth_settimeout(L, &un->tm);
}
/*=========================================================================*\
* Library functions
\*=========================================================================*/
/*-------------------------------------------------------------------------*\
* Creates a master unix object
\*-------------------------------------------------------------------------*/
static int global_create(lua_State *L) {
t_socket sock;
int err = socket_create(&sock, AF_UNIX, SOCK_STREAM, 0);
/* try to allocate a system socket */
if (err == IO_DONE) {
/* allocate unix object */
p_unix un = (p_unix) lua_newuserdata(L, sizeof(t_unix));
/* set its type as master object */
auxiliar_setclass(L, "unix{master}", -1);
/* initialize remaining structure fields */
socket_setnonblocking(&sock);
un->sock = sock;
io_init(&un->io, (p_send) socket_send, (p_recv) socket_recv,
(p_error) socket_ioerror, &un->sock);
timeout_init(&un->tm, -1, -1);
buffer_init(&un->buf, &un->io, &un->tm);
return 1;
} else {
lua_pushnil(L);
lua_pushstring(L, socket_strerror(err));
return 2;
}
}
@@ -0,0 +1,28 @@
#ifndef UNIX_H
#define UNIX_H
/*=========================================================================*\
* Unix domain object
* LuaSocket toolkit
*
* This module is just an example of how to extend LuaSocket with a new
* domain.
*
* RCS ID: $Id: unix.h,v 1.9 2006/03/13 07:16:39 diego Exp $
\*=========================================================================*/
#include "lua.h"
#include "buffer.h"
#include "timeout.h"
#include "socket.h"
typedef struct t_unix_ {
t_socket sock;
t_io io;
t_buffer buf;
t_timeout tm;
} t_unix;
typedef t_unix *p_unix;
int luaopen_socket_unix(lua_State *L);
#endif /* UNIX_H */
@@ -0,0 +1,297 @@
-----------------------------------------------------------------------------
-- URI parsing, composition and relative URL resolution
-- LuaSocket toolkit.
-- Author: Diego Nehab
-- RCS ID: $Id: url.lua,v 1.38 2006/04/03 04:45:42 diego Exp $
-----------------------------------------------------------------------------
-----------------------------------------------------------------------------
-- Declare module
-----------------------------------------------------------------------------
local string = require("string")
local base = _G
local table = require("table")
module("socket.url")
-----------------------------------------------------------------------------
-- Module version
-----------------------------------------------------------------------------
_VERSION = "URL 1.0.1"
-----------------------------------------------------------------------------
-- Encodes a string into its escaped hexadecimal representation
-- Input
-- s: binary string to be encoded
-- Returns
-- escaped representation of string binary
-----------------------------------------------------------------------------
function escape(s)
return string.gsub(s, "([^A-Za-z0-9_])", function(c)
return string.format("%%%02x", string.byte(c))
end)
end
-----------------------------------------------------------------------------
-- Protects a path segment, to prevent it from interfering with the
-- url parsing.
-- Input
-- s: binary string to be encoded
-- Returns
-- escaped representation of string binary
-----------------------------------------------------------------------------
local function make_set(t)
local s = {}
for i,v in base.ipairs(t) do
s[t[i]] = 1
end
return s
end
-- these are allowed withing a path segment, along with alphanum
-- other characters must be escaped
local segment_set = make_set {
"-", "_", ".", "!", "~", "*", "'", "(",
")", ":", "@", "&", "=", "+", "$", ",",
}
local function protect_segment(s)
return string.gsub(s, "([^A-Za-z0-9_])", function (c)
if segment_set[c] then return c
else return string.format("%%%02x", string.byte(c)) end
end)
end
-----------------------------------------------------------------------------
-- Encodes a string into its escaped hexadecimal representation
-- Input
-- s: binary string to be encoded
-- Returns
-- escaped representation of string binary
-----------------------------------------------------------------------------
function unescape(s)
return string.gsub(s, "%%(%x%x)", function(hex)
return string.char(base.tonumber(hex, 16))
end)
end
-----------------------------------------------------------------------------
-- Builds a path from a base path and a relative path
-- Input
-- base_path
-- relative_path
-- Returns
-- corresponding absolute path
-----------------------------------------------------------------------------
local function absolute_path(base_path, relative_path)
if string.sub(relative_path, 1, 1) == "/" then return relative_path end
local path = string.gsub(base_path, "[^/]*$", "")
path = path .. relative_path
path = string.gsub(path, "([^/]*%./)", function (s)
if s ~= "./" then return s else return "" end
end)
path = string.gsub(path, "/%.$", "/")
local reduced
while reduced ~= path do
reduced = path
path = string.gsub(reduced, "([^/]*/%.%./)", function (s)
if s ~= "../../" then return "" else return s end
end)
end
path = string.gsub(reduced, "([^/]*/%.%.)$", function (s)
if s ~= "../.." then return "" else return s end
end)
return path
end
-----------------------------------------------------------------------------
-- Parses a url and returns a table with all its parts according to RFC 2396
-- The following grammar describes the names given to the URL parts
-- <url> ::= <scheme>://<authority>/<path>;<params>?<query>#<fragment>
-- <authority> ::= <userinfo>@<host>:<port>
-- <userinfo> ::= <user>[:<password>]
-- <path> :: = {<segment>/}<segment>
-- Input
-- url: uniform resource locator of request
-- default: table with default values for each field
-- Returns
-- table with the following fields, where RFC naming conventions have
-- been preserved:
-- scheme, authority, userinfo, user, password, host, port,
-- path, params, query, fragment
-- Obs:
-- the leading '/' in {/<path>} is considered part of <path>
-----------------------------------------------------------------------------
function parse(url, default)
-- initialize default parameters
local parsed = {}
for i,v in base.pairs(default or parsed) do parsed[i] = v end
-- empty url is parsed to nil
if not url or url == "" then return nil, "invalid url" end
-- remove whitespace
-- url = string.gsub(url, "%s", "")
-- get fragment
url = string.gsub(url, "#(.*)$", function(f)
parsed.fragment = f
return ""
end)
-- get scheme
url = string.gsub(url, "^([%w][%w%+%-%.]*)%:",
function(s) parsed.scheme = s; return "" end)
-- get authority
url = string.gsub(url, "^//([^/]*)", function(n)
parsed.authority = n
return ""
end)
-- get query stringing
url = string.gsub(url, "%?(.*)", function(q)
parsed.query = q
return ""
end)
-- get params
url = string.gsub(url, "%;(.*)", function(p)
parsed.params = p
return ""
end)
-- path is whatever was left
if url ~= "" then parsed.path = url end
local authority = parsed.authority
if not authority then return parsed end
authority = string.gsub(authority,"^([^@]*)@",
function(u) parsed.userinfo = u; return "" end)
authority = string.gsub(authority, ":([^:]*)$",
function(p) parsed.port = p; return "" end)
if authority ~= "" then parsed.host = authority end
local userinfo = parsed.userinfo
if not userinfo then return parsed end
userinfo = string.gsub(userinfo, ":([^:]*)$",
function(p) parsed.password = p; return "" end)
parsed.user = userinfo
return parsed
end
-----------------------------------------------------------------------------
-- Rebuilds a parsed URL from its components.
-- Components are protected if any reserved or unallowed characters are found
-- Input
-- parsed: parsed URL, as returned by parse
-- Returns
-- a stringing with the corresponding URL
-----------------------------------------------------------------------------
function build(parsed)
local ppath = parse_path(parsed.path or "")
local url = build_path(ppath)
if parsed.params then url = url .. ";" .. parsed.params end
if parsed.query then url = url .. "?" .. parsed.query end
local authority = parsed.authority
if parsed.host then
authority = parsed.host
if parsed.port then authority = authority .. ":" .. parsed.port end
local userinfo = parsed.userinfo
if parsed.user then
userinfo = parsed.user
if parsed.password then
userinfo = userinfo .. ":" .. parsed.password
end
end
if userinfo then authority = userinfo .. "@" .. authority end
end
if authority then url = "//" .. authority .. url end
if parsed.scheme then url = parsed.scheme .. ":" .. url end
if parsed.fragment then url = url .. "#" .. parsed.fragment end
-- url = string.gsub(url, "%s", "")
return url
end
-----------------------------------------------------------------------------
-- Builds a absolute URL from a base and a relative URL according to RFC 2396
-- Input
-- base_url
-- relative_url
-- Returns
-- corresponding absolute url
-----------------------------------------------------------------------------
function absolute(base_url, relative_url)
if base.type(base_url) == "table" then
base_parsed = base_url
base_url = build(base_parsed)
else
base_parsed = parse(base_url)
end
local relative_parsed = parse(relative_url)
if not base_parsed then return relative_url
elseif not relative_parsed then return base_url
elseif relative_parsed.scheme then return relative_url
else
relative_parsed.scheme = base_parsed.scheme
if not relative_parsed.authority then
relative_parsed.authority = base_parsed.authority
if not relative_parsed.path then
relative_parsed.path = base_parsed.path
if not relative_parsed.params then
relative_parsed.params = base_parsed.params
if not relative_parsed.query then
relative_parsed.query = base_parsed.query
end
end
else
relative_parsed.path = absolute_path(base_parsed.path or "",
relative_parsed.path)
end
end
return build(relative_parsed)
end
end
-----------------------------------------------------------------------------
-- Breaks a path into its segments, unescaping the segments
-- Input
-- path
-- Returns
-- segment: a table with one entry per segment
-----------------------------------------------------------------------------
function parse_path(path)
local parsed = {}
path = path or ""
--path = string.gsub(path, "%s", "")
string.gsub(path, "([^/]+)", function (s) table.insert(parsed, s) end)
for i = 1, table.getn(parsed) do
parsed[i] = unescape(parsed[i])
end
if string.sub(path, 1, 1) == "/" then parsed.is_absolute = 1 end
if string.sub(path, -1, -1) == "/" then parsed.is_directory = 1 end
return parsed
end
-----------------------------------------------------------------------------
-- Builds a path component from its segments, escaping protected characters.
-- Input
-- parsed: path segments
-- unsafe: if true, segments are not protected before path is built
-- Returns
-- path: corresponding path stringing
-----------------------------------------------------------------------------
function build_path(parsed, unsafe)
local path = ""
local n = table.getn(parsed)
if unsafe then
for i = 1, n-1 do
path = path .. parsed[i]
path = path .. "/"
end
if n > 0 then
path = path .. parsed[n]
if parsed.is_directory then path = path .. "/" end
end
else
for i = 1, n-1 do
path = path .. protect_segment(parsed[i])
path = path .. "/"
end
if n > 0 then
path = path .. protect_segment(parsed[n])
if parsed.is_directory then path = path .. "/" end
end
end
if parsed.is_absolute then path = "/" .. path end
return path
end
@@ -0,0 +1,538 @@
/* code automatically generated by bin2c -- DO NOT EDIT */
{
/* #include'ing this file in a C program is equivalent to calling
if (luaL_loadfile(L,"url.lua")==0) lua_call(L, 0, 0);
*/
/* url.lua */
static const unsigned char B1[]={
45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45,
45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45,
45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45,
45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 10, 45, 45,
32, 85, 82, 73, 32,112, 97,114,115,105,110,103, 44, 32, 99,111,109,112,111,115,
105,116,105,111,110, 32, 97,110,100, 32,114,101,108, 97,116,105,118,101, 32, 85,
82, 76, 32,114,101,115,111,108,117,116,105,111,110, 10, 45, 45, 32, 76,117, 97,
83,111, 99,107,101,116, 32,116,111,111,108,107,105,116, 46, 10, 45, 45, 32, 65,
117,116,104,111,114, 58, 32, 68,105,101,103,111, 32, 78,101,104, 97, 98, 10, 45,
45, 32, 82, 67, 83, 32, 73, 68, 58, 32, 36, 73,100, 58, 32,117,114,108, 46,108,
117, 97, 44,118, 32, 49, 46, 51, 56, 32, 50, 48, 48, 54, 47, 48, 52, 47, 48, 51,
32, 48, 52, 58, 52, 53, 58, 52, 50, 32,100,105,101,103,111, 32, 69,120,112, 32,
36, 10, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45,
45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45,
45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45,
45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 10,
10, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45,
45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45,
45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45,
45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 10, 45,
45, 32, 68,101, 99,108, 97,114,101, 32,109,111,100,117,108,101, 10, 45, 45, 45,
45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45,
45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45,
45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45,
45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 10,108,111, 99, 97,108,
32,115,116,114,105,110,103, 32, 61, 32,114,101,113,117,105,114,101, 40, 34,115,
116,114,105,110,103, 34, 41, 10,108,111, 99, 97,108, 32, 98, 97,115,101, 32, 61,
32, 95, 71, 10,108,111, 99, 97,108, 32,116, 97, 98,108,101, 32, 61, 32,114,101,
113,117,105,114,101, 40, 34,116, 97, 98,108,101, 34, 41, 10,109,111,100,117,108,
101, 40, 34,115,111, 99,107,101,116, 46,117,114,108, 34, 41, 10, 10, 45, 45, 45,
45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45,
45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45,
45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45,
45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 10, 45, 45, 32, 77,111,
100,117,108,101, 32,118,101,114,115,105,111,110, 10, 45, 45, 45, 45, 45, 45, 45,
45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45,
45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45,
45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45,
45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 10, 95, 86, 69, 82, 83, 73, 79, 78, 32,
61, 32, 34, 85, 82, 76, 32, 49, 46, 48, 46, 49, 34, 10, 10, 45, 45, 45, 45, 45,
45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45,
45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45,
45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45,
45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 10, 45, 45, 32, 69,110, 99,111,
100,101,115, 32, 97, 32,115,116,114,105,110,103, 32,105,110,116,111, 32,105,116,
115, 32,101,115, 99, 97,112,101,100, 32,104,101,120, 97,100,101, 99,105,109, 97,
108, 32,114,101,112,114,101,115,101,110,116, 97,116,105,111,110, 10, 45, 45, 32,
73,110,112,117,116, 10, 45, 45, 32, 32, 32,115, 58, 32, 98,105,110, 97,114,121,
32,115,116,114,105,110,103, 32,116,111, 32, 98,101, 32,101,110, 99,111,100,101,
100, 10, 45, 45, 32, 82,101,116,117,114,110,115, 10, 45, 45, 32, 32, 32,101,115,
99, 97,112,101,100, 32,114,101,112,114,101,115,101,110,116, 97,116,105,111,110,
32,111,102, 32,115,116,114,105,110,103, 32, 98,105,110, 97,114,121, 10, 45, 45,
45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45,
45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45,
45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45,
45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 10,102,117,110, 99,
116,105,111,110, 32,101,115, 99, 97,112,101, 40,115, 41, 10, 32, 32, 32, 32,114,
101,116,117,114,110, 32,115,116,114,105,110,103, 46,103,115,117, 98, 40,115, 44,
32, 34, 40, 91, 94, 65, 45, 90, 97, 45,122, 48, 45, 57, 95, 93, 41, 34, 44, 32,
102,117,110, 99,116,105,111,110, 40, 99, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32,
114,101,116,117,114,110, 32,115,116,114,105,110,103, 46,102,111,114,109, 97,116,
40, 34, 37, 37, 37, 48, 50,120, 34, 44, 32,115,116,114,105,110,103, 46, 98,121,
116,101, 40, 99, 41, 41, 10, 32, 32, 32, 32,101,110,100, 41, 10,101,110,100, 10,
10, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45,
45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45,
45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45,
45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 10, 45,
45, 32, 80,114,111,116,101, 99,116,115, 32, 97, 32,112, 97,116,104, 32,115,101,
103,109,101,110,116, 44, 32,116,111, 32,112,114,101,118,101,110,116, 32,105,116,
32,102,114,111,109, 32,105,110,116,101,114,102,101,114,105,110,103, 32,119,105,
116,104, 32,116,104,101, 10, 45, 45, 32,117,114,108, 32,112, 97,114,115,105,110,
103, 46, 10, 45, 45, 32, 73,110,112,117,116, 10, 45, 45, 32, 32, 32,115, 58, 32,
98,105,110, 97,114,121, 32,115,116,114,105,110,103, 32,116,111, 32, 98,101, 32,
101,110, 99,111,100,101,100, 10, 45, 45, 32, 82,101,116,117,114,110,115, 10, 45,
45, 32, 32, 32,101,115, 99, 97,112,101,100, 32,114,101,112,114,101,115,101,110,
116, 97,116,105,111,110, 32,111,102, 32,115,116,114,105,110,103, 32, 98,105,110,
97,114,121, 10, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45,
45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45,
45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45,
45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45,
45, 10,108,111, 99, 97,108, 32,102,117,110, 99,116,105,111,110, 32,109, 97,107,
101, 95,115,101,116, 40,116, 41, 10, 9,108,111, 99, 97,108, 32,115, 32, 61, 32,
123,125, 10, 9,102,111,114, 32,105, 44,118, 32,105,110, 32, 98, 97,115,101, 46,
105,112, 97,105,114,115, 40,116, 41, 32,100,111, 10, 9, 9,115, 91,116, 91,105,
93, 93, 32, 61, 32, 49, 10, 9,101,110,100, 10, 9,114,101,116,117,114,110, 32,
115, 10,101,110,100, 10, 10, 45, 45, 32,116,104,101,115,101, 32, 97,114,101, 32,
97,108,108,111,119,101,100, 32,119,105,116,104,105,110,103, 32, 97, 32,112, 97,
116,104, 32,115,101,103,109,101,110,116, 44, 32, 97,108,111,110,103, 32,119,105,
116,104, 32, 97,108,112,104, 97,110,117,109, 10, 45, 45, 32,111,116,104,101,114,
32, 99,104, 97,114, 97, 99,116,101,114,115, 32,109,117,115,116, 32, 98,101, 32,
101,115, 99, 97,112,101,100, 10,108,111, 99, 97,108, 32,115,101,103,109,101,110,
116, 95,115,101,116, 32, 61, 32,109, 97,107,101, 95,115,101,116, 32,123, 10, 32,
32, 32, 32, 34, 45, 34, 44, 32, 34, 95, 34, 44, 32, 34, 46, 34, 44, 32, 34, 33,
34, 44, 32, 34,126, 34, 44, 32, 34, 42, 34, 44, 32, 34, 39, 34, 44, 32, 34, 40,
34, 44, 10, 9, 34, 41, 34, 44, 32, 34, 58, 34, 44, 32, 34, 64, 34, 44, 32, 34,
38, 34, 44, 32, 34, 61, 34, 44, 32, 34, 43, 34, 44, 32, 34, 36, 34, 44, 32, 34,
44, 34, 44, 10,125, 10, 10,108,111, 99, 97,108, 32,102,117,110, 99,116,105,111,
110, 32,112,114,111,116,101, 99,116, 95,115,101,103,109,101,110,116, 40,115, 41,
10, 9,114,101,116,117,114,110, 32,115,116,114,105,110,103, 46,103,115,117, 98,
40,115, 44, 32, 34, 40, 91, 94, 65, 45, 90, 97, 45,122, 48, 45, 57, 95, 93, 41,
34, 44, 32,102,117,110, 99,116,105,111,110, 32, 40, 99, 41, 10, 9, 9,105,102,
32,115,101,103,109,101,110,116, 95,115,101,116, 91, 99, 93, 32,116,104,101,110,
32,114,101,116,117,114,110, 32, 99, 10, 9, 9,101,108,115,101, 32,114,101,116,
117,114,110, 32,115,116,114,105,110,103, 46,102,111,114,109, 97,116, 40, 34, 37,
37, 37, 48, 50,120, 34, 44, 32,115,116,114,105,110,103, 46, 98,121,116,101, 40,
99, 41, 41, 32,101,110,100, 10, 9,101,110,100, 41, 10,101,110,100, 10, 10, 45,
45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45,
45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45,
45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45,
45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 10, 45, 45, 32,
69,110, 99,111,100,101,115, 32, 97, 32,115,116,114,105,110,103, 32,105,110,116,
111, 32,105,116,115, 32,101,115, 99, 97,112,101,100, 32,104,101,120, 97,100,101,
99,105,109, 97,108, 32,114,101,112,114,101,115,101,110,116, 97,116,105,111,110,
10, 45, 45, 32, 73,110,112,117,116, 10, 45, 45, 32, 32, 32,115, 58, 32, 98,105,
110, 97,114,121, 32,115,116,114,105,110,103, 32,116,111, 32, 98,101, 32,101,110,
99,111,100,101,100, 10, 45, 45, 32, 82,101,116,117,114,110,115, 10, 45, 45, 32,
32, 32,101,115, 99, 97,112,101,100, 32,114,101,112,114,101,115,101,110,116, 97,
116,105,111,110, 32,111,102, 32,115,116,114,105,110,103, 32, 98,105,110, 97,114,
121, 10, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45,
45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45,
45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45,
45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 10,
102,117,110, 99,116,105,111,110, 32,117,110,101,115, 99, 97,112,101, 40,115, 41,
10, 32, 32, 32, 32,114,101,116,117,114,110, 32,115,116,114,105,110,103, 46,103,
115,117, 98, 40,115, 44, 32, 34, 37, 37, 40, 37,120, 37,120, 41, 34, 44, 32,102,
117,110, 99,116,105,111,110, 40,104,101,120, 41, 10, 32, 32, 32, 32, 32, 32, 32,
32,114,101,116,117,114,110, 32,115,116,114,105,110,103, 46, 99,104, 97,114, 40,
98, 97,115,101, 46,116,111,110,117,109, 98,101,114, 40,104,101,120, 44, 32, 49,
54, 41, 41, 10, 32, 32, 32, 32,101,110,100, 41, 10,101,110,100, 10, 10, 45, 45,
45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45,
45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45,
45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45,
45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 10, 45, 45, 32, 66,
117,105,108,100,115, 32, 97, 32,112, 97,116,104, 32,102,114,111,109, 32, 97, 32,
98, 97,115,101, 32,112, 97,116,104, 32, 97,110,100, 32, 97, 32,114,101,108, 97,
116,105,118,101, 32,112, 97,116,104, 10, 45, 45, 32, 73,110,112,117,116, 10, 45,
45, 32, 32, 32, 98, 97,115,101, 95,112, 97,116,104, 10, 45, 45, 32, 32, 32,114,
101,108, 97,116,105,118,101, 95,112, 97,116,104, 10, 45, 45, 32, 82,101,116,117,
114,110,115, 10, 45, 45, 32, 32, 32, 99,111,114,114,101,115,112,111,110,100,105,
110,103, 32, 97, 98,115,111,108,117,116,101, 32,112, 97,116,104, 10, 45, 45, 45,
45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45,
45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45,
45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45,
45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 10,108,111, 99, 97,108,
32,102,117,110, 99,116,105,111,110, 32, 97, 98,115,111,108,117,116,101, 95,112,
97,116,104, 40, 98, 97,115,101, 95,112, 97,116,104, 44, 32,114,101,108, 97,116,
105,118,101, 95,112, 97,116,104, 41, 10, 32, 32, 32, 32,105,102, 32,115,116,114,
105,110,103, 46,115,117, 98, 40,114,101,108, 97,116,105,118,101, 95,112, 97,116,
104, 44, 32, 49, 44, 32, 49, 41, 32, 61, 61, 32, 34, 47, 34, 32,116,104,101,110,
32,114,101,116,117,114,110, 32,114,101,108, 97,116,105,118,101, 95,112, 97,116,
104, 32,101,110,100, 10, 32, 32, 32, 32,108,111, 99, 97,108, 32,112, 97,116,104,
32, 61, 32,115,116,114,105,110,103, 46,103,115,117, 98, 40, 98, 97,115,101, 95,
112, 97,116,104, 44, 32, 34, 91, 94, 47, 93, 42, 36, 34, 44, 32, 34, 34, 41, 10,
32, 32, 32, 32,112, 97,116,104, 32, 61, 32,112, 97,116,104, 32, 46, 46, 32,114,
101,108, 97,116,105,118,101, 95,112, 97,116,104, 10, 32, 32, 32, 32,112, 97,116,
104, 32, 61, 32,115,116,114,105,110,103, 46,103,115,117, 98, 40,112, 97,116,104,
44, 32, 34, 40, 91, 94, 47, 93, 42, 37, 46, 47, 41, 34, 44, 32,102,117,110, 99,
116,105,111,110, 32, 40,115, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32,105,102, 32,
115, 32,126, 61, 32, 34, 46, 47, 34, 32,116,104,101,110, 32,114,101,116,117,114,
110, 32,115, 32,101,108,115,101, 32,114,101,116,117,114,110, 32, 34, 34, 32,101,
110,100, 10, 32, 32, 32, 32,101,110,100, 41, 10, 32, 32, 32, 32,112, 97,116,104,
32, 61, 32,115,116,114,105,110,103, 46,103,115,117, 98, 40,112, 97,116,104, 44,
32, 34, 47, 37, 46, 36, 34, 44, 32, 34, 47, 34, 41, 10, 32, 32, 32, 32,108,111,
99, 97,108, 32,114,101,100,117, 99,101,100, 10, 32, 32, 32, 32,119,104,105,108,
101, 32,114,101,100,117, 99,101,100, 32,126, 61, 32,112, 97,116,104, 32,100,111,
10, 32, 32, 32, 32, 32, 32, 32, 32,114,101,100,117, 99,101,100, 32, 61, 32,112,
97,116,104, 10, 32, 32, 32, 32, 32, 32, 32, 32,112, 97,116,104, 32, 61, 32,115,
116,114,105,110,103, 46,103,115,117, 98, 40,114,101,100,117, 99,101,100, 44, 32,
34, 40, 91, 94, 47, 93, 42, 47, 37, 46, 37, 46, 47, 41, 34, 44, 32,102,117,110,
99,116,105,111,110, 32, 40,115, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
32, 32,105,102, 32,115, 32,126, 61, 32, 34, 46, 46, 47, 46, 46, 47, 34, 32,116,
104,101,110, 32,114,101,116,117,114,110, 32, 34, 34, 32,101,108,115,101, 32,114,
101,116,117,114,110, 32,115, 32,101,110,100, 10, 32, 32, 32, 32, 32, 32, 32, 32,
101,110,100, 41, 10, 32, 32, 32, 32,101,110,100, 10, 32, 32, 32, 32,112, 97,116,
104, 32, 61, 32,115,116,114,105,110,103, 46,103,115,117, 98, 40,114,101,100,117,
99,101,100, 44, 32, 34, 40, 91, 94, 47, 93, 42, 47, 37, 46, 37, 46, 41, 36, 34,
44, 32,102,117,110, 99,116,105,111,110, 32, 40,115, 41, 10, 32, 32, 32, 32, 32,
32, 32, 32,105,102, 32,115, 32,126, 61, 32, 34, 46, 46, 47, 46, 46, 34, 32,116,
104,101,110, 32,114,101,116,117,114,110, 32, 34, 34, 32,101,108,115,101, 32,114,
101,116,117,114,110, 32,115, 32,101,110,100, 10, 32, 32, 32, 32,101,110,100, 41,
10, 32, 32, 32, 32,114,101,116,117,114,110, 32,112, 97,116,104, 10,101,110,100,
10, 10, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45,
45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45,
45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45,
45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 10,
45, 45, 32, 80, 97,114,115,101,115, 32, 97, 32,117,114,108, 32, 97,110,100, 32,
114,101,116,117,114,110,115, 32, 97, 32,116, 97, 98,108,101, 32,119,105,116,104,
32, 97,108,108, 32,105,116,115, 32,112, 97,114,116,115, 32, 97, 99, 99,111,114,
100,105,110,103, 32,116,111, 32, 82, 70, 67, 32, 50, 51, 57, 54, 10, 45, 45, 32,
84,104,101, 32,102,111,108,108,111,119,105,110,103, 32,103,114, 97,109,109, 97,
114, 32,100,101,115, 99,114,105, 98,101,115, 32,116,104,101, 32,110, 97,109,101,
115, 32,103,105,118,101,110, 32,116,111, 32,116,104,101, 32, 85, 82, 76, 32,112,
97,114,116,115, 10, 45, 45, 32, 60,117,114,108, 62, 32, 58, 58, 61, 32, 60,115,
99,104,101,109,101, 62, 58, 47, 47, 60, 97,117,116,104,111,114,105,116,121, 62,
47, 60,112, 97,116,104, 62, 59, 60,112, 97,114, 97,109,115, 62, 63, 60,113,117,
101,114,121, 62, 35, 60,102,114, 97,103,109,101,110,116, 62, 10, 45, 45, 32, 60,
97,117,116,104,111,114,105,116,121, 62, 32, 58, 58, 61, 32, 60,117,115,101,114,
105,110,102,111, 62, 64, 60,104,111,115,116, 62, 58, 60,112,111,114,116, 62, 10,
45, 45, 32, 60,117,115,101,114,105,110,102,111, 62, 32, 58, 58, 61, 32, 60,117,
115,101,114, 62, 91, 58, 60,112, 97,115,115,119,111,114,100, 62, 93, 10, 45, 45,
32, 60,112, 97,116,104, 62, 32, 58, 58, 32, 61, 32,123, 60,115,101,103,109,101,
110,116, 62, 47,125, 60,115,101,103,109,101,110,116, 62, 10, 45, 45, 32, 73,110,
112,117,116, 10, 45, 45, 32, 32, 32,117,114,108, 58, 32,117,110,105,102,111,114,
109, 32,114,101,115,111,117,114, 99,101, 32,108,111, 99, 97,116,111,114, 32,111,
102, 32,114,101,113,117,101,115,116, 10, 45, 45, 32, 32, 32,100,101,102, 97,117,
108,116, 58, 32,116, 97, 98,108,101, 32,119,105,116,104, 32,100,101,102, 97,117,
108,116, 32,118, 97,108,117,101,115, 32,102,111,114, 32,101, 97, 99,104, 32,102,
105,101,108,100, 10, 45, 45, 32, 82,101,116,117,114,110,115, 10, 45, 45, 32, 32,
32,116, 97, 98,108,101, 32,119,105,116,104, 32,116,104,101, 32,102,111,108,108,
111,119,105,110,103, 32,102,105,101,108,100,115, 44, 32,119,104,101,114,101, 32,
82, 70, 67, 32,110, 97,109,105,110,103, 32, 99,111,110,118,101,110,116,105,111,
110,115, 32,104, 97,118,101, 10, 45, 45, 32, 32, 32, 98,101,101,110, 32,112,114,
101,115,101,114,118,101,100, 58, 10, 45, 45, 32, 32, 32, 32, 32,115, 99,104,101,
109,101, 44, 32, 97,117,116,104,111,114,105,116,121, 44, 32,117,115,101,114,105,
110,102,111, 44, 32,117,115,101,114, 44, 32,112, 97,115,115,119,111,114,100, 44,
32,104,111,115,116, 44, 32,112,111,114,116, 44, 10, 45, 45, 32, 32, 32, 32, 32,
112, 97,116,104, 44, 32,112, 97,114, 97,109,115, 44, 32,113,117,101,114,121, 44,
32,102,114, 97,103,109,101,110,116, 10, 45, 45, 32, 79, 98,115, 58, 10, 45, 45,
32, 32, 32,116,104,101, 32,108,101, 97,100,105,110,103, 32, 39, 47, 39, 32,105,
110, 32,123, 47, 60,112, 97,116,104, 62,125, 32,105,115, 32, 99,111,110,115,105,
100,101,114,101,100, 32,112, 97,114,116, 32,111,102, 32, 60,112, 97,116,104, 62,
10, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45,
45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45,
45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45,
45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 10,102,
117,110, 99,116,105,111,110, 32,112, 97,114,115,101, 40,117,114,108, 44, 32,100,
101,102, 97,117,108,116, 41, 10, 32, 32, 32, 32, 45, 45, 32,105,110,105,116,105,
97,108,105,122,101, 32,100,101,102, 97,117,108,116, 32,112, 97,114, 97,109,101,
116,101,114,115, 10, 32, 32, 32, 32,108,111, 99, 97,108, 32,112, 97,114,115,101,
100, 32, 61, 32,123,125, 10, 32, 32, 32, 32,102,111,114, 32,105, 44,118, 32,105,
110, 32, 98, 97,115,101, 46,112, 97,105,114,115, 40,100,101,102, 97,117,108,116,
32,111,114, 32,112, 97,114,115,101,100, 41, 32,100,111, 32,112, 97,114,115,101,
100, 91,105, 93, 32, 61, 32,118, 32,101,110,100, 10, 32, 32, 32, 32, 45, 45, 32,
101,109,112,116,121, 32,117,114,108, 32,105,115, 32,112, 97,114,115,101,100, 32,
116,111, 32,110,105,108, 10, 32, 32, 32, 32,105,102, 32,110,111,116, 32,117,114,
108, 32,111,114, 32,117,114,108, 32, 61, 61, 32, 34, 34, 32,116,104,101,110, 32,
114,101,116,117,114,110, 32,110,105,108, 44, 32, 34,105,110,118, 97,108,105,100,
32,117,114,108, 34, 32,101,110,100, 10, 32, 32, 32, 32, 45, 45, 32,114,101,109,
111,118,101, 32,119,104,105,116,101,115,112, 97, 99,101, 10, 32, 32, 32, 32, 45,
45, 32,117,114,108, 32, 61, 32,115,116,114,105,110,103, 46,103,115,117, 98, 40,
117,114,108, 44, 32, 34, 37,115, 34, 44, 32, 34, 34, 41, 10, 32, 32, 32, 32, 45,
45, 32,103,101,116, 32,102,114, 97,103,109,101,110,116, 10, 32, 32, 32, 32,117,
114,108, 32, 61, 32,115,116,114,105,110,103, 46,103,115,117, 98, 40,117,114,108,
44, 32, 34, 35, 40, 46, 42, 41, 36, 34, 44, 32,102,117,110, 99,116,105,111,110,
40,102, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32,112, 97,114,115,101,100, 46,102,
114, 97,103,109,101,110,116, 32, 61, 32,102, 10, 32, 32, 32, 32, 32, 32, 32, 32,
114,101,116,117,114,110, 32, 34, 34, 10, 32, 32, 32, 32,101,110,100, 41, 10, 32,
32, 32, 32, 45, 45, 32,103,101,116, 32,115, 99,104,101,109,101, 10, 32, 32, 32,
32,117,114,108, 32, 61, 32,115,116,114,105,110,103, 46,103,115,117, 98, 40,117,
114,108, 44, 32, 34, 94, 40, 91, 37,119, 93, 91, 37,119, 37, 43, 37, 45, 37, 46,
93, 42, 41, 37, 58, 34, 44, 10, 32, 32, 32, 32, 32, 32, 32, 32,102,117,110, 99,
116,105,111,110, 40,115, 41, 32,112, 97,114,115,101,100, 46,115, 99,104,101,109,
101, 32, 61, 32,115, 59, 32,114,101,116,117,114,110, 32, 34, 34, 32,101,110,100,
41, 10, 32, 32, 32, 32, 45, 45, 32,103,101,116, 32, 97,117,116,104,111,114,105,
116,121, 10, 32, 32, 32, 32,117,114,108, 32, 61, 32,115,116,114,105,110,103, 46,
103,115,117, 98, 40,117,114,108, 44, 32, 34, 94, 47, 47, 40, 91, 94, 47, 93, 42,
41, 34, 44, 32,102,117,110, 99,116,105,111,110, 40,110, 41, 10, 32, 32, 32, 32,
32, 32, 32, 32,112, 97,114,115,101,100, 46, 97,117,116,104,111,114,105,116,121,
32, 61, 32,110, 10, 32, 32, 32, 32, 32, 32, 32, 32,114,101,116,117,114,110, 32,
34, 34, 10, 32, 32, 32, 32,101,110,100, 41, 10, 32, 32, 32, 32, 45, 45, 32,103,
101,116, 32,113,117,101,114,121, 32,115,116,114,105,110,103,105,110,103, 10, 32,
32, 32, 32,117,114,108, 32, 61, 32,115,116,114,105,110,103, 46,103,115,117, 98,
40,117,114,108, 44, 32, 34, 37, 63, 40, 46, 42, 41, 34, 44, 32,102,117,110, 99,
116,105,111,110, 40,113, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32,112, 97,114,115,
101,100, 46,113,117,101,114,121, 32, 61, 32,113, 10, 32, 32, 32, 32, 32, 32, 32,
32,114,101,116,117,114,110, 32, 34, 34, 10, 32, 32, 32, 32,101,110,100, 41, 10,
32, 32, 32, 32, 45, 45, 32,103,101,116, 32,112, 97,114, 97,109,115, 10, 32, 32,
32, 32,117,114,108, 32, 61, 32,115,116,114,105,110,103, 46,103,115,117, 98, 40,
117,114,108, 44, 32, 34, 37, 59, 40, 46, 42, 41, 34, 44, 32,102,117,110, 99,116,
105,111,110, 40,112, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32,112, 97,114,115,101,
100, 46,112, 97,114, 97,109,115, 32, 61, 32,112, 10, 32, 32, 32, 32, 32, 32, 32,
32,114,101,116,117,114,110, 32, 34, 34, 10, 32, 32, 32, 32,101,110,100, 41, 10,
32, 32, 32, 32, 45, 45, 32,112, 97,116,104, 32,105,115, 32,119,104, 97,116,101,
118,101,114, 32,119, 97,115, 32,108,101,102,116, 10, 32, 32, 32, 32,105,102, 32,
117,114,108, 32,126, 61, 32, 34, 34, 32,116,104,101,110, 32,112, 97,114,115,101,
100, 46,112, 97,116,104, 32, 61, 32,117,114,108, 32,101,110,100, 10, 32, 32, 32,
32,108,111, 99, 97,108, 32, 97,117,116,104,111,114,105,116,121, 32, 61, 32,112,
97,114,115,101,100, 46, 97,117,116,104,111,114,105,116,121, 10, 32, 32, 32, 32,
105,102, 32,110,111,116, 32, 97,117,116,104,111,114,105,116,121, 32,116,104,101,
110, 32,114,101,116,117,114,110, 32,112, 97,114,115,101,100, 32,101,110,100, 10,
32, 32, 32, 32, 97,117,116,104,111,114,105,116,121, 32, 61, 32,115,116,114,105,
110,103, 46,103,115,117, 98, 40, 97,117,116,104,111,114,105,116,121, 44, 34, 94,
40, 91, 94, 64, 93, 42, 41, 64, 34, 44, 10, 32, 32, 32, 32, 32, 32, 32, 32,102,
117,110, 99,116,105,111,110, 40,117, 41, 32,112, 97,114,115,101,100, 46,117,115,
101,114,105,110,102,111, 32, 61, 32,117, 59, 32,114,101,116,117,114,110, 32, 34,
34, 32,101,110,100, 41, 10, 32, 32, 32, 32, 97,117,116,104,111,114,105,116,121,
32, 61, 32,115,116,114,105,110,103, 46,103,115,117, 98, 40, 97,117,116,104,111,
114,105,116,121, 44, 32, 34, 58, 40, 91, 94, 58, 93, 42, 41, 36, 34, 44, 10, 32,
32, 32, 32, 32, 32, 32, 32,102,117,110, 99,116,105,111,110, 40,112, 41, 32,112,
97,114,115,101,100, 46,112,111,114,116, 32, 61, 32,112, 59, 32,114,101,116,117,
114,110, 32, 34, 34, 32,101,110,100, 41, 10, 32, 32, 32, 32,105,102, 32, 97,117,
116,104,111,114,105,116,121, 32,126, 61, 32, 34, 34, 32,116,104,101,110, 32,112,
97,114,115,101,100, 46,104,111,115,116, 32, 61, 32, 97,117,116,104,111,114,105,
116,121, 32,101,110,100, 10, 32, 32, 32, 32,108,111, 99, 97,108, 32,117,115,101,
114,105,110,102,111, 32, 61, 32,112, 97,114,115,101,100, 46,117,115,101,114,105,
110,102,111, 10, 32, 32, 32, 32,105,102, 32,110,111,116, 32,117,115,101,114,105,
110,102,111, 32,116,104,101,110, 32,114,101,116,117,114,110, 32,112, 97,114,115,
101,100, 32,101,110,100, 10, 32, 32, 32, 32,117,115,101,114,105,110,102,111, 32,
61, 32,115,116,114,105,110,103, 46,103,115,117, 98, 40,117,115,101,114,105,110,
102,111, 44, 32, 34, 58, 40, 91, 94, 58, 93, 42, 41, 36, 34, 44, 10, 32, 32, 32,
32, 32, 32, 32, 32,102,117,110, 99,116,105,111,110, 40,112, 41, 32,112, 97,114,
115,101,100, 46,112, 97,115,115,119,111,114,100, 32, 61, 32,112, 59, 32,114,101,
116,117,114,110, 32, 34, 34, 32,101,110,100, 41, 10, 32, 32, 32, 32,112, 97,114,
115,101,100, 46,117,115,101,114, 32, 61, 32,117,115,101,114,105,110,102,111, 10,
32, 32, 32, 32,114,101,116,117,114,110, 32,112, 97,114,115,101,100, 10,101,110,
100, 10, 10, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45,
45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45,
45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45,
45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45,
10, 45, 45, 32, 82,101, 98,117,105,108,100,115, 32, 97, 32,112, 97,114,115,101,
100, 32, 85, 82, 76, 32,102,114,111,109, 32,105,116,115, 32, 99,111,109,112,111,
110,101,110,116,115, 46, 10, 45, 45, 32, 67,111,109,112,111,110,101,110,116,115,
32, 97,114,101, 32,112,114,111,116,101, 99,116,101,100, 32,105,102, 32, 97,110,
121, 32,114,101,115,101,114,118,101,100, 32,111,114, 32,117,110, 97,108,108,111,
119,101,100, 32, 99,104, 97,114, 97, 99,116,101,114,115, 32, 97,114,101, 32,102,
111,117,110,100, 10, 45, 45, 32, 73,110,112,117,116, 10, 45, 45, 32, 32, 32,112,
97,114,115,101,100, 58, 32,112, 97,114,115,101,100, 32, 85, 82, 76, 44, 32, 97,
115, 32,114,101,116,117,114,110,101,100, 32, 98,121, 32,112, 97,114,115,101, 10,
45, 45, 32, 82,101,116,117,114,110,115, 10, 45, 45, 32, 32, 32, 97, 32,115,116,
114,105,110,103,105,110,103, 32,119,105,116,104, 32,116,104,101, 32, 99,111,114,
114,101,115,112,111,110,100,105,110,103, 32, 85, 82, 76, 10, 45, 45, 45, 45, 45,
45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45,
45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45,
45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45,
45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 10,102,117,110, 99,116,105,111,
110, 32, 98,117,105,108,100, 40,112, 97,114,115,101,100, 41, 10, 32, 32, 32, 32,
108,111, 99, 97,108, 32,112,112, 97,116,104, 32, 61, 32,112, 97,114,115,101, 95,
112, 97,116,104, 40,112, 97,114,115,101,100, 46,112, 97,116,104, 32,111,114, 32,
34, 34, 41, 10, 32, 32, 32, 32,108,111, 99, 97,108, 32,117,114,108, 32, 61, 32,
98,117,105,108,100, 95,112, 97,116,104, 40,112,112, 97,116,104, 41, 10, 32, 32,
32, 32,105,102, 32,112, 97,114,115,101,100, 46,112, 97,114, 97,109,115, 32,116,
104,101,110, 32,117,114,108, 32, 61, 32,117,114,108, 32, 46, 46, 32, 34, 59, 34,
32, 46, 46, 32,112, 97,114,115,101,100, 46,112, 97,114, 97,109,115, 32,101,110,
100, 10, 32, 32, 32, 32,105,102, 32,112, 97,114,115,101,100, 46,113,117,101,114,
121, 32,116,104,101,110, 32,117,114,108, 32, 61, 32,117,114,108, 32, 46, 46, 32,
34, 63, 34, 32, 46, 46, 32,112, 97,114,115,101,100, 46,113,117,101,114,121, 32,
101,110,100, 10, 9,108,111, 99, 97,108, 32, 97,117,116,104,111,114,105,116,121,
32, 61, 32,112, 97,114,115,101,100, 46, 97,117,116,104,111,114,105,116,121, 10,
9,105,102, 32,112, 97,114,115,101,100, 46,104,111,115,116, 32,116,104,101,110,
10, 9, 9, 97,117,116,104,111,114,105,116,121, 32, 61, 32,112, 97,114,115,101,
100, 46,104,111,115,116, 10, 9, 9,105,102, 32,112, 97,114,115,101,100, 46,112,
111,114,116, 32,116,104,101,110, 32, 97,117,116,104,111,114,105,116,121, 32, 61,
32, 97,117,116,104,111,114,105,116,121, 32, 46, 46, 32, 34, 58, 34, 32, 46, 46,
32,112, 97,114,115,101,100, 46,112,111,114,116, 32,101,110,100, 10, 9, 9,108,
111, 99, 97,108, 32,117,115,101,114,105,110,102,111, 32, 61, 32,112, 97,114,115,
101,100, 46,117,115,101,114,105,110,102,111, 10, 9, 9,105,102, 32,112, 97,114,
115,101,100, 46,117,115,101,114, 32,116,104,101,110, 10, 9, 9, 9,117,115,101,
114,105,110,102,111, 32, 61, 32,112, 97,114,115,101,100, 46,117,115,101,114, 10,
9, 9, 9,105,102, 32,112, 97,114,115,101,100, 46,112, 97,115,115,119,111,114,
100, 32,116,104,101,110, 10, 9, 9, 9, 9,117,115,101,114,105,110,102,111, 32,
61, 32,117,115,101,114,105,110,102,111, 32, 46, 46, 32, 34, 58, 34, 32, 46, 46,
32,112, 97,114,115,101,100, 46,112, 97,115,115,119,111,114,100, 10, 9, 9, 9,
101,110,100, 10, 9, 9,101,110,100, 10, 9, 9,105,102, 32,117,115,101,114,105,
110,102,111, 32,116,104,101,110, 32, 97,117,116,104,111,114,105,116,121, 32, 61,
32,117,115,101,114,105,110,102,111, 32, 46, 46, 32, 34, 64, 34, 32, 46, 46, 32,
97,117,116,104,111,114,105,116,121, 32,101,110,100, 10, 9,101,110,100, 10, 32,
32, 32, 32,105,102, 32, 97,117,116,104,111,114,105,116,121, 32,116,104,101,110,
32,117,114,108, 32, 61, 32, 34, 47, 47, 34, 32, 46, 46, 32, 97,117,116,104,111,
114,105,116,121, 32, 46, 46, 32,117,114,108, 32,101,110,100, 10, 32, 32, 32, 32,
105,102, 32,112, 97,114,115,101,100, 46,115, 99,104,101,109,101, 32,116,104,101,
110, 32,117,114,108, 32, 61, 32,112, 97,114,115,101,100, 46,115, 99,104,101,109,
101, 32, 46, 46, 32, 34, 58, 34, 32, 46, 46, 32,117,114,108, 32,101,110,100, 10,
32, 32, 32, 32,105,102, 32,112, 97,114,115,101,100, 46,102,114, 97,103,109,101,
110,116, 32,116,104,101,110, 32,117,114,108, 32, 61, 32,117,114,108, 32, 46, 46,
32, 34, 35, 34, 32, 46, 46, 32,112, 97,114,115,101,100, 46,102,114, 97,103,109,
101,110,116, 32,101,110,100, 10, 32, 32, 32, 32, 45, 45, 32,117,114,108, 32, 61,
32,115,116,114,105,110,103, 46,103,115,117, 98, 40,117,114,108, 44, 32, 34, 37,
115, 34, 44, 32, 34, 34, 41, 10, 32, 32, 32, 32,114,101,116,117,114,110, 32,117,
114,108, 10,101,110,100, 10, 10, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45,
45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45,
45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45,
45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45,
45, 45, 45, 45, 45, 10, 45, 45, 32, 66,117,105,108,100,115, 32, 97, 32, 97, 98,
115,111,108,117,116,101, 32, 85, 82, 76, 32,102,114,111,109, 32, 97, 32, 98, 97,
115,101, 32, 97,110,100, 32, 97, 32,114,101,108, 97,116,105,118,101, 32, 85, 82,
76, 32, 97, 99, 99,111,114,100,105,110,103, 32,116,111, 32, 82, 70, 67, 32, 50,
51, 57, 54, 10, 45, 45, 32, 73,110,112,117,116, 10, 45, 45, 32, 32, 32, 98, 97,
115,101, 95,117,114,108, 10, 45, 45, 32, 32, 32,114,101,108, 97,116,105,118,101,
95,117,114,108, 10, 45, 45, 32, 82,101,116,117,114,110,115, 10, 45, 45, 32, 32,
32, 99,111,114,114,101,115,112,111,110,100,105,110,103, 32, 97, 98,115,111,108,
117,116,101, 32,117,114,108, 10, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45,
45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45,
45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45,
45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45,
45, 45, 45, 45, 45, 10,102,117,110, 99,116,105,111,110, 32, 97, 98,115,111,108,
117,116,101, 40, 98, 97,115,101, 95,117,114,108, 44, 32,114,101,108, 97,116,105,
118,101, 95,117,114,108, 41, 10, 32, 32, 32, 32,105,102, 32, 98, 97,115,101, 46,
116,121,112,101, 40, 98, 97,115,101, 95,117,114,108, 41, 32, 61, 61, 32, 34,116,
97, 98,108,101, 34, 32,116,104,101,110, 10, 32, 32, 32, 32, 32, 32, 32, 32, 98,
97,115,101, 95,112, 97,114,115,101,100, 32, 61, 32, 98, 97,115,101, 95,117,114,
108, 10, 32, 32, 32, 32, 32, 32, 32, 32, 98, 97,115,101, 95,117,114,108, 32, 61,
32, 98,117,105,108,100, 40, 98, 97,115,101, 95,112, 97,114,115,101,100, 41, 10,
32, 32, 32, 32,101,108,115,101, 10, 32, 32, 32, 32, 32, 32, 32, 32, 98, 97,115,
101, 95,112, 97,114,115,101,100, 32, 61, 32,112, 97,114,115,101, 40, 98, 97,115,
101, 95,117,114,108, 41, 10, 32, 32, 32, 32,101,110,100, 10, 32, 32, 32, 32,108,
111, 99, 97,108, 32,114,101,108, 97,116,105,118,101, 95,112, 97,114,115,101,100,
32, 61, 32,112, 97,114,115,101, 40,114,101,108, 97,116,105,118,101, 95,117,114,
108, 41, 10, 32, 32, 32, 32,105,102, 32,110,111,116, 32, 98, 97,115,101, 95,112,
97,114,115,101,100, 32,116,104,101,110, 32,114,101,116,117,114,110, 32,114,101,
108, 97,116,105,118,101, 95,117,114,108, 10, 32, 32, 32, 32,101,108,115,101,105,
102, 32,110,111,116, 32,114,101,108, 97,116,105,118,101, 95,112, 97,114,115,101,
100, 32,116,104,101,110, 32,114,101,116,117,114,110, 32, 98, 97,115,101, 95,117,
114,108, 10, 32, 32, 32, 32,101,108,115,101,105,102, 32,114,101,108, 97,116,105,
118,101, 95,112, 97,114,115,101,100, 46,115, 99,104,101,109,101, 32,116,104,101,
110, 32,114,101,116,117,114,110, 32,114,101,108, 97,116,105,118,101, 95,117,114,
108, 10, 32, 32, 32, 32,101,108,115,101, 10, 32, 32, 32, 32, 32, 32, 32, 32,114,
101,108, 97,116,105,118,101, 95,112, 97,114,115,101,100, 46,115, 99,104,101,109,
101, 32, 61, 32, 98, 97,115,101, 95,112, 97,114,115,101,100, 46,115, 99,104,101,
109,101, 10, 32, 32, 32, 32, 32, 32, 32, 32,105,102, 32,110,111,116, 32,114,101,
108, 97,116,105,118,101, 95,112, 97,114,115,101,100, 46, 97,117,116,104,111,114,
105,116,121, 32,116,104,101,110, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
32,114,101,108, 97,116,105,118,101, 95,112, 97,114,115,101,100, 46, 97,117,116,
104,111,114,105,116,121, 32, 61, 32, 98, 97,115,101, 95,112, 97,114,115,101,100,
46, 97,117,116,104,111,114,105,116,121, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32,
32, 32, 32,105,102, 32,110,111,116, 32,114,101,108, 97,116,105,118,101, 95,112,
97,114,115,101,100, 46,112, 97,116,104, 32,116,104,101,110, 10, 32, 32, 32, 32,
32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,114,101,108, 97,116,105,118,101,
95,112, 97,114,115,101,100, 46,112, 97,116,104, 32, 61, 32, 98, 97,115,101, 95,
112, 97,114,115,101,100, 46,112, 97,116,104, 10, 32, 32, 32, 32, 32, 32, 32, 32,
32, 32, 32, 32, 32, 32, 32, 32,105,102, 32,110,111,116, 32,114,101,108, 97,116,
105,118,101, 95,112, 97,114,115,101,100, 46,112, 97,114, 97,109,115, 32,116,104,
101,110, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
32, 32, 32,114,101,108, 97,116,105,118,101, 95,112, 97,114,115,101,100, 46,112,
97,114, 97,109,115, 32, 61, 32, 98, 97,115,101, 95,112, 97,114,115,101,100, 46,
112, 97,114, 97,109,115, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
32, 32, 32, 32, 32, 32, 32,105,102, 32,110,111,116, 32,114,101,108, 97,116,105,
118,101, 95,112, 97,114,115,101,100, 46,113,117,101,114,121, 32,116,104,101,110,
10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
32, 32, 32, 32, 32,114,101,108, 97,116,105,118,101, 95,112, 97,114,115,101,100,
46,113,117,101,114,121, 32, 61, 32, 98, 97,115,101, 95,112, 97,114,115,101,100,
46,113,117,101,114,121, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
32, 32, 32, 32, 32, 32, 32,101,110,100, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32,
32, 32, 32, 32, 32, 32, 32,101,110,100, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32,
32, 32, 32,101,108,115,101, 32, 32, 32, 32, 10, 32, 32, 32, 32, 32, 32, 32, 32,
32, 32, 32, 32, 32, 32, 32, 32,114,101,108, 97,116,105,118,101, 95,112, 97,114,
115,101,100, 46,112, 97,116,104, 32, 61, 32, 97, 98,115,111,108,117,116,101, 95,
112, 97,116,104, 40, 98, 97,115,101, 95,112, 97,114,115,101,100, 46,112, 97,116,
104, 32,111,114, 32, 34, 34, 44, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
32, 32, 32, 32, 32, 32, 32, 32, 32,114,101,108, 97,116,105,118,101, 95,112, 97,
114,115,101,100, 46,112, 97,116,104, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32,
32, 32, 32,101,110,100, 10, 32, 32, 32, 32, 32, 32, 32, 32,101,110,100, 10, 32,
32, 32, 32, 32, 32, 32, 32,114,101,116,117,114,110, 32, 98,117,105,108,100, 40,
114,101,108, 97,116,105,118,101, 95,112, 97,114,115,101,100, 41, 10, 32, 32, 32,
32,101,110,100, 10,101,110,100, 10, 10, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45,
45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45,
45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45,
45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45,
45, 45, 45, 45, 45, 45, 45, 10, 45, 45, 32, 66,114,101, 97,107,115, 32, 97, 32,
112, 97,116,104, 32,105,110,116,111, 32,105,116,115, 32,115,101,103,109,101,110,
116,115, 44, 32,117,110,101,115, 99, 97,112,105,110,103, 32,116,104,101, 32,115,
101,103,109,101,110,116,115, 10, 45, 45, 32, 73,110,112,117,116, 10, 45, 45, 32,
32, 32,112, 97,116,104, 10, 45, 45, 32, 82,101,116,117,114,110,115, 10, 45, 45,
32, 32, 32,115,101,103,109,101,110,116, 58, 32, 97, 32,116, 97, 98,108,101, 32,
119,105,116,104, 32,111,110,101, 32,101,110,116,114,121, 32,112,101,114, 32,115,
101,103,109,101,110,116, 10, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45,
45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45,
45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45,
45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45,
45, 45, 45, 45, 10,102,117,110, 99,116,105,111,110, 32,112, 97,114,115,101, 95,
112, 97,116,104, 40,112, 97,116,104, 41, 10, 9,108,111, 99, 97,108, 32,112, 97,
114,115,101,100, 32, 61, 32,123,125, 10, 9,112, 97,116,104, 32, 61, 32,112, 97,
116,104, 32,111,114, 32, 34, 34, 10, 9, 45, 45,112, 97,116,104, 32, 61, 32,115,
116,114,105,110,103, 46,103,115,117, 98, 40,112, 97,116,104, 44, 32, 34, 37,115,
34, 44, 32, 34, 34, 41, 10, 9,115,116,114,105,110,103, 46,103,115,117, 98, 40,
112, 97,116,104, 44, 32, 34, 40, 91, 94, 47, 93, 43, 41, 34, 44, 32,102,117,110,
99,116,105,111,110, 32, 40,115, 41, 32,116, 97, 98,108,101, 46,105,110,115,101,
114,116, 40,112, 97,114,115,101,100, 44, 32,115, 41, 32,101,110,100, 41, 10, 9,
102,111,114, 32,105, 32, 61, 32, 49, 44, 32,116, 97, 98,108,101, 46,103,101,116,
110, 40,112, 97,114,115,101,100, 41, 32,100,111, 10, 9, 9,112, 97,114,115,101,
100, 91,105, 93, 32, 61, 32,117,110,101,115, 99, 97,112,101, 40,112, 97,114,115,
101,100, 91,105, 93, 41, 10, 9,101,110,100, 10, 9,105,102, 32,115,116,114,105,
110,103, 46,115,117, 98, 40,112, 97,116,104, 44, 32, 49, 44, 32, 49, 41, 32, 61,
61, 32, 34, 47, 34, 32,116,104,101,110, 32,112, 97,114,115,101,100, 46,105,115,
95, 97, 98,115,111,108,117,116,101, 32, 61, 32, 49, 32,101,110,100, 10, 9,105,
102, 32,115,116,114,105,110,103, 46,115,117, 98, 40,112, 97,116,104, 44, 32, 45,
49, 44, 32, 45, 49, 41, 32, 61, 61, 32, 34, 47, 34, 32,116,104,101,110, 32,112,
97,114,115,101,100, 46,105,115, 95,100,105,114,101, 99,116,111,114,121, 32, 61,
32, 49, 32,101,110,100, 10, 9,114,101,116,117,114,110, 32,112, 97,114,115,101,
100, 10,101,110,100, 10, 10, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45,
45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45,
45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45,
45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45,
45, 45, 45, 45, 10, 45, 45, 32, 66,117,105,108,100,115, 32, 97, 32,112, 97,116,
104, 32, 99,111,109,112,111,110,101,110,116, 32,102,114,111,109, 32,105,116,115,
32,115,101,103,109,101,110,116,115, 44, 32,101,115, 99, 97,112,105,110,103, 32,
112,114,111,116,101, 99,116,101,100, 32, 99,104, 97,114, 97, 99,116,101,114,115,
46, 10, 45, 45, 32, 73,110,112,117,116, 10, 45, 45, 32, 32, 32,112, 97,114,115,
101,100, 58, 32,112, 97,116,104, 32,115,101,103,109,101,110,116,115, 10, 45, 45,
32, 32, 32,117,110,115, 97,102,101, 58, 32,105,102, 32,116,114,117,101, 44, 32,
115,101,103,109,101,110,116,115, 32, 97,114,101, 32,110,111,116, 32,112,114,111,
116,101, 99,116,101,100, 32, 98,101,102,111,114,101, 32,112, 97,116,104, 32,105,
115, 32, 98,117,105,108,116, 10, 45, 45, 32, 82,101,116,117,114,110,115, 10, 45,
45, 32, 32, 32,112, 97,116,104, 58, 32, 99,111,114,114,101,115,112,111,110,100,
105,110,103, 32,112, 97,116,104, 32,115,116,114,105,110,103,105,110,103, 10, 45,
45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45,
45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45,
45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45,
45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 10,102,117,110,
99,116,105,111,110, 32, 98,117,105,108,100, 95,112, 97,116,104, 40,112, 97,114,
115,101,100, 44, 32,117,110,115, 97,102,101, 41, 10, 9,108,111, 99, 97,108, 32,
112, 97,116,104, 32, 61, 32, 34, 34, 10, 9,108,111, 99, 97,108, 32,110, 32, 61,
32,116, 97, 98,108,101, 46,103,101,116,110, 40,112, 97,114,115,101,100, 41, 10,
9,105,102, 32,117,110,115, 97,102,101, 32,116,104,101,110, 10, 9, 9,102,111,
114, 32,105, 32, 61, 32, 49, 44, 32,110, 45, 49, 32,100,111, 10, 9, 9, 9,112,
97,116,104, 32, 61, 32,112, 97,116,104, 32, 46, 46, 32,112, 97,114,115,101,100,
91,105, 93, 10, 9, 9, 9,112, 97,116,104, 32, 61, 32,112, 97,116,104, 32, 46,
46, 32, 34, 47, 34, 10, 9, 9,101,110,100, 10, 9, 9,105,102, 32,110, 32, 62,
32, 48, 32,116,104,101,110, 10, 9, 9, 9,112, 97,116,104, 32, 61, 32,112, 97,
116,104, 32, 46, 46, 32,112, 97,114,115,101,100, 91,110, 93, 10, 9, 9, 9,105,
102, 32,112, 97,114,115,101,100, 46,105,115, 95,100,105,114,101, 99,116,111,114,
121, 32,116,104,101,110, 32,112, 97,116,104, 32, 61, 32,112, 97,116,104, 32, 46,
46, 32, 34, 47, 34, 32,101,110,100, 10, 9, 9,101,110,100, 10, 9,101,108,115,
101, 10, 9, 9,102,111,114, 32,105, 32, 61, 32, 49, 44, 32,110, 45, 49, 32,100,
111, 10, 9, 9, 9,112, 97,116,104, 32, 61, 32,112, 97,116,104, 32, 46, 46, 32,
112,114,111,116,101, 99,116, 95,115,101,103,109,101,110,116, 40,112, 97,114,115,
101,100, 91,105, 93, 41, 10, 9, 9, 9,112, 97,116,104, 32, 61, 32,112, 97,116,
104, 32, 46, 46, 32, 34, 47, 34, 10, 9, 9,101,110,100, 10, 9, 9,105,102, 32,
110, 32, 62, 32, 48, 32,116,104,101,110, 10, 9, 9, 9,112, 97,116,104, 32, 61,
32,112, 97,116,104, 32, 46, 46, 32,112,114,111,116,101, 99,116, 95,115,101,103,
109,101,110,116, 40,112, 97,114,115,101,100, 91,110, 93, 41, 10, 9, 9, 9,105,
102, 32,112, 97,114,115,101,100, 46,105,115, 95,100,105,114,101, 99,116,111,114,
121, 32,116,104,101,110, 32,112, 97,116,104, 32, 61, 32,112, 97,116,104, 32, 46,
46, 32, 34, 47, 34, 32,101,110,100, 10, 9, 9,101,110,100, 10, 9,101,110,100,
10, 9,105,102, 32,112, 97,114,115,101,100, 46,105,115, 95, 97, 98,115,111,108,
117,116,101, 32,116,104,101,110, 32,112, 97,116,104, 32, 61, 32, 34, 47, 34, 32,
46, 46, 32,112, 97,116,104, 32,101,110,100, 10, 9,114,101,116,117,114,110, 32,
112, 97,116,104, 10,101,110,100, 10,
};
if (luaL_loadbuffer(L,(const char*)B1,sizeof(B1),"url.lua")==0) lua_call(L, 0, 0);
}
@@ -0,0 +1,370 @@
/*=========================================================================*\
* Socket compatibilization module for Unix
* LuaSocket toolkit
*
* The code is now interrupt-safe.
* The penalty of calling select to avoid busy-wait is only paid when
* the I/O call fail in the first place.
*
* RCS ID: $Id: usocket.c,v 1.38 2007/10/13 23:55:20 diego Exp $
\*=========================================================================*/
#include <string.h>
#include <signal.h>
#include "socket.h"
/*-------------------------------------------------------------------------*\
* Wait for readable/writable/connected socket with timeout
\*-------------------------------------------------------------------------*/
#ifdef SOCKET_POLL
#include <sys/poll.h>
#define WAITFD_R POLLIN
#define WAITFD_W POLLOUT
#define WAITFD_C (POLLIN|POLLOUT)
int socket_waitfd(p_socket ps, int sw, p_timeout tm) {
int ret;
struct pollfd pfd;
pfd.fd = *ps;
pfd.events = sw;
pfd.revents = 0;
if (timeout_iszero(tm)) return IO_TIMEOUT; /* optimize timeout == 0 case */
do {
int t = (int)(timeout_getretry(tm)*1e3);
ret = poll(&pfd, 1, t >= 0? t: -1);
} while (ret == -1 && errno == EINTR);
if (ret == -1) return errno;
if (ret == 0) return IO_TIMEOUT;
if (sw == WAITFD_C && (pfd.revents & (POLLIN|POLLERR))) return IO_CLOSED;
return IO_DONE;
}
#else
#define WAITFD_R 1
#define WAITFD_W 2
#define WAITFD_C (WAITFD_R|WAITFD_W)
int socket_waitfd(p_socket ps, int sw, p_timeout tm) {
int ret;
fd_set rfds, wfds, *rp, *wp;
struct timeval tv, *tp;
double t;
if (timeout_iszero(tm)) return IO_TIMEOUT; /* optimize timeout == 0 case */
do {
/* must set bits within loop, because select may have modifed them */
rp = wp = NULL;
if (sw & WAITFD_R) { FD_ZERO(&rfds); FD_SET(*ps, &rfds); rp = &rfds; }
if (sw & WAITFD_W) { FD_ZERO(&wfds); FD_SET(*ps, &wfds); wp = &wfds; }
t = timeout_getretry(tm);
tp = NULL;
if (t >= 0.0) {
tv.tv_sec = (int)t;
tv.tv_usec = (int)((t-tv.tv_sec)*1.0e6);
tp = &tv;
}
ret = select(*ps+1, rp, wp, NULL, tp);
} while (ret == -1 && errno == EINTR);
if (ret == -1) return errno;
if (ret == 0) return IO_TIMEOUT;
if (sw == WAITFD_C && FD_ISSET(*ps, &rfds)) return IO_CLOSED;
return IO_DONE;
}
#endif
/*-------------------------------------------------------------------------*\
* Initializes module
\*-------------------------------------------------------------------------*/
int socket_open(void) {
/* instals a handler to ignore sigpipe or it will crash us */
signal(SIGPIPE, SIG_IGN);
return 1;
}
/*-------------------------------------------------------------------------*\
* Close module
\*-------------------------------------------------------------------------*/
int socket_close(void) {
return 1;
}
/*-------------------------------------------------------------------------*\
* Close and inutilize socket
\*-------------------------------------------------------------------------*/
void socket_destroy(p_socket ps) {
if (*ps != SOCKET_INVALID) {
socket_setblocking(ps);
close(*ps);
*ps = SOCKET_INVALID;
}
}
/*-------------------------------------------------------------------------*\
* Select with timeout control
\*-------------------------------------------------------------------------*/
int socket_select(t_socket n, fd_set *rfds, fd_set *wfds, fd_set *efds,
p_timeout tm) {
int ret;
do {
struct timeval tv;
double t = timeout_getretry(tm);
tv.tv_sec = (int) t;
tv.tv_usec = (int) ((t - tv.tv_sec) * 1.0e6);
/* timeout = 0 means no wait */
ret = select(n, rfds, wfds, efds, t >= 0.0 ? &tv: NULL);
} while (ret < 0 && errno == EINTR);
return ret;
}
/*-------------------------------------------------------------------------*\
* Creates and sets up a socket
\*-------------------------------------------------------------------------*/
int socket_create(p_socket ps, int domain, int type, int protocol) {
*ps = socket(domain, type, protocol);
if (*ps != SOCKET_INVALID) return IO_DONE;
else return errno;
}
/*-------------------------------------------------------------------------*\
* Binds or returns error message
\*-------------------------------------------------------------------------*/
int socket_bind(p_socket ps, SA *addr, socklen_t len) {
int err = IO_DONE;
socket_setblocking(ps);
if (bind(*ps, addr, len) < 0) err = errno;
socket_setnonblocking(ps);
return err;
}
/*-------------------------------------------------------------------------*\
*
\*-------------------------------------------------------------------------*/
int socket_listen(p_socket ps, int backlog) {
int err = IO_DONE;
socket_setblocking(ps);
if (listen(*ps, backlog)) err = errno;
socket_setnonblocking(ps);
return err;
}
/*-------------------------------------------------------------------------*\
*
\*-------------------------------------------------------------------------*/
void socket_shutdown(p_socket ps, int how) {
socket_setblocking(ps);
shutdown(*ps, how);
socket_setnonblocking(ps);
}
/*-------------------------------------------------------------------------*\
* Connects or returns error message
\*-------------------------------------------------------------------------*/
int socket_connect(p_socket ps, SA *addr, socklen_t len, p_timeout tm) {
int err;
/* avoid calling on closed sockets */
if (*ps == SOCKET_INVALID) return IO_CLOSED;
/* call connect until done or failed without being interrupted */
do if (connect(*ps, addr, len) == 0) return IO_DONE;
while ((err = errno) == EINTR);
/* if connection failed immediately, return error code */
if (err != EINPROGRESS && err != EAGAIN) return err;
/* zero timeout case optimization */
if (timeout_iszero(tm)) return IO_TIMEOUT;
/* wait until we have the result of the connection attempt or timeout */
err = socket_waitfd(ps, WAITFD_C, tm);
if (err == IO_CLOSED) {
if (recv(*ps, (char *) &err, 0, 0) == 0) return IO_DONE;
else return errno;
} else return err;
}
/*-------------------------------------------------------------------------*\
* Accept with timeout
\*-------------------------------------------------------------------------*/
int socket_accept(p_socket ps, p_socket pa, SA *addr, socklen_t *len, p_timeout tm) {
SA daddr;
socklen_t dlen = sizeof(daddr);
if (*ps == SOCKET_INVALID) return IO_CLOSED;
if (!addr) addr = &daddr;
if (!len) len = &dlen;
for ( ;; ) {
int err;
if ((*pa = accept(*ps, addr, len)) != SOCKET_INVALID) return IO_DONE;
err = errno;
if (err == EINTR) continue;
if (err != EAGAIN && err != ECONNABORTED) return err;
if ((err = socket_waitfd(ps, WAITFD_R, tm)) != IO_DONE) return err;
}
/* can't reach here */
return IO_UNKNOWN;
}
/*-------------------------------------------------------------------------*\
* Send with timeout
\*-------------------------------------------------------------------------*/
int socket_send(p_socket ps, const char *data, size_t count,
size_t *sent, p_timeout tm)
{
int err;
*sent = 0;
/* avoid making system calls on closed sockets */
if (*ps == SOCKET_INVALID) return IO_CLOSED;
/* loop until we send something or we give up on error */
for ( ;; ) {
long put = (long) send(*ps, data, count, 0);
/* if we sent anything, we are done */
if (put > 0) {
*sent = put;
return IO_DONE;
}
err = errno;
/* send can't really return 0, but EPIPE means the connection was
closed */
if (put == 0 || err == EPIPE) return IO_CLOSED;
/* we call was interrupted, just try again */
if (err == EINTR) continue;
/* if failed fatal reason, report error */
if (err != EAGAIN) return err;
/* wait until we can send something or we timeout */
if ((err = socket_waitfd(ps, WAITFD_W, tm)) != IO_DONE) return err;
}
/* can't reach here */
return IO_UNKNOWN;
}
/*-------------------------------------------------------------------------*\
* Sendto with timeout
\*-------------------------------------------------------------------------*/
int socket_sendto(p_socket ps, const char *data, size_t count, size_t *sent,
SA *addr, socklen_t len, p_timeout tm)
{
int err;
*sent = 0;
if (*ps == SOCKET_INVALID) return IO_CLOSED;
for ( ;; ) {
long put = (long) sendto(*ps, data, count, 0, addr, len);
if (put > 0) {
*sent = put;
return IO_DONE;
}
err = errno;
if (put == 0 || err == EPIPE) return IO_CLOSED;
if (err == EINTR) continue;
if (err != EAGAIN) return err;
if ((err = socket_waitfd(ps, WAITFD_W, tm)) != IO_DONE) return err;
}
return IO_UNKNOWN;
}
/*-------------------------------------------------------------------------*\
* Receive with timeout
\*-------------------------------------------------------------------------*/
int socket_recv(p_socket ps, char *data, size_t count, size_t *got, p_timeout tm) {
int err;
*got = 0;
if (*ps == SOCKET_INVALID) return IO_CLOSED;
for ( ;; ) {
long taken = (long) recv(*ps, data, count, 0);
if (taken > 0) {
*got = taken;
return IO_DONE;
}
err = errno;
if (taken == 0) return IO_CLOSED;
if (err == EINTR) continue;
if (err != EAGAIN) return err;
if ((err = socket_waitfd(ps, WAITFD_R, tm)) != IO_DONE) return err;
}
return IO_UNKNOWN;
}
/*-------------------------------------------------------------------------*\
* Recvfrom with timeout
\*-------------------------------------------------------------------------*/
int socket_recvfrom(p_socket ps, char *data, size_t count, size_t *got,
SA *addr, socklen_t *len, p_timeout tm) {
int err;
*got = 0;
if (*ps == SOCKET_INVALID) return IO_CLOSED;
for ( ;; ) {
long taken = (long) recvfrom(*ps, data, count, 0, addr, len);
if (taken > 0) {
*got = taken;
return IO_DONE;
}
err = errno;
if (taken == 0) return IO_CLOSED;
if (err == EINTR) continue;
if (err != EAGAIN) return err;
if ((err = socket_waitfd(ps, WAITFD_R, tm)) != IO_DONE) return err;
}
return IO_UNKNOWN;
}
/*-------------------------------------------------------------------------*\
* Put socket into blocking mode
\*-------------------------------------------------------------------------*/
void socket_setblocking(p_socket ps) {
int flags = fcntl(*ps, F_GETFL, 0);
flags &= (~(O_NONBLOCK));
fcntl(*ps, F_SETFL, flags);
}
/*-------------------------------------------------------------------------*\
* Put socket into non-blocking mode
\*-------------------------------------------------------------------------*/
void socket_setnonblocking(p_socket ps) {
int flags = fcntl(*ps, F_GETFL, 0);
flags |= O_NONBLOCK;
fcntl(*ps, F_SETFL, flags);
}
/*-------------------------------------------------------------------------*\
* DNS helpers
\*-------------------------------------------------------------------------*/
int socket_gethostbyaddr(const char *addr, socklen_t len, struct hostent **hp) {
*hp = gethostbyaddr(addr, len, AF_INET);
if (*hp) return IO_DONE;
else if (h_errno) return h_errno;
else if (errno) return errno;
else return IO_UNKNOWN;
}
int socket_gethostbyname(const char *addr, struct hostent **hp) {
*hp = gethostbyname(addr);
if (*hp) return IO_DONE;
else if (h_errno) return h_errno;
else if (errno) return errno;
else return IO_UNKNOWN;
}
/*-------------------------------------------------------------------------*\
* Error translation functions
* Make sure important error messages are standard
\*-------------------------------------------------------------------------*/
const char *socket_hoststrerror(int err) {
if (err <= 0) return io_strerror(err);
switch (err) {
case HOST_NOT_FOUND: return "host not found";
default: return hstrerror(err);
}
}
const char *socket_strerror(int err) {
if (err <= 0) return io_strerror(err);
switch (err) {
case EADDRINUSE: return "address already in use";
case EISCONN: return "already connected";
case EACCES: return "permission denied";
case ECONNREFUSED: return "connection refused";
case ECONNABORTED: return "closed";
case ECONNRESET: return "closed";
case ETIMEDOUT: return "timeout";
default: return strerror(errno);
}
}
const char *socket_ioerror(p_socket ps, int err) {
(void) ps;
return socket_strerror(err);
}
@@ -0,0 +1,40 @@
#ifndef USOCKET_H
#define USOCKET_H
/*=========================================================================*\
* Socket compatibilization module for Unix
* LuaSocket toolkit
*
* RCS ID: $Id: usocket.h,v 1.7 2005/10/07 04:40:59 diego Exp $
\*=========================================================================*/
/*=========================================================================*\
* BSD include files
\*=========================================================================*/
/* error codes */
#include <errno.h>
/* close function */
#include <unistd.h>
/* fnctnl function and associated constants */
#include <fcntl.h>
/* struct sockaddr */
#include <sys/types.h>
/* socket function */
#include <sys/socket.h>
/* struct timeval */
#include <sys/time.h>
/* gethostbyname and gethostbyaddr functions */
#include <netdb.h>
/* sigpipe handling */
#include <signal.h>
/* IP stuff*/
#include <netinet/in.h>
#include <arpa/inet.h>
/* TCP options (nagle algorithm disable) */
#include <netinet/tcp.h>
typedef int t_socket;
typedef t_socket *p_socket;
#define SOCKET_INVALID (-1)
#endif /* USOCKET_H */
@@ -0,0 +1,401 @@
/*=========================================================================*\
* Socket compatibilization module for Win32
* LuaSocket toolkit
*
* The penalty of calling select to avoid busy-wait is only paid when
* the I/O call fail in the first place.
*
* RCS ID: $Id: wsocket.c,v 1.36 2007/06/11 23:44:54 diego Exp $
\*=========================================================================*/
#include <string.h>
#include "socket.h"
/* WinSock doesn't have a strerror... */
static const char *wstrerror(int err);
/*-------------------------------------------------------------------------*\
* Initializes module
\*-------------------------------------------------------------------------*/
int socket_open(void) {
WSADATA wsaData;
WORD wVersionRequested = MAKEWORD(2, 0);
int err = WSAStartup(wVersionRequested, &wsaData );
if (err != 0) return 0;
if ((LOBYTE(wsaData.wVersion) != 2 || HIBYTE(wsaData.wVersion) != 0) &&
(LOBYTE(wsaData.wVersion) != 1 || HIBYTE(wsaData.wVersion) != 1)) {
WSACleanup();
return 0;
}
return 1;
}
/*-------------------------------------------------------------------------*\
* Close module
\*-------------------------------------------------------------------------*/
int socket_close(void) {
WSACleanup();
return 1;
}
/*-------------------------------------------------------------------------*\
* Wait for readable/writable/connected socket with timeout
\*-------------------------------------------------------------------------*/
#define WAITFD_R 1
#define WAITFD_W 2
#define WAITFD_E 4
#define WAITFD_C (WAITFD_E|WAITFD_W)
int socket_waitfd(p_socket ps, int sw, p_timeout tm) {
int ret;
fd_set rfds, wfds, efds, *rp = NULL, *wp = NULL, *ep = NULL;
struct timeval tv, *tp = NULL;
double t;
if (timeout_iszero(tm)) return IO_TIMEOUT; /* optimize timeout == 0 case */
if (sw & WAITFD_R) {
FD_ZERO(&rfds);
FD_SET(*ps, &rfds);
rp = &rfds;
}
if (sw & WAITFD_W) { FD_ZERO(&wfds); FD_SET(*ps, &wfds); wp = &wfds; }
if (sw & WAITFD_C) { FD_ZERO(&efds); FD_SET(*ps, &efds); ep = &efds; }
if ((t = timeout_get(tm)) >= 0.0) {
tv.tv_sec = (int) t;
tv.tv_usec = (int) ((t-tv.tv_sec)*1.0e6);
tp = &tv;
}
ret = select(0, rp, wp, ep, tp);
if (ret == -1) return WSAGetLastError();
if (ret == 0) return IO_TIMEOUT;
if (sw == WAITFD_C && FD_ISSET(*ps, &efds)) return IO_CLOSED;
return IO_DONE;
}
/*-------------------------------------------------------------------------*\
* Select with int timeout in ms
\*-------------------------------------------------------------------------*/
int socket_select(t_socket n, fd_set *rfds, fd_set *wfds, fd_set *efds,
p_timeout tm) {
struct timeval tv;
double t = timeout_get(tm);
tv.tv_sec = (int) t;
tv.tv_usec = (int) ((t - tv.tv_sec) * 1.0e6);
if (n <= 0) {
Sleep((DWORD) (1000*t));
return 0;
} else return select(0, rfds, wfds, efds, t >= 0.0? &tv: NULL);
}
/*-------------------------------------------------------------------------*\
* Close and inutilize socket
\*-------------------------------------------------------------------------*/
void socket_destroy(p_socket ps) {
if (*ps != SOCKET_INVALID) {
socket_setblocking(ps); /* close can take a long time on WIN32 */
closesocket(*ps);
*ps = SOCKET_INVALID;
}
}
/*-------------------------------------------------------------------------*\
*
\*-------------------------------------------------------------------------*/
void socket_shutdown(p_socket ps, int how) {
socket_setblocking(ps);
shutdown(*ps, how);
socket_setnonblocking(ps);
}
/*-------------------------------------------------------------------------*\
* Creates and sets up a socket
\*-------------------------------------------------------------------------*/
int socket_create(p_socket ps, int domain, int type, int protocol) {
*ps = socket(domain, type, protocol);
if (*ps != SOCKET_INVALID) return IO_DONE;
else return WSAGetLastError();
}
/*-------------------------------------------------------------------------*\
* Connects or returns error message
\*-------------------------------------------------------------------------*/
int socket_connect(p_socket ps, SA *addr, socklen_t len, p_timeout tm) {
int err;
/* don't call on closed socket */
if (*ps == SOCKET_INVALID) return IO_CLOSED;
/* ask system to connect */
if (connect(*ps, addr, len) == 0) return IO_DONE;
/* make sure the system is trying to connect */
err = WSAGetLastError();
if (err != WSAEWOULDBLOCK && err != WSAEINPROGRESS) return err;
/* zero timeout case optimization */
if (timeout_iszero(tm)) return IO_TIMEOUT;
/* we wait until something happens */
err = socket_waitfd(ps, WAITFD_C, tm);
if (err == IO_CLOSED) {
int len = sizeof(err);
/* give windows time to set the error (yes, disgusting) */
Sleep(10);
/* find out why we failed */
getsockopt(*ps, SOL_SOCKET, SO_ERROR, (char *)&err, &len);
/* we KNOW there was an error. if 'why' is 0, we will return
* "unknown error", but it's not really our fault */
return err > 0? err: IO_UNKNOWN;
} else return err;
}
/*-------------------------------------------------------------------------*\
* Binds or returns error message
\*-------------------------------------------------------------------------*/
int socket_bind(p_socket ps, SA *addr, socklen_t len) {
int err = IO_DONE;
socket_setblocking(ps);
if (bind(*ps, addr, len) < 0) err = WSAGetLastError();
socket_setnonblocking(ps);
return err;
}
/*-------------------------------------------------------------------------*\
*
\*-------------------------------------------------------------------------*/
int socket_listen(p_socket ps, int backlog) {
int err = IO_DONE;
socket_setblocking(ps);
if (listen(*ps, backlog) < 0) err = WSAGetLastError();
socket_setnonblocking(ps);
return err;
}
/*-------------------------------------------------------------------------*\
* Accept with timeout
\*-------------------------------------------------------------------------*/
int socket_accept(p_socket ps, p_socket pa, SA *addr, socklen_t *len,
p_timeout tm) {
SA daddr;
socklen_t dlen = sizeof(daddr);
if (*ps == SOCKET_INVALID) return IO_CLOSED;
if (!addr) addr = &daddr;
if (!len) len = &dlen;
for ( ;; ) {
int err;
/* try to get client socket */
if ((*pa = accept(*ps, addr, len)) != SOCKET_INVALID) return IO_DONE;
/* find out why we failed */
err = WSAGetLastError();
/* if we failed because there was no connectoin, keep trying */
if (err != WSAEWOULDBLOCK && err != WSAECONNABORTED) return err;
/* call select to avoid busy wait */
if ((err = socket_waitfd(ps, WAITFD_R, tm)) != IO_DONE) return err;
}
/* can't reach here */
return IO_UNKNOWN;
}
/*-------------------------------------------------------------------------*\
* Send with timeout
* On windows, if you try to send 10MB, the OS will buffer EVERYTHING
* this can take an awful lot of time and we will end up blocked.
* Therefore, whoever calls this function should not pass a huge buffer.
\*-------------------------------------------------------------------------*/
int socket_send(p_socket ps, const char *data, size_t count,
size_t *sent, p_timeout tm)
{
int err;
*sent = 0;
/* avoid making system calls on closed sockets */
if (*ps == SOCKET_INVALID) return IO_CLOSED;
/* loop until we send something or we give up on error */
for ( ;; ) {
/* try to send something */
int put = send(*ps, data, (int) count, 0);
/* if we sent something, we are done */
if (put > 0) {
*sent = put;
return IO_DONE;
}
/* deal with failure */
err = WSAGetLastError();
/* we can only proceed if there was no serious error */
if (err != WSAEWOULDBLOCK) return err;
/* avoid busy wait */
if ((err = socket_waitfd(ps, WAITFD_W, tm)) != IO_DONE) return err;
}
/* can't reach here */
return IO_UNKNOWN;
}
/*-------------------------------------------------------------------------*\
* Sendto with timeout
\*-------------------------------------------------------------------------*/
int socket_sendto(p_socket ps, const char *data, size_t count, size_t *sent,
SA *addr, socklen_t len, p_timeout tm)
{
int err;
*sent = 0;
if (*ps == SOCKET_INVALID) return IO_CLOSED;
for ( ;; ) {
int put = sendto(*ps, data, (int) count, 0, addr, len);
if (put > 0) {
*sent = put;
return IO_DONE;
}
err = WSAGetLastError();
if (err != WSAEWOULDBLOCK) return err;
if ((err = socket_waitfd(ps, WAITFD_W, tm)) != IO_DONE) return err;
}
return IO_UNKNOWN;
}
/*-------------------------------------------------------------------------*\
* Receive with timeout
\*-------------------------------------------------------------------------*/
int socket_recv(p_socket ps, char *data, size_t count, size_t *got, p_timeout tm) {
int err;
*got = 0;
if (*ps == SOCKET_INVALID) return IO_CLOSED;
for ( ;; ) {
int taken = recv(*ps, data, (int) count, 0);
if (taken > 0) {
*got = taken;
return IO_DONE;
}
if (taken == 0) return IO_CLOSED;
err = WSAGetLastError();
if (err != WSAEWOULDBLOCK) return err;
if ((err = socket_waitfd(ps, WAITFD_R, tm)) != IO_DONE) return err;
}
return IO_UNKNOWN;
}
/*-------------------------------------------------------------------------*\
* Recvfrom with timeout
\*-------------------------------------------------------------------------*/
int socket_recvfrom(p_socket ps, char *data, size_t count, size_t *got,
SA *addr, socklen_t *len, p_timeout tm) {
int err;
*got = 0;
if (*ps == SOCKET_INVALID) return IO_CLOSED;
for ( ;; ) {
int taken = recvfrom(*ps, data, (int) count, 0, addr, len);
if (taken > 0) {
*got = taken;
return IO_DONE;
}
if (taken == 0) return IO_CLOSED;
err = WSAGetLastError();
if (err != WSAEWOULDBLOCK) return err;
if ((err = socket_waitfd(ps, WAITFD_R, tm)) != IO_DONE) return err;
}
return IO_UNKNOWN;
}
/*-------------------------------------------------------------------------*\
* Put socket into blocking mode
\*-------------------------------------------------------------------------*/
void socket_setblocking(p_socket ps) {
u_long argp = 0;
ioctlsocket(*ps, FIONBIO, &argp);
}
/*-------------------------------------------------------------------------*\
* Put socket into non-blocking mode
\*-------------------------------------------------------------------------*/
void socket_setnonblocking(p_socket ps) {
u_long argp = 1;
ioctlsocket(*ps, FIONBIO, &argp);
}
/*-------------------------------------------------------------------------*\
* DNS helpers
\*-------------------------------------------------------------------------*/
int socket_gethostbyaddr(const char *addr, socklen_t len, struct hostent **hp) {
*hp = gethostbyaddr(addr, len, AF_INET);
if (*hp) return IO_DONE;
else return WSAGetLastError();
}
int socket_gethostbyname(const char *addr, struct hostent **hp) {
*hp = gethostbyname(addr);
if (*hp) return IO_DONE;
else return WSAGetLastError();
}
/*-------------------------------------------------------------------------*\
* Error translation functions
\*-------------------------------------------------------------------------*/
const char *socket_hoststrerror(int err) {
if (err <= 0) return io_strerror(err);
switch (err) {
case WSAHOST_NOT_FOUND: return "host not found";
default: return wstrerror(err);
}
}
const char *socket_strerror(int err) {
if (err <= 0) return io_strerror(err);
switch (err) {
case WSAEADDRINUSE: return "address already in use";
case WSAECONNREFUSED: return "connection refused";
case WSAEISCONN: return "already connected";
case WSAEACCES: return "permission denied";
case WSAECONNABORTED: return "closed";
case WSAECONNRESET: return "closed";
case WSAETIMEDOUT: return "timeout";
default: return wstrerror(err);
}
}
const char *socket_ioerror(p_socket ps, int err) {
(void) ps;
return socket_strerror(err);
}
static const char *wstrerror(int err) {
switch (err) {
case WSAEINTR: return "Interrupted function call";
case WSAEACCES: return "Permission denied";
case WSAEFAULT: return "Bad address";
case WSAEINVAL: return "Invalid argument";
case WSAEMFILE: return "Too many open files";
case WSAEWOULDBLOCK: return "Resource temporarily unavailable";
case WSAEINPROGRESS: return "Operation now in progress";
case WSAEALREADY: return "Operation already in progress";
case WSAENOTSOCK: return "Socket operation on nonsocket";
case WSAEDESTADDRREQ: return "Destination address required";
case WSAEMSGSIZE: return "Message too long";
case WSAEPROTOTYPE: return "Protocol wrong type for socket";
case WSAENOPROTOOPT: return "Bad protocol option";
case WSAEPROTONOSUPPORT: return "Protocol not supported";
case WSAESOCKTNOSUPPORT: return "Socket type not supported";
case WSAEOPNOTSUPP: return "Operation not supported";
case WSAEPFNOSUPPORT: return "Protocol family not supported";
case WSAEAFNOSUPPORT:
return "Address family not supported by protocol family";
case WSAEADDRINUSE: return "Address already in use";
case WSAEADDRNOTAVAIL: return "Cannot assign requested address";
case WSAENETDOWN: return "Network is down";
case WSAENETUNREACH: return "Network is unreachable";
case WSAENETRESET: return "Network dropped connection on reset";
case WSAECONNABORTED: return "Software caused connection abort";
case WSAECONNRESET: return "Connection reset by peer";
case WSAENOBUFS: return "No buffer space available";
case WSAEISCONN: return "Socket is already connected";
case WSAENOTCONN: return "Socket is not connected";
case WSAESHUTDOWN: return "Cannot send after socket shutdown";
case WSAETIMEDOUT: return "Connection timed out";
case WSAECONNREFUSED: return "Connection refused";
case WSAEHOSTDOWN: return "Host is down";
case WSAEHOSTUNREACH: return "No route to host";
case WSAEPROCLIM: return "Too many processes";
case WSASYSNOTREADY: return "Network subsystem is unavailable";
case WSAVERNOTSUPPORTED: return "Winsock.dll version out of range";
case WSANOTINITIALISED:
return "Successful WSAStartup not yet performed";
case WSAEDISCON: return "Graceful shutdown in progress";
case WSAHOST_NOT_FOUND: return "Host not found";
case WSATRY_AGAIN: return "Nonauthoritative host not found";
case WSANO_RECOVERY: return "Nonrecoverable name lookup error";
case WSANO_DATA: return "Valid name, no data record of requested type";
default: return "Unknown error";
}
}
@@ -0,0 +1,21 @@
#ifndef WSOCKET_H
#define WSOCKET_H
/*=========================================================================*\
* Socket compatibilization module for Win32
* LuaSocket toolkit
*
* RCS ID: $Id: wsocket.h,v 1.4 2005/10/07 04:40:59 diego Exp $
\*=========================================================================*/
/*=========================================================================*\
* WinSock include files
\*=========================================================================*/
#include <winsock.h>
typedef int socklen_t;
typedef SOCKET t_socket;
typedef t_socket *p_socket;
#define SOCKET_INVALID (INVALID_SOCKET)
#endif /* WSOCKET_H */
+120
View File
@@ -0,0 +1,120 @@
/**
* Copyright (c) 2006-2009 LOVE Development Team
*
* This software is provided 'as-is', without any express or implied
* warranty. In no event will the authors be held liable for any damages
* arising from the use of this software.
*
* Permission is granted to anyone to use this software for any purpose,
* including commercial applications, and to alter it and redistribute it
* freely, subject to the following restrictions:
*
* 1. The origin of this software must not be misrepresented; you must not
* claim that you wrote the original software. If you use this software
* in a product, an acknowledgment in the product documentation would be
* appreciated but is not required.
* 2. Altered source versions must be plainly marked as such, and must not be
* misrepresented as being the original software.
* 3. This notice may not be removed or altered from any source distribution.
**/
#include "luasocket.h"
// LuaSocket
extern "C" {
#include "libluasocket/luasocket.h"
#include "libluasocket/mime.h"
}
// Quick macro for adding functions to
// the preloder.
#define PRELOAD(name, function) \
lua_getglobal(L, "package"); \
lua_getfield(L, -1, "preload"); \
lua_pushcfunction(L, function); \
lua_setfield(L, -2, name); \
lua_pop(L, 2);
namespace love
{
namespace luasocket
{
int __open(lua_State * L)
{
// Preload code from LuaSocket.
PRELOAD("socket.core", luaopen_socket_core);
PRELOAD("mime.core", luaopen_mime_core);
PRELOAD("socket", __open_luasocket_socket);
PRELOAD("socket.ftp", __open_luasocket_ftp)
PRELOAD("socket.http", __open_luasocket_http);
PRELOAD("ltn12", __open_luasocket_ltn12);
PRELOAD("mime", __open_luasocket_mime)
PRELOAD("socket.smtp", __open_luasocket_smtp);
PRELOAD("socket.tp", __open_luasocket_tp)
PRELOAD("socket.url", __open_luasocket_url)
// No need to register garbage collector function.
return 0;
}
int __open_luasocket_socket(lua_State * L)
{
#include "libluasocket/socket.lua.h"
lua_getglobal(L, "socket");
return 1;
}
int __open_luasocket_ftp(lua_State * L)
{
#include "libluasocket/ftp.lua.h"
lua_getglobal(L, "socket.ftp");
return 1;
}
int __open_luasocket_http(lua_State * L)
{
#include "libluasocket/http.lua.h"
lua_getglobal(L, "socket.http");
return 1;
}
int __open_luasocket_ltn12(lua_State * L)
{
#include "libluasocket/ltn12.lua.h"
lua_getglobal(L, "ltn12");
return 1;
}
int __open_luasocket_mime(lua_State * L)
{
#include "libluasocket/mime.lua.h"
lua_getglobal(L, "mime");
return 1;
}
int __open_luasocket_smtp(lua_State * L)
{
#include "libluasocket/smtp.lua.h"
lua_getglobal(L, "socket.smtp");
return 1;
}
int __open_luasocket_tp(lua_State * L)
{
#include "libluasocket/tp.lua.h"
lua_getglobal(L, "socket.tp");
return 1;
}
int __open_luasocket_url(lua_State * L)
{
#include "libluasocket/url.lua.h"
lua_getglobal(L, "socket.url");
return 1;
}
} // luasocket
} // love
+48
View File
@@ -0,0 +1,48 @@
/**
* Copyright (c) 2006-2009 LOVE Development Team
*
* This software is provided 'as-is', without any express or implied
* warranty. In no event will the authors be held liable for any damages
* arising from the use of this software.
*
* Permission is granted to anyone to use this software for any purpose,
* including commercial applications, and to alter it and redistribute it
* freely, subject to the following restrictions:
*
* 1. The origin of this software must not be misrepresented; you must not
* claim that you wrote the original software. If you use this software
* in a product, an acknowledgment in the product documentation would be
* appreciated but is not required.
* 2. Altered source versions must be plainly marked as such, and must not be
* misrepresented as being the original software.
* 3. This notice may not be removed or altered from any source distribution.
**/
#ifndef LOVE_LUASOCKET_LUASOCKET_H
#define LOVE_LUASOCKET_LUASOCKET_H
// LOVE
#include <common/runtime.h>
namespace love
{
namespace luasocket
{
int __open(lua_State * L);
// Loaders for all lua files. We want to be able
// to load these dynamically. (Identical in the LuaSocket
// documentation. These functions wrap the parsing of code, etc).
int __open_luasocket_socket(lua_State * L);
int __open_luasocket_ftp(lua_State * L);
int __open_luasocket_http(lua_State * L);
int __open_luasocket_ltn12(lua_State * L);
int __open_luasocket_mime(lua_State * L);
int __open_luasocket_smtp(lua_State * L);
int __open_luasocket_tp(lua_State * L);
int __open_luasocket_url(lua_State * L);
} // luasocket
} // love
#endif // LOVE_LUASOCKET_LUASOCKET_H
+144
View File
@@ -0,0 +1,144 @@
/**
* Copyright (c) 2006-2009 LOVE Development Team
*
* This software is provided 'as-is', without any express or implied
* warranty. In no event will the authors be held liable for any damages
* arising from the use of this software.
*
* Permission is granted to anyone to use this software for any purpose,
* including commercial applications, and to alter it and redistribute it
* freely, subject to the following restrictions:
*
* 1. The origin of this software must not be misrepresented; you must not
* claim that you wrote the original software. If you use this software
* in a product, an acknowledgment in the product documentation would be
* appreciated but is not required.
* 2. Altered source versions must be plainly marked as such, and must not be
* misrepresented as being the original software.
* 3. This notice may not be removed or altered from any source distribution.
**/
// STD
// SDL
#include <SDL.h>
// LOVE
#include <common/config.h>
#include <common/runtime.h>
#include <common/constants.h>
// Modules
#include <audio/wrap_Audio.h>
#include <audio/openal/Audio.h>
#include <audio/null/Audio.h>
#include <event/sdl/wrap_Event.h>
#include <filesystem/physfs/wrap_Filesystem.h>
#include <graphics/opengl/wrap_Graphics.h>
#include <image/wrap_Image.h>
#include <joystick/sdl/wrap_Joystick.h>
#include <keyboard/sdl/wrap_Keyboard.h>
#include <mouse/sdl/wrap_Mouse.h>
#include <native/tcc/wrap_Native.h>
#include <physics/box2d/wrap_Physics.h>
#include <sound/wrap_Sound.h>
#include <timer/sdl/wrap_Timer.h>
// Libraries.
#include "libraries/luasocket/luasocket.h"
#include "libraries/lanes/lanes.h"
DECLSPEC int luaopen_love(lua_State * L)
{
// Create the love table.
lua_newtable(L);
// Install constants.
for(int i = 0; love::lua_constants[i].name != 0; i++)
{
lua_pushinteger(L, love::lua_constants[i].value);
lua_setfield(L, -2, love::lua_constants[i].name);
}
// Create the __fin table.
lua_newtable(L);
lua_setfield(L, -2, "__fin");
// Set the love table.
lua_setglobal(L, "love");
love::luax_preload(L, love::audio::wrap_Audio_open, "love.audio");
love::luax_preload(L, love::filesystem::physfs::wrap_Filesystem_open, "love.filesystem");
love::luax_preload(L, love::event::sdl::wrap_Event_open, "love.event");
love::luax_preload(L, love::keyboard::sdl::wrap_Keyboard_open, "love.keyboard");
love::luax_preload(L, love::mouse::sdl::wrap_Mouse_open, "love.mouse");
love::luax_preload(L, love::native::tcc::wrap_Native_open, "love.native");
love::luax_preload(L, love::timer::sdl::wrap_Timer_open, "love.timer");
love::luax_preload(L, love::joystick::sdl::wrap_Joystick_open, "love.joystick");
love::luax_preload(L, love::graphics::opengl::wrap_Graphics_open, "love.graphics");
love::luax_preload(L, love::image::wrap_Image_open, "love.image");
love::luax_preload(L, love::physics::box2d::wrap_Physics_open, "love.physics");
love::luax_preload(L, love::sound::wrap_Sound_open, "love.sound");
love::luasocket::__open(L);
love::lanes::open(L);
return 0;
}
#if LOVE_BUILD_EXE
int main(int argc, char ** argv)
{
// Create the virtual machine.
lua_State * L = lua_open();
luaL_openlibs(L);
love::luax_preload(L, luaopen_love, "love");
luaopen_love(L);
// Add command line arguments to love.__args
{
lua_getglobal(L, "love");
lua_newtable(L);
for(int i = 0;i<argc;i++)
{
lua_pushstring(L, argv[i]);
lua_rawseti(L, -2, i);
}
lua_setfield(L, -2, "__args");
lua_pop(L, 1);
}
// Add love.__exe = true.
// This indicates that we're running the
// standalone version of love, and not the
// DLL version.
{
lua_getglobal(L, "love");
lua_pushboolean(L, 1);
lua_setfield(L, -2, "__exe");
lua_pop(L, 1);
}
// This is where we should run the built-in Lua code
// which gets everything started.
// TODO: This is obviously test code.
//luaL_dofile(L, "../../src/scripts/boot.lua");
# include "scripts/boot.lua.h"
lua_close(L);
#if defined(LOVE_DEBUG) && defined(LOVE_WINDOWS)
printf("(press key)\n");
getchar();
#endif
printf("Done. This was: %s (%s)\n", LOVE_VERSION_STR.c_str(), LOVE_VERSION_CODENAME.c_str());
return 0;
}
#endif // LOVE_BUILD_EXE
+48
View File
@@ -0,0 +1,48 @@
/**
* Copyright (c) 2006-2009 LOVE Development Team
*
* This software is provided 'as-is', without any express or implied
* warranty. In no event will the authors be held liable for any damages
* arising from the use of this software.
*
* Permission is granted to anyone to use this software for any purpose,
* including commercial applications, and to alter it and redistribute it
* freely, subject to the following restrictions:
*
* 1. The origin of this software must not be misrepresented; you must not
* claim that you wrote the original software. If you use this software
* in a product, an acknowledgment in the product documentation would be
* appreciated but is not required.
* 2. Altered source versions must be plainly marked as such, and must not be
* misrepresented as being the original software.
* 3. This notice may not be removed or altered from any source distribution.
**/
#ifndef LOVE_AUDIO_AUDIBLE_H
#define LOVE_AUDIO_AUDIBLE_H
// LOVE
#include <common/Object.h>
namespace love
{
namespace audio
{
class Source;
class Audible : public Object
{
public:
virtual ~Audible(){};
virtual void play(Source * source) = 0;
virtual void update(Source * source) = 0;
virtual void stop(Source * source) = 0;
virtual void rewind(Source * source) = 0;
}; // Audible
} // audio
} // love
#endif // LOVE_AUDIO_AUDIBLE_H
+164
View File
@@ -0,0 +1,164 @@
/**
* Copyright (c) 2006-2009 LOVE Development Team
*
* This software is provided 'as-is', without any express or implied
* warranty. In no event will the authors be held liable for any damages
* arising from the use of this software.
*
* Permission is granted to anyone to use this software for any purpose,
* including commercial applications, and to alter it and redistribute it
* freely, subject to the following restrictions:
*
* 1. The origin of this software must not be misrepresented = 0; you must not
* claim that you wrote the original software. If you use this software
* in a product, an acknowledgment in the product documentation would be
* appreciated but is not required.
* 2. Altered source versions must be plainly marked as such, and must not be
* misrepresented as being the original software.
* 3. This notice may not be removed or altered from any source distribution.
**/
#ifndef LOVE_AUDIO_AUDIO_H
#define LOVE_AUDIO_AUDIO_H
#include <common/Module.h>
#include "Source.h"
#include "Sound.h"
#include "Music.h"
namespace love
{
namespace audio
{
/**
* The Audio module is responsible for playing back raw sound samples.
**/
class Audio : public Module
{
public:
/**
* Destructor.
**/
virtual ~Audio(){};
/**
* Creates a new Sound with the specified SoundData.
* @param data The SoundData from which to create the sound.
* @return A new Sound if successful, zero otherwise.
**/
virtual Sound * newSound(love::sound::SoundData * data) = 0;
/**
* Creates a new Music (stream) using the specified SoundData.
* @param decoder The object to use to decode the sound stream.
**/
virtual Music * newMusic(love::sound::Decoder * decoder) = 0;
/**
* Creates a new Source.
* @returns A new Source.
**/
virtual Source * newSource() = 0;
/**
* Gets the current number of simulatenous playing sources.
* @return The current number of simulatenous playing sources.
**/
virtual int getNumSources() const = 0;
/**
* Gets the maximum supported number of simulatenous playing sources.
* @return The maximum supported number of simulatenous playing sources.
**/
virtual int getMaxSources() const = 0;
/**
* Play the specified Source.
* @param source The Source to play.
**/
virtual void play(Source * source) = 0;
/**
* Plays one Sound on the specified Source. We need separate
* Sound and Music play functions because Music must be cloned,
* whereas Sound needs not be.
*
* @param sound The Sound to play.
* @param source The Source on which to play the Sound.
**/
virtual void play(Sound * sound) = 0;
/**
* Plays one Music on the specified Source. We need separate
* Sound and Music play functions because Music must be cloned,
* whereas Sound needs not be.
*
* @param music The Music to play.
* @param source The Source on which to play the Music.
**/
virtual void play(Music * music) = 0;
/**
* Stops playback on the specified source.
* @param source The source on which to stop the playback.
**/
virtual void stop(Source * source) = 0;
/**
* Stops all playing audio.
**/
virtual void stop() = 0;
/**
* Pauses playback on the specified source.
* @param source The source on which to pause the playback.
**/
virtual void pause(Source * source) = 0;
/**
* Pauses all audio.
**/
virtual void pause() = 0;
/**
* Resumes playback on the specified source.
* @param source The source on which to resume the playback.
**/
virtual void resume(Source * source) = 0;
/**
* Resumes all audio.
**/
virtual void resume() = 0;
/**
* Rewinds the specified source. Whatever is playing on this
* source gets rewound to the start.
* @param source The source to rewind.
**/
virtual void rewind(Source * source) = 0;
/**
* Rewinds all playing audio.
**/
virtual void rewind() = 0;
/**
* Sets the master volume, where 0.0f is min (off) and 1.0f is max.
* @param volume The new master volume.
**/
virtual void setVolume(float volume) = 0;
/**
* Gets the master volume.
* @return The current master volume.
**/
virtual float getVolume() const = 0;
}; // Audio
} // audio
} // love
#endif // LOVE_AUDIO_AUDIO_H
+63
View File
@@ -0,0 +1,63 @@
/**
* Copyright (c) 2006-2009 LOVE Development Team
*
* This software is provided 'as-is', without any express or implied
* warranty. In no event will the authors be held liable for any damages
* arising from the use of this software.
*
* Permission is granted to anyone to use this software for any purpose,
* including commercial applications, and to alter it and redistribute it
* freely, subject to the following restrictions:
*
* 1. The origin of this software must not be misrepresented; you must not
* claim that you wrote the original software. If you use this software
* in a product, an acknowledgment in the product documentation would be
* appreciated but is not required.
* 2. Altered source versions must be plainly marked as such, and must not be
* misrepresented as being the original software.
* 3. This notice may not be removed or altered from any source distribution.
**/
#ifndef LOVE_AUDIO_MUSIC_H
#define LOVE_AUDIO_MUSIC_H
// LOVE
#include "Audible.h"
#include <sound/Decoder.h>
namespace love
{
namespace audio
{
/**
* A Music object represents a stream of sound samples which are gradually
* acquired somehow. Compare with Sounds, which have all the needed sound
* samples pre-decoded.
*
* Typically, you would want to use love::sound::Decoder to decode samples
* from some encoded format, like OGG or MP3, however, Music can come from
* other sources as well.
**/
class Music : public Audible
{
public:
/**
* Destructor.
**/
virtual ~Music(){};
/**
* Creates a clone of the music stream. Music objects are gradually
* decoded, so if the client wants to play the same Music object, we can't
* use the same object. We must clone the entire stream.
* @return A clone of this object, but rewound to the start.
**/
virtual Music * clone() = 0;
}; // Music
} // audio
} // love
#endif // LOVE_AUDIO_MUSIC_H
+42
View File
@@ -0,0 +1,42 @@
/**
* Copyright (c) 2006-2009 LOVE Development Team
*
* This software is provided 'as-is', without any express or implied
* warranty. In no event will the authors be held liable for any damages
* arising from the use of this software.
*
* Permission is granted to anyone to use this software for any purpose,
* including commercial applications, and to alter it and redistribute it
* freely, subject to the following restrictions:
*
* 1. The origin of this software must not be misrepresented; you must not
* claim that you wrote the original software. If you use this software
* in a product, an acknowledgment in the product documentation would be
* appreciated but is not required.
* 2. Altered source versions must be plainly marked as such, and must not be
* misrepresented as being the original software.
* 3. This notice may not be removed or altered from any source distribution.
**/
#ifndef LOVE_AUDIO_SOUND_H
#define LOVE_AUDIO_SOUND_H
// LOVE
#include <sound/SoundData.h>
#include "Audible.h"
namespace love
{
namespace audio
{
class Sound : public Audible
{
private:
public:
virtual ~Sound(){};
}; // Sound
} // audio
} // love
#endif // LOVE_AUDIO_SOUND_H
+60
View File
@@ -0,0 +1,60 @@
/**
* Copyright (c) 2006-2009 LOVE Development Team
*
* This software is provided 'as-is', without any express or implied
* warranty. In no event will the authors be held liable for any damages
* arising from the use of this software.
*
* Permission is granted to anyone to use this software for any purpose,
* including commercial applications, and to alter it and redistribute it
* freely, subject to the following restrictions:
*
* 1. The origin of this software must not be misrepresented; you must not
* claim that you wrote the original software. If you use this software
* in a product, an acknowledgment in the product documentation would be
* appreciated but is not required.
* 2. Altered source versions must be plainly marked as such, and must not be
* misrepresented as being the original software.
* 3. This notice may not be removed or altered from any source distribution.
**/
#include "Source.h"
namespace love
{
namespace audio
{
Source::Source()
: audible(0)
{
}
Source::~Source()
{
if(audible != 0)
{
audible->stop(this);
audible->release();
}
}
void Source::setAudible(Audible * audible)
{
// If this source already has an audible, remove it.
if(this->audible != 0)
{
this->audible->stop(this);
this->audible->release();
}
this->audible = audible;
audible->retain();
}
Audible * Source::getAudible() const
{
return audible;
}
} // audio
} // love
+61
View File
@@ -0,0 +1,61 @@
/**
* Copyright (c) 2006-2009 LOVE Development Team
*
* This software is provided 'as-is', without any express or implied
* warranty. In no event will the authors be held liable for any damages
* arising from the use of this software.
*
* Permission is granted to anyone to use this software for any purpose,
* including commercial applications, and to alter it and redistribute it
* freely, subject to the following restrictions:
*
* 1. The origin of this software must not be misrepresented; you must not
* claim that you wrote the original software. If you use this software
* in a product, an acknowledgment in the product documentation would be
* appreciated but is not required.
* 2. Altered source versions must be plainly marked as such, and must not be
* misrepresented as being the original software.
* 3. This notice may not be removed or altered from any source distribution.
**/
#ifndef LOVE_AUDIO_SOURCE_H
#define LOVE_AUDIO_SOURCE_H
// LOVE
#include <common/Object.h>
#include "Audible.h"
namespace love
{
namespace audio
{
class Source : public Object
{
protected:
Audible * audible;
public:
Source();
virtual ~Source();
void setAudible(Audible * audible);
Audible * getAudible() const;
virtual void play() = 0;
virtual void stop() = 0;
virtual void pause() = 0;
virtual void resume() = 0;
virtual void rewind() = 0;
virtual bool isFinished() const = 0;
virtual void update() = 0;
virtual void setPitch(float pitch) = 0;
virtual float getPitch() const = 0;
virtual void setVolume(float volume) = 0;
virtual float getVolume() const = 0;
}; // Source
} // audio
} // love
#endif // LOVE_AUDIO_SOURCE_H
+127
View File
@@ -0,0 +1,127 @@
/**
* Copyright (c) 2006-2009 LOVE Development Team
*
* This software is provided 'as-is', without any express or implied
* warranty. In no event will the authors be held liable for any damages
* arising from the use of this software.
*
* Permission is granted to anyone to use this software for any purpose,
* including commercial applications, and to alter it and redistribute it
* freely, subject to the following restrictions:
*
* 1. The origin of this software must not be misrepresented; you must not
* claim that you wrote the original software. If you use this software
* in a product, an acknowledgment in the product documentation would be
* appreciated but is not required.
* 2. Altered source versions must be plainly marked as such, and must not be
* misrepresented as being the original software.
* 3. This notice may not be removed or altered from any source distribution.
**/
#include "Audio.h"
namespace love
{
namespace audio
{
namespace null
{
Audio::Audio()
{
}
Audio::~Audio()
{
}
const char * Audio::getName() const
{
return "love.audio.null";
}
love::audio::Sound * Audio::newSound(love::sound::SoundData * data)
{
return new Sound(data);
}
love::audio::Music * Audio::newMusic(love::sound::Decoder * decoder)
{
return new Music(decoder);
}
love::audio::Source * Audio::newSource()
{
return new Source();
}
int Audio::getNumSources() const
{
return 0;
}
int Audio::getMaxSources() const
{
return 0;
}
void Audio::play(love::audio::Source * source)
{
}
void Audio::play(love::audio::Sound * sound)
{
}
void Audio::play(love::audio::Music * music)
{
}
void Audio::play()
{
}
void Audio::stop(love::audio::Source * source)
{
}
void Audio::stop()
{
}
void Audio::pause(love::audio::Source * source)
{
}
void Audio::pause()
{
}
void Audio::resume(love::audio::Source * source)
{
}
void Audio::resume()
{
}
void Audio::rewind(love::audio::Source * source)
{
}
void Audio::rewind()
{
}
void Audio::setVolume(float volume)
{
this->volume = volume;
}
float Audio::getVolume() const
{
return volume;
}
} // null
} // audio
} // love
+76
View File
@@ -0,0 +1,76 @@
/**
* Copyright (c) 2006-2009 LOVE Development Team
*
* This software is provided 'as-is', without any express or implied
* warranty. In no event will the authors be held liable for any damages
* arising from the use of this software.
*
* Permission is granted to anyone to use this software for any purpose,
* including commercial applications, and to alter it and redistribute it
* freely, subject to the following restrictions:
*
* 1. The origin of this software must not be misrepresented; you must not
* claim that you wrote the original software. If you use this software
* in a product, an acknowledgment in the product documentation would be
* appreciated but is not required.
* 2. Altered source versions must be plainly marked as such, and must not be
* misrepresented as being the original software.
* 3. This notice may not be removed or altered from any source distribution.
**/
#ifndef LOVE_AUDIO_NULL_AUDIO_H
#define LOVE_AUDIO_NULL_AUDIO_H
// LOVE
#include <audio/Audio.h>
#include "Sound.h"
#include "Music.h"
#include "Source.h"
namespace love
{
namespace audio
{
namespace null
{
class Audio : public love::audio::Audio
{
private:
float volume;
public:
Audio();
~Audio();
// Implements Module.
const char * getName() const;
// Implements Audio.
love::audio::Sound * newSound(love::sound::SoundData * data);
love::audio::Music * newMusic(love::sound::Decoder * decoder);
love::audio::Source * newSource();
int getNumSources() const;
int getMaxSources() const;
void play(love::audio::Source * source);
void play(love::audio::Sound * sound);
void play(love::audio::Music * music);
void play();
void stop(love::audio::Source * source);
void stop();
void pause(love::audio::Source * source);
void pause();
void resume(love::audio::Source * source);
void resume();
void rewind(love::audio::Source * source);
void rewind();
void setVolume(float volume);
float getVolume() const;
}; // Audio
} // null
} // audio
} // love
#endif // LOVE_AUDIO_NULL_AUDIO_H
+63
View File
@@ -0,0 +1,63 @@
/**
* Copyright (c) 2006-2009 LOVE Development Team
*
* This software is provided 'as-is', without any express or implied
* warranty. In no event will the authors be held liable for any damages
* arising from the use of this software.
*
* Permission is granted to anyone to use this software for any purpose,
* including commercial applications, and to alter it and redistribute it
* freely, subject to the following restrictions:
*
* 1. The origin of this software must not be misrepresented; you must not
* claim that you wrote the original software. If you use this software
* in a product, an acknowledgment in the product documentation would be
* appreciated but is not required.
* 2. Altered source versions must be plainly marked as such, and must not be
* misrepresented as being the original software.
* 3. This notice may not be removed or altered from any source distribution.
**/
#include "Music.h"
namespace love
{
namespace audio
{
namespace null
{
Music::Music(love::sound::Decoder * decoder)
: decoder(decoder)
{
decoder->retain();
}
Music::~Music()
{
decoder->release();
}
love::audio::Music * Music::clone()
{
return new Music(decoder->clone());
}
void Music::play(love::audio::Source * s)
{
}
void Music::update(love::audio::Source * s)
{
}
void Music::stop(love::audio::Source * s)
{
}
void Music::rewind(love::audio::Source * s)
{
}
} // null
} // audio
} // love
+57
View File
@@ -0,0 +1,57 @@
/**
* Copyright (c) 2006-2009 LOVE Development Team
*
* This software is provided 'as-is', without any express or implied
* warranty. In no event will the authors be held liable for any damages
* arising from the use of this software.
*
* Permission is granted to anyone to use this software for any purpose,
* including commercial applications, and to alter it and redistribute it
* freely, subject to the following restrictions:
*
* 1. The origin of this software must not be misrepresented; you must not
* claim that you wrote the original software. If you use this software
* in a product, an acknowledgment in the product documentation would be
* appreciated but is not required.
* 2. Altered source versions must be plainly marked as such, and must not be
* misrepresented as being the original software.
* 3. This notice may not be removed or altered from any source distribution.
**/
#ifndef LOVE_AUDIO_NULL_MUSIC_H
#define LOVE_AUDIO_NULL_MUSIC_H
// LOVE
#include <audio/Music.h>
#include <sound/Decoder.h>
namespace love
{
namespace audio
{
namespace null
{
class Music : public love::audio::Music
{
private:
love::sound::Decoder * decoder;
public:
Music(love::sound::Decoder * decoder);
virtual ~Music();
// Implements Audible.
void play(love::audio::Source * source);
void update(love::audio::Source * source);
void stop(love::audio::Source * source);
void rewind(love::audio::Source * source);
// Implements Music.
love::audio::Music * clone();
}; // Music
} // null
} // audio
} // love
#endif // LOVE_AUDIO_NULL_MUSIC_H
+55
View File
@@ -0,0 +1,55 @@
/**
* Copyright (c) 2006-2009 LOVE Development Team
*
* This software is provided 'as-is', without any express or implied
* warranty. In no event will the authors be held liable for any damages
* arising from the use of this software.
*
* Permission is granted to anyone to use this software for any purpose,
* including commercial applications, and to alter it and redistribute it
* freely, subject to the following restrictions:
*
* 1. The origin of this software must not be misrepresented; you must not
* claim that you wrote the original software. If you use this software
* in a product, an acknowledgment in the product documentation would be
* appreciated but is not required.
* 2. Altered source versions must be plainly marked as such, and must not be
* misrepresented as being the original software.
* 3. This notice may not be removed or altered from any source distribution.
**/
#include "Sound.h"
namespace love
{
namespace audio
{
namespace null
{
Sound::Sound(love::sound::SoundData * data)
{
}
Sound::~Sound()
{
}
void Sound::play(love::audio::Source * s)
{
}
void Sound::update(love::audio::Source * s)
{
}
void Sound::stop(love::audio::Source * s)
{
}
void Sound::rewind(love::audio::Source * s)
{
}
} // null
} // audio
} // love
+54
View File
@@ -0,0 +1,54 @@
/**
* Copyright (c) 2006-2009 LOVE Development Team
*
* This software is provided 'as-is', without any express or implied
* warranty. In no event will the authors be held liable for any damages
* arising from the use of this software.
*
* Permission is granted to anyone to use this software for any purpose,
* including commercial applications, and to alter it and redistribute it
* freely, subject to the following restrictions:
*
* 1. The origin of this software must not be misrepresented; you must not
* claim that you wrote the original software. If you use this software
* in a product, an acknowledgment in the product documentation would be
* appreciated but is not required.
* 2. Altered source versions must be plainly marked as such, and must not be
* misrepresented as being the original software.
* 3. This notice may not be removed or altered from any source distribution.
**/
#ifndef LOVE_AUDIO_NULL_SOUND_H
#define LOVE_AUDIO_NULL_SOUND_H
// LOVE
#include <sound/SoundData.h>
#include <audio/Sound.h>
namespace love
{
namespace audio
{
namespace null
{
class Sound : public love::audio::Sound
{
private:
public:
Sound(love::sound::SoundData * data);
virtual ~Sound();
// Implements Audible.
void play(love::audio::Source * s);
void update(love::audio::Source * s);
void stop(love::audio::Source * s);
void rewind(love::audio::Source * s);
}; // Sound
} // null
} // audio
} // love
#endif // LOVE_AUDIO_NULL_SOUND_H
+94
View File
@@ -0,0 +1,94 @@
/**
* Copyright (c) 2006-2009 LOVE Development Team
*
* This software is provided 'as-is', without any express or implied
* warranty. In no event will the authors be held liable for any damages
* arising from the use of this software.
*
* Permission is granted to anyone to use this software for any purpose,
* including commercial applications, and to alter it and redistribute it
* freely, subject to the following restrictions:
*
* 1. The origin of this software must not be misrepresented; you must not
* claim that you wrote the original software. If you use this software
* in a product, an acknowledgment in the product documentation would be
* appreciated but is not required.
* 2. Altered source versions must be plainly marked as such, and must not be
* misrepresented as being the original software.
* 3. This notice may not be removed or altered from any source distribution.
**/
#include "Source.h"
namespace love
{
namespace audio
{
namespace null
{
Source::Source()
{
}
Source::Source(Audible * audible)
{
setAudible(audible);
}
Source::~Source()
{
}
void Source::play()
{
}
void Source::stop()
{
}
void Source::pause()
{
}
void Source::resume()
{
}
void Source::rewind()
{
}
bool Source::isFinished() const
{
return true;
}
void Source::update()
{
}
void Source::setPitch(float pitch)
{
this->pitch = pitch;
}
float Source::getPitch() const
{
return pitch;
}
void Source::setVolume(float volume)
{
this->volume = volume;
}
float Source::getVolume() const
{
return volume;
}
} // null
} // audio
} // love
+66
View File
@@ -0,0 +1,66 @@
/**
* Copyright (c) 2006-2009 LOVE Development Team
*
* This software is provided 'as-is', without any express or implied
* warranty. In no event will the authors be held liable for any damages
* arising from the use of this software.
*
* Permission is granted to anyone to use this software for any purpose,
* including commercial applications, and to alter it and redistribute it
* freely, subject to the following restrictions:
*
* 1. The origin of this software must not be misrepresented; you must not
* claim that you wrote the original software. If you use this software
* in a product, an acknowledgment in the product documentation would be
* appreciated but is not required.
* 2. Altered source versions must be plainly marked as such, and must not be
* misrepresented as being the original software.
* 3. This notice may not be removed or altered from any source distribution.
**/
#ifndef LOVE_AUDIO_NULL_SOURCE_H
#define LOVE_AUDIO_NULL_SOURCE_H
// LOVE
#include <common/Object.h>
#include <audio/Source.h>
namespace love
{
namespace audio
{
namespace null
{
class Source : public love::audio::Source
{
private:
float pitch;
float volume;
public:
Source();
Source(Audible * audible);
virtual ~Source();
void play();
void stop();
void pause();
void resume();
void rewind();
bool isFinished() const;
void update();
void setPitch(float pitch);
float getPitch() const;
void setVolume(float volume);
float getVolume() const;
}; // Source
} // null
} // audio
} // love
#endif // LOVE_AUDIO_NULL_SOURCE_H
+180
View File
@@ -0,0 +1,180 @@
/**
* Copyright (c) 2006-2009 LOVE Development Team
*
* This software is provided 'as-is', without any express or implied
* warranty. In no event will the authors be held liable for any damages
* arising from the use of this software.
*
* Permission is granted to anyone to use this software for any purpose,
* including commercial applications, and to alter it and redistribute it
* freely, subject to the following restrictions:
*
* 1. The origin of this software must not be misrepresented; you must not
* claim that you wrote the original software. If you use this software
* in a product, an acknowledgment in the product documentation would be
* appreciated but is not required.
* 2. Altered source versions must be plainly marked as such, and must not be
* misrepresented as being the original software.
* 3. This notice may not be removed or altered from any source distribution.
**/
#include "Audio.h"
namespace love
{
namespace audio
{
namespace openal
{
Audio::Audio()
{
// Passing zero for default device.
device = alcOpenDevice(0);
if(device == 0)
throw love::Exception("Could not open device.");
context = alcCreateContext(device, 0);
if(context == 0)
throw love::Exception("Could not create context.");
alcMakeContextCurrent(context);
if(alcGetError(device) != ALC_NO_ERROR)
throw love::Exception("Could not make context current.");
// pool must be allocated after AL context.
pool = new Pool();
thread = SDL_CreateThread(Audio::run, (void*)this);
}
Audio::~Audio()
{
SDL_KillThread(thread);
delete pool;
alcMakeContextCurrent(0);
alcDestroyContext(context);
alcCloseDevice(device);
}
int Audio::run(void * d)
{
Audio * instance = (Audio*)d;
while(true)
{
instance->pool->update();
SDL_Delay(10);
}
return 0;
}
const char * Audio::getName() const
{
return "love.audio.openal";
}
love::audio::Sound * Audio::newSound(love::sound::SoundData * data)
{
return new Sound(pool, data);
}
love::audio::Music * Audio::newMusic(love::sound::Decoder * decoder)
{
return new Music(pool, decoder);
}
love::audio::Source * Audio::newSource()
{
return new Source(pool);
}
int Audio::getNumSources() const
{
return pool->getNumSources();
}
int Audio::getMaxSources() const
{
return pool->getMaxSources();
}
void Audio::play(love::audio::Source * source)
{
source->play();
}
void Audio::play(love::audio::Sound * sound)
{
Source * source = new Source(pool, sound);
play(source);
source->release();
}
void Audio::play(love::audio::Music * music)
{
Source * source = new Source(pool, music->clone());
play(source);
source->release();
}
void Audio::stop(love::audio::Source * source)
{
source->stop();
}
void Audio::stop()
{
pool->stop();
}
void Audio::pause(love::audio::Source * source)
{
source->pause();
}
void Audio::pause()
{
pool->pause();
}
void Audio::resume(love::audio::Source * source)
{
source->resume();
}
void Audio::resume()
{
pool->resume();
}
void Audio::rewind(love::audio::Source * source)
{
source->rewind();
}
void Audio::rewind()
{
pool->rewind();
}
void Audio::setVolume(float volume)
{
alListenerf(AL_GAIN, volume);
}
float Audio::getVolume() const
{
ALfloat volume;
alGetListenerf(AL_GAIN, &volume);
return volume;
}
} // openal
} // audio
} // love
+106
View File
@@ -0,0 +1,106 @@
/**
* Copyright (c) 2006-2009 LOVE Development Team
*
* This software is provided 'as-is', without any express or implied
* warranty. In no event will the authors be held liable for any damages
* arising from the use of this software.
*
* Permission is granted to anyone to use this software for any purpose,
* including commercial applications, and to alter it and redistribute it
* freely, subject to the following restrictions:
*
* 1. The origin of this software must not be misrepresented; you must not
* claim that you wrote the original software. If you use this software
* in a product, an acknowledgment in the product documentation would be
* appreciated but is not required.
* 2. Altered source versions must be plainly marked as such, and must not be
* misrepresented as being the original software.
* 3. This notice may not be removed or altered from any source distribution.
**/
#ifndef LOVE_AUDIO_OPENAL_AUDIO_H
#define LOVE_AUDIO_OPENAL_AUDIO_H
// STD
#include <queue>
#include <map>
#include <iostream>
#include <cmath>
// SDL
#include <SDL.h>
// OpenAL
#include <AL/alc.h>
#include <AL/al.h>
// LOVE
#include <audio/Audio.h>
#include <common/config.h>
#include <common/constants.h>
#include <sound/SoundData.h>
#include "Sound.h"
#include "Music.h"
#include "Source.h"
#include "Pool.h"
namespace love
{
namespace audio
{
namespace openal
{
class Audio : public love::audio::Audio
{
private:
// The OpenAL device.
ALCdevice * device;
// The OpenAL context.
ALCcontext * context;
SDL_Thread * thread;
// The Pool.
Pool * pool;
static int run(void * unused);
public:
Audio();
~Audio();
// Implements Module.
const char * getName() const;
// Implements Audio.
love::audio::Sound * newSound(love::sound::SoundData * data);
love::audio::Music * newMusic(love::sound::Decoder * decoder);
love::audio::Source * newSource();
int getNumSources() const;
int getMaxSources() const;
void play(love::audio::Source * source);
void play(love::audio::Sound * sound);
void play(love::audio::Music * music);
void play();
void stop(love::audio::Source * source);
void stop();
void pause(love::audio::Source * source);
void pause();
void resume(love::audio::Source * source);
void resume();
void rewind(love::audio::Source * source);
void rewind();
void setVolume(float volume);
float getVolume() const;
}; // Audio
} // openal
} // audio
} // love
#endif // LOVE_AUDIO_OPENAL_AUDIO_H
+136
View File
@@ -0,0 +1,136 @@
/**
* Copyright (c) 2006-2009 LOVE Development Team
*
* This software is provided 'as-is', without any express or implied
* warranty. In no event will the authors be held liable for any damages
* arising from the use of this software.
*
* Permission is granted to anyone to use this software for any purpose,
* including commercial applications, and to alter it and redistribute it
* freely, subject to the following restrictions:
*
* 1. The origin of this software must not be misrepresented; you must not
* claim that you wrote the original software. If you use this software
* in a product, an acknowledgment in the product documentation would be
* appreciated but is not required.
* 2. Altered source versions must be plainly marked as such, and must not be
* misrepresented as being the original software.
* 3. This notice may not be removed or altered from any source distribution.
**/
#include "Music.h"
// STD
#include <iostream>
namespace love
{
namespace audio
{
namespace openal
{
Music::Music(Pool * pool, love::sound::Decoder * decoder)
: pool(pool), decoder(decoder), source(0)
{
decoder->retain();
alGenBuffers(NUM_BUFFERS, buffers);
}
Music::~Music()
{
decoder->release();
alDeleteBuffers(NUM_BUFFERS, buffers);
}
love::audio::Music * Music::clone()
{
return new Music(pool, decoder->clone());
}
void Music::play(love::audio::Source * s)
{
source = pool->find(s);
if(source)
{
for(int i = 0; i < NUM_BUFFERS; i++)
{
if(!stream(buffers[i]))
{
std::cout << "Could not stream music." << std::endl;
return;
}
}
alSourceQueueBuffers(source, NUM_BUFFERS, buffers);
}
}
void Music::update(love::audio::Source * s)
{
if(source)
{
// Number of processed buffers.
ALint processed;
alGetSourcei(source, AL_BUFFERS_PROCESSED, &processed);
while(processed--)
{
ALuint buffer;
// Get a free buffer.
alSourceUnqueueBuffers(source, 1, &buffer);
if(stream(buffer))
alSourceQueueBuffers(source, 1, &buffer);
}
}
}
void Music::stop(love::audio::Source * s)
{
if(source)
{
ALuint bufs[NUM_BUFFERS];
alSourceStop(source);
alSourceUnqueueBuffers(source, NUM_BUFFERS, bufs);
source = 0;
}
}
void Music::rewind(love::audio::Source * s)
{
// Stop source, unqueue buffers.
stop(s);
// Rewind data pointer.
decoder->rewind();
// Requeue buffers.
play(s);
}
bool Music::stream(ALuint buffer)
{
// Get more sound data.
int decoded = decoder->decode();
int fmt = pool->getFormat(decoder->getChannels(), decoder->getBits());
if(fmt == 0)
return false;
if(decoded > 0)
{
alBufferData(buffer, fmt, decoder->getBuffer(),
decoder->getSize(), decoder->getSampleRate());
return true;
}
return false;
}
} // openal
} // audio
} // love
+73
View File
@@ -0,0 +1,73 @@
/**
* Copyright (c) 2006-2009 LOVE Development Team
*
* This software is provided 'as-is', without any express or implied
* warranty. In no event will the authors be held liable for any damages
* arising from the use of this software.
*
* Permission is granted to anyone to use this software for any purpose,
* including commercial applications, and to alter it and redistribute it
* freely, subject to the following restrictions:
*
* 1. The origin of this software must not be misrepresented; you must not
* claim that you wrote the original software. If you use this software
* in a product, an acknowledgment in the product documentation would be
* appreciated but is not required.
* 2. Altered source versions must be plainly marked as such, and must not be
* misrepresented as being the original software.
* 3. This notice may not be removed or altered from any source distribution.
**/
#ifndef LOVE_AUDIO_OPENAL_MUSIC_H
#define LOVE_AUDIO_OPENAL_MUSIC_H
// LOVE
#include <audio/Music.h>
#include <sound/Decoder.h>
#include "Pool.h"
// OpenAL
#include <AL/alc.h>
#include <AL/al.h>
namespace love
{
namespace audio
{
namespace openal
{
// Forward declarations.
class Audio;
class Music : public love::audio::Music
{
private:
static const unsigned int NUM_BUFFERS = 32;
ALuint buffers[NUM_BUFFERS];
Pool * pool;
love::sound::Decoder * decoder;
ALuint source;
public:
Music(Pool * pool, love::sound::Decoder * decoder);
virtual ~Music();
// Implements Audible.
void play(love::audio::Source * source);
void update(love::audio::Source * source);
void stop(love::audio::Source * source);
void rewind(love::audio::Source * source);
// Implements Music.
love::audio::Music * clone();
private:
bool stream(ALuint buffer);
}; // Sound
} // openal
} // audio
} // love
#endif // LOVE_AUDIO_OPENAL_MUSIC_H
+237
View File
@@ -0,0 +1,237 @@
/**
* Copyright (c) 2006-2009 LOVE Development Team
*
* This software is provided 'as-is', without any express or implied
* warranty. In no event will the authors be held liable for any damages
* arising from the use of this software.
*
* Permission is granted to anyone to use this software for any purpose,
* including commercial applications, and to alter it and redistribute it
* freely, subject to the following restrictions:
*
* 1. The origin of this software must not be misrepresented; you must not
* claim that you wrote the original software. If you use this software
* in a product, an acknowledgment in the product documentation would be
* appreciated but is not required.
* 2. Altered source versions must be plainly marked as such, and must not be
* misrepresented as being the original software.
* 3. This notice may not be removed or altered from any source distribution.
**/
#include "Pool.h"
#define MUTEX_ASSERT(fn, sval) \
if(fn != sval) \
{ \
std::cout << "Mutex lock/unlock failure. " << SDL_GetError() << std::endl; \
exit(-1); \
} \
#define LOCK(m) MUTEX_ASSERT(SDL_mutexP(m), 0)
#define UNLOCK(m) MUTEX_ASSERT(SDL_mutexV(m), 0);
namespace love
{
namespace audio
{
namespace openal
{
Pool::Pool()
{
// Generate sources.
alGenSources(NUM_SOURCES, sources);
// Create the mutex.
mutex = SDL_CreateMutex();
if(alGetError() != AL_NO_ERROR)
throw love::Exception("Could not generate sources.");
// Make all sources available initially.
for(int i = 0; i < NUM_SOURCES; i++)
available.push(sources[i]);
}
Pool::~Pool()
{
SDL_DestroyMutex(mutex);
std::map<love::audio::Source *, ALuint>::iterator i = playing.begin();
while(i != playing.end())
{
i->first->stop();
i->first->release();
i++;
}
// Free all sources.
alDeleteSources(NUM_SOURCES, sources);
}
ALenum Pool::getFormat(int channels, int bits) const
{
if(channels == 1 && bits == 8)
return AL_FORMAT_MONO8;
else if(channels == 1 && bits == 16)
return AL_FORMAT_MONO16;
else if(channels == 2 && bits == 8)
return AL_FORMAT_STEREO8;
else if(channels == 2 && bits == 16)
return AL_FORMAT_STEREO16;
else
return 0;
}
bool Pool::isAvailable() const
{
bool has = false;
LOCK(mutex);
has = !available.empty();
UNLOCK(mutex);
return has;
}
ALuint Pool::claim(love::audio::Source * source)
{
ALuint s = 0;
LOCK(mutex);
if(!available.empty())
{
// Get the first available source.
s = available.front();
// Remove it.
available.pop();
// Insert into map of playing sources.
playing.insert(std::pair<love::audio::Source *, ALuint>(source, s));
// Retain the source.
source->retain();
}
UNLOCK(mutex);
return s;
}
void Pool::release(love::audio::Source * source)
{
LOCK(mutex);
ALuint s = findi(source);
if(s != 0)
{
available.push(s);
playing.erase(source);
source->release();
}
UNLOCK(mutex);
}
ALuint Pool::find(const love::audio::Source * source) const
{
ALuint r = 0;
LOCK(mutex);
r = findi(source);
UNLOCK(mutex);
return r;
}
bool Pool::isPlaying(love::audio::Source * s)
{
bool p = false;
LOCK(mutex);
for(std::map<love::audio::Source *, ALuint>::iterator i = playing.begin(); i != playing.end(); i++)
{
if(i->first == s)
p = true;
}
UNLOCK(mutex);
return p;
}
void Pool::update()
{
LOCK(mutex);
std::map<love::audio::Source *, ALuint>::iterator i = playing.begin();
while(i != playing.end())
{
if(i->first->isFinished())
{
// Stop the source.
i->first->stop();
// Make it available.
available.push(i->second);
// Remove if from the playing list.
playing.erase(i++);
}
else
{
i->first->update();
i++;
}
}
UNLOCK(mutex);
}
int Pool::getNumSources() const
{
return playing.size();
}
int Pool::getMaxSources() const
{
return NUM_SOURCES;
}
void Pool::stop()
{
LOCK(mutex);
for(std::map<love::audio::Source *, ALuint>::iterator i = playing.begin(); i != playing.end(); i++)
i->first->stop();
UNLOCK(mutex);
}
void Pool::pause()
{
LOCK(mutex);
for(std::map<love::audio::Source *, ALuint>::iterator i = playing.begin(); i != playing.end(); i++)
i->first->pause();
UNLOCK(mutex);
}
void Pool::resume()
{
LOCK(mutex);
for(std::map<love::audio::Source *, ALuint>::iterator i = playing.begin(); i != playing.end(); i++)
i->first->resume();
UNLOCK(mutex);
}
void Pool::rewind()
{
LOCK(mutex);
for(std::map<love::audio::Source *, ALuint>::iterator i = playing.begin(); i != playing.end(); i++)
i->first->rewind();
UNLOCK(mutex);
}
ALuint Pool::findi(const love::audio::Source * source) const
{
std::map<love::audio::Source *, ALuint>::const_iterator i = playing.find((love::audio::Source *)source);
if(i != playing.end())
return i->second;
return 0;
}
} // openal
} // audio
} // love

Some files were not shown because too many files have changed in this diff Show More