Magento 1.5.x удаление заказов

20 сентября, 2011 1 комментарий

При переносе проекта на другой хостинг, понадобилось удалить все заказы из magento, так как они были сделаны в тестовых целях. Оказалось, что в стандартных действия в админ панели magento нет удаления заказов. По соображениям разработчиков этого чудесного движка такая функция не доступна для заказов.

Поискав немного в интернете обнаружил немалое количество расширений, позволяющих удалять заказы, но все они оказались платные. Выход один — чистить руками в базе данных. Но какие таблицы необходимо почистить?

Ответ на этот вопрос я обнаружил на одном сайте: http://www.myscienceisbetter.info/delete-test-orders-in-magento-1-5-x.html

Итак, чтобы почистить заказы, нужно выполнить такой вот хитрый запрос:

SET FOREIGN_KEY_CHECKS=0;
 
TRUNCATE `sales_flat_order`;
TRUNCATE `sales_flat_order_address`;
TRUNCATE `sales_flat_order_grid`;
TRUNCATE `sales_flat_order_item`;
TRUNCATE `sales_flat_order_status_history`;
TRUNCATE `sales_flat_quote`;
TRUNCATE `sales_flat_quote_address`;
TRUNCATE `sales_flat_quote_address_item`;
TRUNCATE `sales_flat_quote_item`;
TRUNCATE `sales_flat_quote_item_option`;
TRUNCATE `sales_flat_order_payment`;
TRUNCATE `sales_flat_quote_payment`;
TRUNCATE `sales_flat_shipment`;
TRUNCATE `sales_flat_shipment_item`;
TRUNCATE `sales_flat_shipment_grid`;
TRUNCATE `sales_flat_invoice`;
TRUNCATE `sales_flat_invoice_grid`;
TRUNCATE `sales_flat_invoice_item`;
TRUNCATE `sendfriend_log`;
TRUNCATE `tag`;
TRUNCATE `tag_relation`;
TRUNCATE `tag_summary`;
TRUNCATE `wishlist`;
TRUNCATE `log_quote`;
TRUNCATE `report_event`;
 
ALTER TABLE `sales_flat_order` AUTO_INCREMENT=1;
ALTER TABLE `sales_flat_order_address` AUTO_INCREMENT=1;
ALTER TABLE `sales_flat_order_grid` AUTO_INCREMENT=1;
ALTER TABLE `sales_flat_order_item` AUTO_INCREMENT=1;
ALTER TABLE `sales_flat_order_status_history` AUTO_INCREMENT=1;
ALTER TABLE `sales_flat_quote` AUTO_INCREMENT=1;
ALTER TABLE `sales_flat_quote_address` AUTO_INCREMENT=1;
ALTER TABLE `sales_flat_quote_address_item` AUTO_INCREMENT=1;
ALTER TABLE `sales_flat_quote_item` AUTO_INCREMENT=1;
ALTER TABLE `sales_flat_quote_item_option` AUTO_INCREMENT=1;
ALTER TABLE `sendfriend_log` AUTO_INCREMENT=1;
ALTER TABLE `sales_flat_order_payment` AUTO_INCREMENT=1;
ALTER TABLE `sales_flat_quote_payment` AUTO_INCREMENT=1;
ALTER TABLE `sales_flat_shipment` AUTO_INCREMENT=1;
ALTER TABLE `sales_flat_shipment_item` AUTO_INCREMENT=1;
ALTER TABLE `sales_flat_invoice` AUTO_INCREMENT=1;
ALTER TABLE `sales_flat_invoice_grid` AUTO_INCREMENT=1;
ALTER TABLE `sales_flat_invoice_item` AUTO_INCREMENT=1;
ALTER TABLE `sales_flat_shipment_grid` AUTO_INCREMENT=1;
ALTER TABLE `tag` AUTO_INCREMENT=1;
ALTER TABLE `tag_relation` AUTO_INCREMENT=1;
ALTER TABLE `tag_summary` AUTO_INCREMENT=1;
ALTER TABLE `wishlist` AUTO_INCREMENT=1;
ALTER TABLE `log_quote` AUTO_INCREMENT=1;
ALTER TABLE `report_event` AUTO_INCREMENT=1;
 
