26.04.2010
Считаю что Java у Вас уже установлена. В противном случае – это тема отдельной статьи, которую вскорости может быть напишу. У меня Java установлена тут
$ /usr/local/diablo-jdk1.6.0
Для сборки сервера red5 нам потребуется Apache Ant, который можно легко поставить из портов:
$ cd /usr/ports/devel/apache-ant
$ make install clean
Теперь нам нужны исходники red5, чекаутим их с официального сайта примерно следующим образом:
$ mkdir /home/red5
$ svn co http://red5.googlecode.com/svn/java/server/trunk /home/red5
Теперь соберем его
Процесс на 2-3 минуты. Должны поставиться всякие там jar, а те которых нет, подкачаться и также поставиться. Создадим рабочую директорию Red5 и перенесем туда только что собраный сервер:
$ mkdir /usr/share/red5
$ cp -R /home/red5/dist/* /usr/share/red5
На всякий случай:
$ chmod 755 /usr/share/red5/red5.sh
Исправляем shell:
$ ee /usr/share/red5/red5.sh
/bin/bash -> /bin/sh
Делаем пускач:
$ touch /usr/local/etc/rc.d/red5.sh
#!/bin/sh
RED5_DIR=/usr/share/red5
test -x $RED5_DIR/red5.sh || exit 5
case "$1" in
start)
cd "$RED5_DIR"
"$RED5_DIR"/red5.sh &
sleep 2
;;
stop)
echo Shutting down Red5
killall java
sleep 2
;;
restart)
$0 stop
$0 start
;;
esac
Запускаем Red5 и проверяем открытость портов:
$ /usr/local/etc/rc.d/red5.sh start
$ netstat -ant
...
tcp4 0 0 *.5080 *.* LISTEN
tcp4 0 0 *.1935 *.* LISTEN
tcp4 0 0 *.51724 *.* LISTEN
tcp4 0 0 *.9999 *.* LISTEN
...
Все гуд. Контрольный выстрел:
$ telnet name-server 5080 или http://name-server:5080
Вот вроде и все – сервер собран, установлен и запущен (дефолтные настройки). Вам осталось накрутить конфиги Red5 под свои нужды (не забываем после этого сделать /usr/local/etc/rc.d/red5.sh restart).
ЗЫ: Правда надо еще поправить пускач, чтобы он стартовал Red5 при старте системы. Ну это на досуге как-нибудь
Комментарии
mandarin80:
01.02.2011 в 19:42
установил, но не запускается, в чем может быть проблема?
MrDekk:
01.02.2011 в 23:09
Добрый день!
Проблема может быть во многих вещах. Для того, чтобы я Вам мог подсказать по делу надо бы посмотреть логи.
Тайланд:
03.03.2011 в 00:05
У меня проблема в том, что red зависает, проблема решается только перезагрузкой, удалением файла red5.pid и запуском заново, что за фигня, кто знает?
MrDekk:
03.03.2011 в 18:14
Ну, вообще, выключать его правильно. Там есть скриптик, для Windows вроде stop.bat или shutdown.bat, для Unix: stop.sh или shutdown.sh – я не помню точно как называется. Если же это не помогает, то можно написать свой файлик, или скрипт запуска пополнить функцией анализа наличия pid и либо не делать дальше действий и просто сообщать, либо удалять его и проводить нормальный процесс запуска.
11.04.2010
Попалась мне тут намендни сложная задачка. Надо к разрабатываемой программе прикрутить программный софтфон для SIP (VOIP). Несколько дней с гуглом ничего толком не дали, пока однажды не наткнулся (хвала опять же гуглу :) ) на один проект, который хостится опять же на гугле :) . Названием ему SipekSdk. О нем то и пойдет сегодня речь. Сегодня я покажу как написать свой софтфон.
Для разработки будем ипользовать Visual Studio 2008 Express Edition. Почему именно EE – потому что он легальный. Впрочем Вы можете пользоваться той редакцией и версией студии, которая Вам по душе.
Для начала создадим новый проект.
- Откройте Visual Studio и выполните File/New/Project
- Выберите тип проекта Visual C#/Windows Application
- В поле имени введите какое-нибудь имя, например SoftPhone
- Выберите место на диске где он у Вас будет сохранен
- Нажмите ОК
Проект создаться и Вы должны увидеть дизайнер окна Form1. Это хорошо. Если что-то не получилось – ищите ошибку или почитайте документацию по студии.
Далее накидаем несколько компонентов на нашу форму. Нам потребуются
- TextBox с именем cs_Phone для ввода номера телефона
- TextBox с именем cs_RegState для вывода информации о регистрации
- TextBox с именем cs_CallState для вывода информации о звонке
- Две Label к cs_RegState и cs_CallState для пояснения
- Кнопка MakeCall с именем cs_MakeCall для совершения звонка
- Кнопка Release с именем cs_Release для того чтобы иметь возможность «Ложить трубку»
Получилось что-то подобное

Далее необходимо подключить SipekSdk, для этого необходимо проделать следующие действия:
- Скопируйте библиотеку SipekSdk.dll в папку проекта. Ее можно взять тут SipekSdk.dll
- В SolutionExplorer студии выберите Add Reference…
- В диалоге выберите закладку Browse, а в ней выберите файл SipekSdk.dll
- Жмите ОК.
Аналогичные действия надо проделать с библиотекой pjsipDll.dll, взять ее можно отсюдова pjsipDll.dll.
Кроме того, Вы можете собрать их самостоятельно.
Теперь нам нужно сконфигурировать эти библиотеки. Вообще SipekSdk содержит в себе только интерфейсы, которые мы должны имплементировать. Нас в данном случае будут интересовать два интерфейса:
- IConfigurationInterface. Насколько я понял – основной конфигурационный интерфейс.
- IAccount. Настройки конкретного аккаунта.
Итак
- Создаем новый класс. Правый клик в SolutionExplorer/Add/New item…
- Выберите Class и введите имя, например rc_PhoneCfg
- Откроется новый файл. Вы можете удалить его содержание, если там оно присутствует и Вы этого хотите.
-
Добавьте включение
-
Теперь определите интерфейс
internal class rc_PhoneCfg : IConfigurationInterface
- Имплементируйте стандартные методы. Студия Вам в этом поможет.
-
Студия добавит Вам везде
throw new Exception("The method or operation is not implemented.");
- Пока оставьте, исправим позже
- Теперь аналогичным образом имплементируйте интерфейс IAccount, пусть класс будет rc_AccountCfg
- Попробуйте скомпилировать. Должно быть все ОК.
Теперь добавим кой чего полезного
-
Добавьте список аккаунтов в rc_PhoneCfg
List< IAccount > v_slAccList = new List< IAccount>( );
internal rc_PhoneCfg( )
{
v_slAccList.Add( new rc_AccountCfg( ) );
}
-
Определите свойство Accounts
public List< IAccount> Accounts
{
get
{
return v_slAccList;
}
}
-
Остальные свойства определите следующим образом (свойства set везде пусть будут set { } )
CFBFlag = false;
CFBNumber = "";
CFNRFlag = false;
CFNRNumber = "";
CFUFlag = false;
CFUNumber = "";
public List< String > CodecList
{
get
{
List< String > slCodecs = new List< String >( );
slCodecs.Add( "PCMA" );
return slCodecs;
}
set {}
}
DNDFlag = false;
DefaultAccountIndex = 0;
IsNull = false;
PublishEnabled = false;
SIPPort = 5060;
То же самое сделайте в классе rc_AccountCfg. Введите правильные настройки.
AccountName = "3000";
DisplayName = "3000";
DomainName = "*";
Enabled = true;
HostName = "10.91.25.22";
Id = "3000";
Index = 0;
Password = "admin";
ProxyAddress = "";
RegState = 0;
TransportMode = ETransportMode.TM_UDP;
UserName = "3000";
Теперь займемся главной формой. Дальше весь код пишется в главной форме Form1, имейте ввиду.
Добавляем импорты
using Sipek.Common;
using Sipek.Common.CallControl;
using Sipek.Sip;
Реализуем несколько свойств
#region properties
CCallManager CallManager
{
get
{
return CCallManager.Instance;
}
}
private rc_PhoneCfg v_hPhoneCfg = new rc_PhoneCfg( );
internal rc_PhoneCfg Config
{
get
{
return v_hPhoneCfg;
}
}
private IStateMachine v_hCall = null;
#endregion
Теперь мы готовы зарегистрировать функции обратного вызова. Делаем в конструкторе
CallManager.CallStateRefresh += new DCallStateRefresh( CallManager_CallStateRefresh );
pjsipRegistrar.Instance.AccountStateChanged += new DAccountStateChanged( Instance_AccountStateChanged );
Обработчики реализуем попозже
Теперь мы готовы инициализировать систему Sipek. Для этого делаем следующие шаги
-
Присваиваем
CallManager.StackProxy = pjsipStackProxy.Instance;
-
Отправляем настройки в систему
CallManager.Config = Config;
pjsipStackProxy.Instance.Config = Config;
pjsipRegistrar.Instance.Config = Config;
-
Инициализируем
CallManager.Initialize( );
-
И пытаемся зарегистрироваться на сервере
pjsipRegistrar.Instance.registerAccounts( );
Теперь реализуем обработчики. Чтобы избежать проблему синхронизации потоков, будем использовать Invoke.
#region callbacks
void Instance_AccountStateChanged( Int32 iAccountId, Int32 iAccState )
{
if ( InvokeRequired )
this.BeginInvoke( new DAccountStateChanged( OnRegistrationUpdate ), new Object[ ] { iAccountId, iAccState } );
else
OnRegistrationUpdate( iAccountId, iAccState );
}
void CallManager_CallStateRefresh( Int32 iSessionId )
{
if ( InvokeRequired )
this.BeginInvoke( new DCallStateRefresh( OnStateUpdate ), new Object[ ] { iSessionId } );
else
OnStateUpdate( iSessionId );
}
#endregion
И синхронизированные обработчики
#region synchronized callbacks
private void OnRegistrationUpdate( Int32 iAccountId, Int32 iAccState )
{
cs_RegState.Text = iAccState.ToString( );
}
private void OnStateUpdate( Int32 iSessionId )
{
cs_CallState.Text = CallManager.getCall( iSessionId ).StateId.ToString( );
}
#endregion
И обработчики нажатия кнопок
private void cs_MakeCall_Click( Object hSender, EventArgs hArgs )
{
v_hCall = CallManager.createOutboundCall( cs_Phone.Text );
}
private void cs_Release_Click( Object hSender, EventArgs hArgs )
{
cs_Phone.Clear( );
CallManager.onUserRelease( v_hCall.Session );
}
Теперь если Вы правильно ввели HostName, UserName и Password в rc_AccountCfg, ваш (или не Ваш) SIP сервер запущен и работает, то в поле RegState вы должны увидеть 200, что означает что ваш софтфон успешно зарегистрировался на SIP сервере.
Набирайте в cs_Phone номер и нажимайте MakeCall. Удачных телефонных переговоров.
Комментарии со старой версии блога
Nevin:
03.11.2010 в 00:55
Спасибо за статью. единственное замечание: IConfigurationInterface в сегодняшней версии библиотеки называется IConfiguratorInterface
Alex:
17.11.2010 в 22:33
Спасибо! Отличное руководство =)
На этапе «Теперь мы готовы зарегистрировать функции обратного вызова.» не понятно где делать в конструкторе (где этот констркутор?):
allManager.CallStateRefresh += new DCallStateRefresh( CallManager_CallStateRefresh );
pjsipRegistrar.Instance.AccountStateChanged += new DAccountStateChanged( Instance_AccountStateChanged );
Прокомментируйте поподробней пожалуйста.
С Уважением, Alex
MrDekk:
17.11.2010 в 22:49
Я имел в виду конструктора формы. Можете скачать исходники моих экспериментов вот тут вот Надеюсь это Вам поможет в Ваших изысканиях.
Всегда рад помочь
MrDekk:
17.11.2010 в 22:50
И да – пост про IConfiguratorInterface очень верный. Теперь он действительно так называется.
Koks:
21.11.2010 в 08:08
Вроде получилось, регистрируется и звонит, но никак не реагирует на входящий вызов( в чем может быть проблема? Исходники скачал те что выложил автор.
MrDekk:
21.11.2010 в 13:53
Честно говоря я сам не до конца понял как реагировать на входящий вызов. Глубокий дебаг библиотеки показал, что она реагирует на входящий вызов, но делегат почему-то не вызывает.
Проблема видимо в настройках каких-то, которые мы не учли, либо в недрах библиотеки.
Koks:
21.11.2010 в 21:02
Самое интересное что и sipek2 вроде бы законченный телефон тоже не реагирует.
Koks:
21.11.2010 в 21:23
А нельзя соорудить какой нибудь костыль что бы получать входящие? Просто очень надо =)
Сейчас скачаю сырцы библиотеки посмотреть.
MrDekk:
21.11.2010 в 23:44
sipek2 на основе этой же библиотеки написан. Я не рылся в этом направлении – для моей задачи были нужны только исходящие звонки.
С входящими пробовал – но так ничего и не добился.
Если найдете что-то интересное – дайте знать пожалуйста.
Koks:
23.11.2010 в 04:13
Только что починил, пересоздав свой евент.
В классе CallManager добавил
Form OnForm = null;
public delegate void IncCallHandler(int SessionId, string Number,string Info);
delegate void IncDelegate(int SessionId, string Number, string Info);
private void IncEvent(int SessionId, string Number, string Info)
{
if (OnForm.InvokeRequired)
{
IncDelegate Invoker = new IncDelegate(IncEvent);
OnForm.Invoke(Invoker, new object[] { SessionId, Number,Info });
}
else
{
IncCall(SessionId,Number,Info);
}
}
public void On_Form(Form ParentForm)
{
OnForm = ParentForm;
}
public event IncCallHandler IncCall;
Дальше изменил там же
private void OnIncomingCall(int sessionId, string number, string info)
{
IStateMachine call = this[sessionId];
//if (call.IsNull) return;
// inform automaton for incoming call
call.State.incomingCall(number, info);
// call callback
IncEvent(sessionId, number, info);
}
Теперь когда создаем класс
Делаем еще вот так
CallManager.On_Form(this);
CallManager.IncCall += new CCallManager.IncCallHandler(IncCaller);
И там например
private void IncCaller(int SessionId, string number, string info)
{
cs_CallState.Text = number;
}
Все работает.
Koks:
23.11.2010 в 04:51
Не работает еще кнопка ответа, если кто найдет как починить буду благодарен.
Koks:
23.11.2010 в 05:29
Разбираться в дебрях библиотеки было лень, поэтому вот атким костылем можно и отвечать)
Sipek.Sip.pjsipCallProxy.dll_answerCall(0, 200);
0 это номер сессии
Koks:
23.11.2010 в 05:34
Теперь еще одна проблема, со звуком он не дружит только у меня?
Viktor:
15.01.2011 в 21:52
А с какими серверами вы работаете? я вот что-то совсем не могу подружить его с 3CX сервером… ни в какую не хочет регистрироваться… Может кто-нить что подскажет?
MrDekk:
16.01.2011 в 11:32
Ну лично я работал с Asterisk. Все работало.
Viktor:
16.01.2011 в 14:26
еще вопрос: что значит regState 171101? нигде не смог найти описания…
MrDekk:
17.01.2011 в 12:08
171101 я честно говоря не знаю.
А по поводу 3СХ сервера, если бы Вы рассказали проблему и ее решение – было бы оочень замечательно.
elg:
14.02.2011 в 13:31
А под вистой/семеркой работает?
Почему-то не слышно звука от собеседника. Связано ли с тем, что SipekSdk использует WaveLibMixer, а он не поддерживается в Vista? Можно ли как-то решить эту проблему?
MrDekk:
16.02.2011 в 15:31
У меня под семеркой работает нормально. Под вистой не пробовал если честно.
Могу посоветовать только проверить настройки в панели управления. У меня были проблемы с микрофоном. Но эти проблемы к SipekSdk не имеют вообще никакого отношения.
Удачи в делах.
jasja1:
01.03.2011 в 03:23
Запускал на Win7, результат – нулевой, не могу добиться даже регистрации на сервере. Думал дело в ОС, запустил на ВМ WinXP – та же ситуация. Софтфон от 3CX – работает нормально.. перепробовал уже много вариантов.. Буду очень рад, если кто-нибудь даст дельный совет, в чем может быть проблема
MrDekk:
01.03.2011 в 09:14
Ну можно попробовать. Если Вы выполните два условия:
- Опишите проблему – что конкретно у Вас не получается
- Выложите проблемный код
Тогда будет возможность Вам чем-то помочь.
jasja1:
01.03.2011 в 19:48
- не получается зарегистрироваться на сервере – после запуска программы абсолютно ничего не происходит
- код был полностью взят из исходника, c настроенным интерфейсом IAccountCfg:
AccountName="100"
DisplayName="100"
DomainName="*""
Enabled=true
HostName="192.168.199.1"
id="100"
Index=0
Password="qwerty"
ProxyAddress=""
RegState=0
TransportMode=ETransportMode.TM_TCP
UserName="100"
Установлен и настроен сервер 3cx (Sip порт 5060, Публичный IP: 192.168.199.1).
Добавлен абонент (Внутренний номер 100 Имя 100 Фамилия 100 ID=100 пароль qwerty)
После запуска программы регистрация на сервере не проходит. Лог сервера чист.
Соответственно пробовал софтфоны 3cx и X-Lite 4 – с аналогичными настройками все работает..
jasja1:
01.03.2011 в 20:06
Часть лога программы
17:55:29.607 pjsua_core.c 1 SIP worker threads created
17:55:29.607 pjsua_core.c pjsua version 1.2 for win32 initialized
17:55:29.611 pjsua_core.c SIP UDP socket reachable at 192.168.0.100:5060
17:55:29.611 udp055775A0 SIP UDP transport started, published address is 192.168.0.100:5060
17:55:29.611 pjsua_acc.c Account added with id 0
17:55:29.611 tcplis SIP TCP listener destroyed
17:55:29.611 pjsua_core.c Error creating SIP TCP listener: Address already in use (WSAEADDRINUSE) [status=130048]
Откуда берется IP 192.168.0.100? + решил для эксперимента поменять порт в интерфейсе IPhoneCfg на 5070, на сервере порт остался прежним.. и регистрация прошла – RegState 200.
Не могу понять логику)
MrDekk:
03.03.2011 в 18:12
Address already in use случается тогда, когда вы биндите сокет (socket bind) на порт, который уже занят (уже был бинд от другого приложения). Поэтому у Вас не получалось приконнектится (видимо какой-то софтфон был запущен и он биндил адрес). Когда Вы адрес поменяли, то все работало.
Чтобы работало без смены порта можно сделать следующее
int on = 1;
int s = socket( ... )
if ( setsockopt( s, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on)) < 0)
{
// случилась ошибка
}
Ну или запускать с нестандартным портом…
Алексей:
22.03.2011 в 00:27
Каким вы сервером пользуетесь??? Я запускаю программу и сервер(какой-то нашел сиповский) и никакой реакции, IP указал 127.0.0.1, пробовал и тот что получают от роутера, ничего не даёт. Никакой реакции по нажатию на кнопки. Обьясните что и как тут вообще??? и что вводить в поле имени кому звонить?
MrDekk:
22.03.2011 в 19:23
Я пользовался Asterisk’ом. Ставил на сервер и даже звонил через ТФОП.
Дмитрий:
28.04.2011 в 19:29
Привет, MrDekk.
Очень помогла ваша звонилка. Есть одно «НО». pjsipDLL написан на C++ и когда я пытаюсь запустить приложение под вистой или семеркой x64 возникает ошибка «An attempt was made to load a program with an incorrect format» при попытке обращения к pjsipDLL. Быстро решить эту проблему я не смог, поэтому пишу здесь. Если есть идеи, то я был бы очень благодарен.
Дмитрий:
28.04.2011 в 19:35
Забыл написать.
Нашел это
http://blogs.msdn.com/b/arvindsh/archive/2009/06/21/tip-of-the-day-an-attempt-was-made-to-load-a-program-with-an-incorrect-format-net-p-invoke-issue.aspx
Долго втыкал, но самостоятельно разобраться не смог. Возможно в этом тесте есть решение проблемы, ноя настолько пень ,что не могу им воспользоваться. Хелп плз.
Заранее большое спасибо.
MrDekk:
29.04.2011 в 14:12
В настройках компиляции .net проектов вместо ANY CPU поставьте x86 – все должно заработать.
Дмитрий:
04.05.2011 в 20:48
Спасибо. С этим справился.
Вообще не звонит на windows 7.
После выполнения
CallManager.createOutboundCall(txtPhone.Text);
событие CallStateRefresh не наступает вообще.
В чем может быть беда?
MrDekk:
04.05.2011 в 21:51
Ну, файерволл у Вас есть? Может быть в нем беда. Вообще, мне кажется где-то что-то не дает пройти соединению. Можете попробовать включить native дебаггер и пройтись внутрь sipeksdk.
Дмитрий:
05.05.2011 в 16:37
Буду писать сюда о своих действиях, вдруг у кого-то возникнут идеи как мне помочь. Итак, проблема все та же: не работает наш любимый софтфон под вин 7.
Нашел это:
http://groups.google.com/group/sipek/browse_thread/thread/ca47464ac4dbdb9f?pli=1
Выкачал исходники SipekSDK. В них упомянутой ссылки на WaveLibMixer вообще нет. Добавил в свой проект сборку SipekSDK, чтобы было проще отлаживаться. При отладке наткнулся на следующее.
Итак мы жмем на кнопку «позвонить», вызывается
v_hCall = CallManager.createOutboundCall(txtPhone.Text);
Проследовал по обработке OutboundCall вплоть до следующей строчки во враппере для pjsipDLL:
SessionId = dll_makeCall(Config.Accounts[accountId].Index, sipuri);
Здесь получаю SessionId = -1, что приводит к окончанию обработки звонка. То есть под висту (7) почему-то не работает dll_makeCall из pjsipDLL. Попробовал погуглить эту беду ,пока безрезультатно. Может быть у кого-то запускается вся эта радость на висте или семерке? приму любую помощь.
MrDekk:
05.05.2011 в 20:48
Вы native-дебаггером в pjsip.dll пробовали заходить?
Дмитрий:
06.05.2011 в 12:38
Debug->Options->Native. Выставил галочки на Load DLL Imports и Enable RPC Debugging.
После этого я должен иметь возможность заглянуть дебаггером внутрь pjsipDLL? Может быть у меня урезанная студия (хотя нет – вроде Ultimate), но я пройти внутрь pjsipDLL не могу. Что я делаю не так?
MrDekk:
06.05.2011 в 13:24
В настройках запускаемого шарпового проекта в закладке Debug внизу есть опция Enable Debuggers, там надо поставить галочку напротив Enable unmanaged code debugging. После этого вам нужны исходники pjsip, либо хотя бы pdb файл. Тогда у Вас будет возможность заглянуть внутрь Pjsip.dll
Дмитрий:
07.06.2011 в 16:02
На всякий случай оставляю комментарий, если у кого будут похожие проблемы.
Итак беда с Виндоус 7 связана с pjsipDLL, которую мы скачиваем. Я выкачал исходники pjsipDLL и пересобрал библиотеку по указаниям отсюда http://sites.google.com/site/sipekvoip/Home/documentation/pjsipwrapper/pjsipwrapper-for-windows
После этого под семеркой нормально зазвонило.
Богдан:
15.07.2013 в 17:56
Ответ на звонки полностью работоспособен!
Вы забыли реализовать свойство bool AAFlag.
Оно отвечает за автоответ, и проверяется при входящем звонке.
Если его реализовать все будет хорошо, и не нужно ничего в либе менять.
08.04.2010
Как и обещал продолжаю цикл заметок о замене Windows на FreeBSD на почти серверной машине. Сегодняшняя наша цель – подключить виндовый раздел к фре. Сразу стоит отмести ту мысль, что можно было все перевести на ufs и не мучаться. Тут не все так просто, раздел этот размером 1Тб, с заполнением примерно но 80%. Второго такого винта не нашлось для временного перелива информации, поэтому была поставлена задача запустить его под фрей «как есть».
Проблема первая – непонятно какая на нем файловая система (всмысле FAT32 или NTFS). Создавался этот раздел давно и никто уже не помнит. Проблема решается просто – грузимся с любого виндового LiveCD и каким-нибудь Акронисом смотрим. У меня оказалась NTFS. Рекомендую сделать это заранее, т.к. я потратил определенное время пытаясь смонтировать этот винт как FAT32.
Далее нам надо чтобы ядро у нас поддерживало определенную функциональность. Делаем
и смотрим чтобы в выдаче был модуль geom_mbr.ko. Если его нет, делаем следующие вещи
$ cd /usr/src/sys/modules/geom
$ make && make obj && make install clean
$ kldload geom_mbr
кроме того, идем в /boot/loader.conf и прописываем там автозапуск модуля
После этого у нас есть возможность видеть разделы в /dev у меня виндовый раздел был ad12s2s1. Далее так как система у нас NTFS надо надо организовать поддержку NTFS. Для этого воспользуемся fusefs. Идем в /usr/ports, делаем
$ cd /usr/ports/
$ make search name=’ntfs’
и идем в ту которая от fuse. после этого делаем стандартные
После этого надо прописать fusefs в автозагрузку. Для этого в /etc/rc.conf добавляем
# fusefs
fusefs_enable=»YES»
и запускаем
$ /usr/loca/etc/rc.d/fusefs start
Монтируем том
$ mkdir /d
$ ntfs-3g -o rw,locale=ru_RU.UTF-8 /dev/ad12s2s1 /d
Чтобы том автоматически подцеплялся при старте системы добавляем строчку в /etc/rc.conf после fusefs
# mount ntfs volume
/usr/local/bin/ntfs-3g -o rw,locale=ru_RU.UTF-8 /dev/ad12s2s1 /d
После этого
И наслаждаемся. Теперь у нас в фряхе подцеплен виндовый ntfs раздел. Могут быть проблемы с UTF-8 в консоли. Но – это тема следующих статей