-- lets reset customers
TRUNCATE `customer_address_entity`;
TRUNCATE `customer_address_entity_datetime`;
TRUNCATE `customer_address_entity_decimal`;
TRUNCATE `customer_address_entity_int`;
TRUNCATE `customer_address_entity_text`;
TRUNCATE `customer_address_entity_varchar`;
TRUNCATE `customer_entity`;
TRUNCATE `customer_entity_datetime`;
TRUNCATE `customer_entity_decimal`;
TRUNCATE `customer_entity_int`;
TRUNCATE `customer_entity_text`;
TRUNCATE `customer_entity_varchar`;
TRUNCATE `log_customer`;
TRUNCATE `log_visitor`;
TRUNCATE `log_visitor_info`;
 
ALTER TABLE `customer_address_entity` AUTO_INCREMENT=1;
ALTER TABLE `customer_address_entity_datetime` AUTO_INCREMENT=1;
ALTER TABLE `customer_address_entity_decimal` AUTO_INCREMENT=1;
ALTER TABLE `customer_address_entity_int` AUTO_INCREMENT=1;
ALTER TABLE `customer_address_entity_text` AUTO_INCREMENT=1;
ALTER TABLE `customer_address_entity_varchar` AUTO_INCREMENT=1;
ALTER TABLE `customer_entity` AUTO_INCREMENT=1;
ALTER TABLE `customer_entity_datetime` AUTO_INCREMENT=1;
ALTER TABLE `customer_entity_decimal` AUTO_INCREMENT=1;
ALTER TABLE `customer_entity_int` AUTO_INCREMENT=1;
ALTER TABLE `customer_entity_text` AUTO_INCREMENT=1;
ALTER TABLE `customer_entity_varchar` AUTO_INCREMENT=1;
ALTER TABLE `log_customer` AUTO_INCREMENT=1;
ALTER TABLE `log_visitor` AUTO_INCREMENT=1;
ALTER TABLE `log_visitor_info` AUTO_INCREMENT=1;
 
-- Now, lets Reset all ID counters
TRUNCATE `eav_entity_store`;
ALTER TABLE `eav_entity_store` AUTO_INCREMENT=1;
 
SET FOREIGN_KEY_CHECKS=1;

Установка нескольких версий PHP на Apache (Ubuntu)

20 сентября, 2011 6 комментариев

С выходом ветки PHP 5.3 при разработке проектов мы стали ориентироваться на эту версию, к тому же клиенты стали активно обновлять свои хостинги. Однако, большинство проектов было написано под PHP 5.2.x и адаптировать их под новую версию языка не всегда представляется возможным. В связи с этим возникла необходимость установить на компьютере разработчика как минимум две версии PHP (5.2.x и 5.3.x), чтобы они работали на одном сервере Apache.

Одним из популярных способов решения этой проблемы является подключение одной версий PHP к апачу как FastCGI приложение, а другой — обычным способом — как модуль Apache.

Один мой друг написал мануал по настройке сервера таким механизмом. Он призводил установку PHP с Apache на сервер Debian. Эти же шаги легко адаптировать на любую ветку Unix. Я производил настройку Ubuntu 11.04. Итак, руководствуясь инструкцией из блога, делаем настройку.

Для начала нужно определиться, какую версию PHP ставить как модуль, а какую подключать как FastCGI. В репозитории Ubuntu 11.04 по умолчанию идет PHP версии 5.3.5. Таким образом, эту версию можно установить «стандартным» способом как модуль apache.

Теперь, установим PHP 5.2.x, а именно соберем ее из исходников. Скачать ее можно отсюда:  http://us3.php.net/get/php-5.2.17.tar.bz2/from/a/mirror

Последняя версия ветки 5.2 на данный момент — 5.2.17. В результате получится файл php-5.2.17.tar.gz. Распакуем его командой:

tar xzvf php-5.2.17.tar.gz

Установим необходимые для компиляции библиотеки:

apt-get install libxml2-dev libmysqlclient-dev libcurl4-gnutls-dev libcurl4-openssl-dev libpng12-dev libjpeg62-dev

Подготовим PHP  к сборке:

./configure --prefix=/opt/php5.2 \
--with-config-file-path=/opt/php5.2 \
--with-mysqli \
--with-mysql \
--with-curl \
--with-gd \
--with-jpeg \
--with-jpeg-dir \
--enable-cli \
--enable-fastcgi \
--enable-discard-path \
--enable-force-cgi-redirect

Здесь хочу отметить, что Ubuntu поругалась на отсутствие двух библиотек libpng.so и lingjpeg.so. На само деле они установлены, но сами файлы библиотек PNG и JPEG включают номер версии. В моем случае это были:

libpng12.so

libjpeg.so.62

Для устранения ошибки достаточно создать символические ссылки с нужным именем:

ln -s /usr/lib/libjpeg.so.62 libjpeg.so

ln -s /usr/lib/libpng12.so libpng.so

Теперь скомпилируем и установим PHP:

make

make install

Если у apache не установлен модуль для работы с FastCGI установим его:

apt-get install libapache2-mod-fastcgi

a2enmod fastcgi

Для удобства активируем модуль apache mod_actions:

a2enmod actions

Теперь создадим SH-скрипт, который будет запускать CGI приложение PHP для обработки скриптов:

vi /usr/lib/cgi-bin/php52-cgi

Запишем туда, следующие строчки:

#!/bin/sh
PHPRC="/opt/php5.2/"
export PHPRC
PHP_FCGI_CHILDREN=4
export PHP_FCGI_CHILDREN
PHP_FCGI_MAX_REQUESTS=5000
export PHP_FCGI_MAX_REQUESTS
exec /opt/php5.2/bin/php-cgi

Дадим этому скрипту права на запись:

chmod +x /usr/lib/cgi-bin/php5-cgi

Создадим конфигурационный файл для apache с настройками обработчика PHP скриптов, нужно сказать серверу, что скрипты должны обрабатываться CGI-приложение PHP 5.2:

vi /etc/apache2/php52.conf

Пропишем там следующее:

<FilesMatch "\.php">
SetHandler application/x-httpd-php5
</FilesMatch>
ScriptAlias /php52-cgi /usr/lib/cgi-bin/php52-cgi
Action application/x-httpd-php5 /php52-cgi
AddHandler application/x-httpd-php5 .php

Вот и все, теперь достаточно в настройках виртуального хоста добавить импорт php52.conf файла  и для этого хоста будет работать PHP 5.2:

<VirtualHost *.80>
........................................
Include php52.conf
.........................................
</VirtualHost>

Применение Sales Rules в Magento 1.5.x

Так получилось, что последние два проекта на работе были связаны с написанием интернет магазинов на популярном движке magento. Вся сложность заключалась в том, что дизайн, полученный от клиента никак не вписывался в «стандартный» движок magento. Более того в некоторых местах необходимо изменить обыкновенную логику движка, не влезая при этом в код. В связи с этим пришлось решить ряд проблем.

Одной из таких проблем стало применение Sales Rules в ShoppingCart. Добавление, изменение количества и удаление товара было реализовано с помощью ajax.  Для этого были созданы внешние PHP скрипты, использующие классы magento. Здесь возникла проблема. После отработки ajax скрипта и обновлении данных shopping cart к ценам товаров не применяются правила скидок (SalesRules). После продолжительных поисков в сторону решения наткнулся на одну статью. Оказывается, правила скидок применяются в ценам по определенным событиям специальными объектами (Observers). И работают они в backend’е и frontend’е по-разному в зависимости от того, в каком окружении (areas) происходит работа (frontend, admin).

Простейший Ajax скрипт выглядит следующим образом:

include_once 'app/Mage.php'; // подключение файла ядра
$app = Mage::app(); // инициализация приложения
Mage::app()->getLocale()->setLocale('nl_NL');
Mage::app()->getTranslator()->init('frontend', true);
..........................................................

Подключается основной файл ядра magento, инициализируется приложение, а далее выполняются необходимые действия. Например, для добавления товара в карту происходит следующее:

$session = Mage::getSingleton('core/session', array('name'=>'frontend'));
$cart = Mage::helper('checkout/cart')->getCart();
......................................................
$cart->addProduct($product, $qty);
$session->setLastAddedProductId($product->getId());
$session->setCartWasUpdated(true);
$cart->save();
......................................................

Очевидно в этом случае, magento грузит observer’ы которые прописаны в config.xml в разделе. Таким образом, чтобы решить проблему, надо «указать magento» в каком окружении мы хотим работать:

Mage::app()->loadArea($area);

В данном случае это FRONTEND. Для этого необходимо сразу после инициализации приложения добавить строку такого вида:

Mage::app()->loadArea(Mage_Core_Model_App_Area::AREA_FRONTEND);

Ruby on Rails ActionMailer Inline Attachments

Для одного проекта на Ruby on Rails 2.3.x понадобилось отправлять письмо, внутри которого должна находиться картинка со ссылкой. К сожалению, средстами простого ActionMailer добиться такого результата не удалось. Картинка упорно приходит просто как вложение в письмо. Основательно поискав информацию в интернете решил испольвать gem inline_attachements. Что же нужно сделать, чтобы это работало?..

Для начала нужно установить сам gem:

sudo gem install inline_attachments

Далее нутри метода отправки письма в ActionMailer указываем inlint_attachment:

def notify()
.....................
inline_attachment :content_type=&gt;'image/jpg', :body=&gt;File.read("#{RAILS_ROOT}/public/images/banner_mail.jpg"),
:filename=&gt;'banner.jpg'
end

content_type указывает на mime тип прикрепляемого файла

filename — имя файла, по которому он будет доступен внутри письма

Теперь, осталось только в теле письма прописать ссылку на эту картинку. Я обычно создаю view файл для сообщения в каталоге view/ActionMailer_Name/ActionName.html.erb, внутри которого можно добавить следующую конструкцию:

<a href="<%=@url%>"><%= image_tag "banner_mail.jpg", :border=>0 %> </a>

Удаление папок .svn из проекта в Ubuntu

По долгу службы все разрабатываемые проекты у меня хранятся в репозитории SVN. Иногда, бывает необходимо получить «чистую» копию проекта из локального репозитория. Конечно, можно воспользоваться функцией svn export, но это не всегда бывает удобно. Иногда, я просто копирую содержимое репозитория и стираю служебные папки svn. Чтобы сделать это для всего проекта в ubuntu, необходимо выполнить команду вида:

rm -rf `find . -type d -name .svn`

Програмный resize изображения

Понадобилось програмно изменить размеры изображения из своей программы. Программа работает под управлением ОС Ubuntu.

Для решения этой задачи можно воспользоваться утилитой ImageMagick. Он позволяет производить множество действий с изображением. В том числе и изменять размеры. К тому же, похоже, она входит в дистрибутив Ubuntu. По крайней мере она уже был установлена на моем Ubuntu.

Итак, чтобы изменить изображение необходимо выполнить команду:


convert -resize widthxheight source-image destanation-image


Если нужно,  отресайзить изображение бех сохранения aspect ratio, можно использовать команду:


convert -geometry widthxheight!  source-image destanation-image

Выполнение команд при запуске Ubuntu

23 июня, 2010 1 комментарий

После некоторого времени работы в Ubuntu появилась необходимость при запуске ОС выполнять некоторые консольные команды. Эти команды предназначены для выполнения определенных действий необходимых для работы демона. Поискав немного в Интернете, я обнаружил довольно простой способ, как это можно сделать.

Можно создать SH скрипт, поместить его в /etc/init.d/ и сконфигурировать на запуск утилитой update-rc.d.

Например,


sudo vi /etc/init.d/local.autostart

Эта команда создат файл local.autostart в /etc/init.d/. Сюда можно помещать любые терминальные команды. И этот скрипт должен начинаться с


#!/bin/sh

Теперь необходимо проставить скрипту права на запуск:

sudo chmod +x /etc/init.d/local.autostart

И наконец, сконфигурировать систему, чтобы наш скрипт запускался при загрузке ОС:


sudo update-rc.d local.autostart defaults 80

Все, при следующей загрузке системы все команды, помещенные в local.startup, будут выполнены.

IE и expression

30 марта, 2010 1 комментарий

Решив недавно задачу с применением CSS параметров max-width и max-height для Internet Exlorer’ов я очень обрадовался. И, как оказалось, весьма поспешно.

В предыдущую задачу входило поставить ограничения  на максимальную ширину и высоту для изображений на странице.  Соответственно, проблему можно решить поставив с CSS max-width и max-height для тэга IMG. Все отлично работает, однако, если на странице довольно много изображений, Internet Explorer повисает на прочь (у некоторых даже наблюдалось полнейшнее повисание компьютера). В поисках решения наткнулся на одну запись в дневнике: http://lusever.livejournal.com/15868.html. Оказывается:

Есть несколько особенностей у expression:

  • выполняется постоянно, если не переопределить CSS–свойство;
  • выполняется мгновенно;
  • ключевое слово this необязательно, выражение this.style равносильно простому style;
  • работают комментарии /* */, несмотря на то, что мы находимся внутри css;
  • можно использовать внешние функции или библиотеки, если они объявлены или подключены в html;
  • пробелы могут вызывать ошибку, хотя такое встречается редко;

«на каждое движение мышки по странице или выполнение JavaScript–кода происходит пересчет expression. Избежать пересчета удастся, просто переопределив фильтр в начале выражения:»

.button1, .button2, .button3, .button4
{ filter: expression( runtimeStyle.filter = 'alpha(opacity='+currentStyle.opacity*100+')' ) }

/** выдержки из статьи (Автор: Палсеич)**/

Вот как оказывается не все так просто. Последовав совету, я немного позанимался с runtime Style, и все получилось. Вот, что в итоге выходит для max-width и max-height:

.good img {
    max-height: 140px;
    max-width:140px;
    height : expression(runtimeStyle.height = this.offsetHeight  > 140 ? "140px" : "auto");
    width:expression(runtimeStyle.width = this.width > 140? "140px":  "auto" );
}
Рубрики:HTML Метки: , , ,

MAX-WIDTH в IE6

В текущем проекте на работе возникла необходимость обрезать изображение, если его ширина превышает определенное значение. При этом никак нельзя изменять параметры в верстке. Как вариант можно было на уровне скрипта PHP  при генерации тэга IMG проверять размеры картинки, и в зависимости от ее размера подставлять соответствующий стиль. Однако, хочется более элегантного решения. Такое вполне можно организовать с помощью CSS.

Существует параметр max-width, который корректно обрабатывается всеми современными броузерами. Достаточно указать максимальную ширину, и изображение будет автоматически ресайзиться:

#element img {max-width:800px}

Однако для IE6 такая конструкция уже не пройдет. Погуглив немного обнаружил конструкцию, которая прилично обрабатывается даже на ранних версиях IE, начиня с 5.0:

#element img {width:expression(document.body.clientWidth > 440? "440px": "auto" );}

Подробнее об expression можно почитать здесь

Рубрики:HTML Метки: , , ,

Создание демона (службы) в Linux

2 марта, 2010 2 комментария

Чего я никак не мог предположить, так это того, что на моей работе мне представится возможность или скорее появится необходимости писать что-нибудь под linux. Однако такое событие произошло. Несмотря на то, что по долгу службы я являюсь PHP-разработчиком (веб-разработчиком) мне «предложили» написать утилиту под Ubuntu для начинающегося проекта. И не просто утилиту а демона — службу под linux. Еще пару лет назад подобного рода задача могла бы испугать меня. Но только не теперь. Тем более что для разработки под Linux совсем необязательно иметь специфическое программное обеспечение. Компилятор C++ уже имеется. Однако я давно собирался попробовать кросс платформенную среду для разработки ПО Lazarus. И я решил создавать демона на FreePascal.

Итак, здесь я попытаюсь показать пример создания простейшего демона в Lazarus.

Структура основной программы выглядит также, как и обыкновенного консольного приложения:

program mydaemon;
{$mode objfpc}{$H+}
uses
{$IFDEF UNIX}{$IFDEF UseCThreads}
cthreads,
{$ENDIF}{$ENDIF}
SysUtils
Begin
End.

Основная идея при создании демона заключается в следующем: создается еще один экземпляр приложения в памяти а текущая программа завершается. Таким образом и стартует демон. Для реализации этого подхода используется функция fpFork. Она создает копию текущего процесса и возвращает:

  • PID, если процесс успешно создан;
  • -1, если возникла ошибка при создании процесса;
  • 0, если это уже копия процесса (потомок).

Таким образом старт демона осуществляется при помощи несложных операций:

pid := fpFork;
case pid of
0 : begin { we are in the child }
Close(input); { close standard in }
Assign(input,'/dev/null');
ReWrite(input);
Close(output); { close standard out }
Assign(output,'/dev/null');
ReWrite(output);
Close(stderr); { close standard error }
pid:=fpGetPid;
end;
-1 :begin
WriteLn('forking error, so halt 1');
halt(1);
end;
else begin
Halt;          { successful fork, so parent dies }
end;

При запуске программы мы делаем копию нашего процесса, и если это прошло успешно, завершаем работы (попадаем в ветку case else). Дочерний же процесс начинает свою работу, попадая в ветку case 0 и следует далее по коду программы. Теперь демон переходит в режим ожидания и ждет сигнала, после которого он активизируется и выполнит определенные действия. В простейшем случае это можно организовать в виде цикла:

while not bTerm do
begin
......
end;

Этот цикл будет выполняться до тех пор пока не придет сигнал об уничтожении. Теперь необходимо научить демон принимать внешние сигналы от ОС. Для этого создадим функцию, которая будет обрабатывать сигналы:

procedure DoSig(sig : longint);cdecl;
begin
case sig of
SIGTERM : bTerm := true;
end;
end;

И теперь перенаправим обработку сигналов на эту функцию:

{$hints off}
FpsigEmptySet(zerosigs);
{$hints on}
{ set global daemon booleans }
bTerm := false;

{ block all signals except -TERM }
sSet := $ffffbffe;
ps1 := @sSet;
fpsigprocmask(sig_block,ps1,nil);

{ setup the signal handlers }
new(aOld);
new(aTerm);
aTerm^.sa_handler{.sh} := SigactionHandler(@DoSig);
aTerm^.sa_mask := zerosigs;
aTerm^.sa_flags := 0;
fpSigAction(SIGTERM,aTerm,aOld)

Теперь, если наш демон получит сигнал об уничтожении sigTerm, он будет завершен. Остается придумать механизм запуска и остановки демона. Сейчас я реализовал это довольно простым способом. При запуске демона проверяется какой параметр ему передан. Если start, то форким, создаем во временной директории файл daemonname.lock и пишем туда pid демона. Если же в качестве параметра передан stop открываем файл daemonname.lock, читаем pid, убиваем процесс с таким pid, удалем lock файл. Однако, вероятно, это не лучшее решение. Поэтому предстоит еще провести исследование в этом направлении.

Полный код демона:

program mydaemon;

{$mode objfpc}{$H+}

uses
{$IFDEF UNIX}{$IFDEF UseCThreads}
cthreads,
{$ENDIF}{$ENDIF}
SysUtils,BaseUnix, logger, mydb, VideoRecorder, socketserver;

Var
{ vars for daemonizing }
bTerm : boolean;
aOld,
aTerm: pSigActionRec;
ps1  : psigset;
sSet : cardinal;
pid  : pid_t;
zerosigs : sigset_t;
status: integer;
secs : longint;
FileEngine:TLogger;
err: LongInt;
counter:integer;
db:TMyDB;
Socket:TSocketServer;
CurrentQueue:TQueueInfo;
{ handle SIGTERM }
procedure DoSig(sig : longint);cdecl;
begin
case sig of
SIGTERM : bTerm := true;
end;
end;

procedure RunDaemon();
var
Player:TVideoRecorder;
begin
db:=TMyDB.Create('localhost', 'root', 'college', 'daemon');
writeln('Connecting...');
if not db.ConnectToDatabase then
begin
writeln('Error connection to database:');
writeln(db.getError());
FileEngine.WriteLog(db.getError);
halt;
exit;
end;
{$hints off}
FpsigEmptySet(zerosigs);
{$hints on}
{ set global daemon booleans }
bTerm := false;

{ block all signals except -TERM }
sSet := $ffffbffe;
ps1 := @sSet;
fpsigprocmask(sig_block,ps1,nil);

{ setup the signal handlers }
new(aOld);
new(aTerm);
aTerm^.sa_handler{.sh} := SigactionHandler(@DoSig);

aTerm^.sa_mask := zerosigs;
aTerm^.sa_flags := 0;
fpSigAction(SIGTERM,aTerm,aOld);
{ daemonize }
pid := fpFork;
case pid of
0 : begin { we are in the child }
Close(input); { close standard in }
Assign(input,'/dev/null');
ReWrite(input);
Close(output); { close standard out }
//Assign(output,'dpsoutput.log');
//ReWrite(output);
Assign(output,'/dev/null');
ReWrite(output);
Close(stderr); { close standard error }
pid:=fpGetPid;
FileEngine.Lock(pid);
writeln('Daemon Started');
end;
-1 :begin
WriteLn('forking error, so halt 1');
halt(1);
end;
else begin
Halt;          { successful fork, so parent dies }
end;
end;
FileEngine.WriteLog('Daemon start');
{ begin processing loop }
counter:=0;
Player:=TVideoRecorder.Create;
repeat
//Some actions
until bTerm;
Player.Free;
FileEngine.UnLock;
FileEngine.WriteLog('Daemon terminated');
db.Free;
end;

Begin
{Init File Engine}
FileEngine:=TLogger.Create('test');
{**Check for superuser rights**}
{ if fpGetUID&lt;&gt;0 then
begin
Writeln('Error: Need superuser rights');
halt;
end;}
{****}
if ParamStr(1)='start' then
begin
if FileEngine.isLockFileExists then
begin
WriteLn('Process already running');
halt;
end;
Writeln('Startin Daemon...');
RunDaemon;
end
else if ParamStr(1)='stop' then
begin
writeln('Stoping daemon');
if FileEngine.isLockFileExists then
begin
pid:=FileEngine.getPID;
if fpkill(pid, SIGTERM) &lt; 0 then
begin
err := fpGetErrno;
case err of
ESysEsrch:
begin
Writeln(stderr,'Porcces with PID='+IntToStr(pid)+' not exists');
FileEngine.UnLock;
end;
ESysEperm: Writeln(stderr,'Permissions to kill process denied');
end;
end
else
begin
Writeln(stderr,'Daemon stopped');
end;
end
else
Writeln('Daemon is not running');
end
else writeln('Usage: ./mydaemon start|stop|restart');
End.