794 lines
18 KiB
C
794 lines
18 KiB
C
/* $Id: start_prog.c,v 1.3 1997/04/10 23:32:19 luethje Exp $
|
||
*
|
||
* ISDN accounting for isdn4linux.
|
||
*
|
||
* Copyright 1996 by Michael 'Ghandi' Herold,
|
||
* Stefan Luethje (luethje@sl-gw.lake.de)
|
||
*
|
||
* This program is free software; you can redistribute it and/or modify
|
||
* it under the terms of the GNU General Public License as published by
|
||
* the Free Software Foundation; either version 2, or (at your option)
|
||
* any later version.
|
||
*
|
||
* This program is distributed in the hope that it will be useful,
|
||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||
* GNU General Public License for more details.
|
||
*
|
||
* You should have received a copy of the GNU General Public License
|
||
* along with this program; if not, write to the Free Software
|
||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||
*
|
||
* $Log: start_prog.c,v $
|
||
* Revision 1.3 1997/04/10 23:32:19 luethje
|
||
* Added the feature, that environment variables are allowed in the config files.
|
||
*
|
||
* Revision 1.2 1997/04/03 22:58:34 luethje
|
||
* some primitve changes.
|
||
*
|
||
* Revision 1.1 1997/03/16 20:58:55 luethje
|
||
* Added the source code isdnlog. isdnlog is not working yet.
|
||
* A workaround for that problem:
|
||
* copy lib/policy.h into the root directory of isdn4k-utils.
|
||
*
|
||
* Revision 2.3.27 1996/05/05 20:35:46 akool
|
||
*
|
||
* Revision 2.21 1996/03/13 11:58:46 akool
|
||
*/
|
||
|
||
|
||
#define _START_PROG_C_
|
||
#include "isdnlog.h"
|
||
#include <pwd.h>
|
||
#include <grp.h>
|
||
#include <sys/types.h>
|
||
|
||
/*************************************************************************/
|
||
|
||
static interval *RootIntervall = NULL;
|
||
|
||
/** Prototypes ***********************************************************/
|
||
|
||
static void KillCommand(int);
|
||
static int GetArgs(char *, char *[], char *[], int);
|
||
static interval *Next_Interval(void);
|
||
static int set_user(char *User);
|
||
static int set_group(char *Group);
|
||
|
||
/****************************************************************************/
|
||
|
||
static int set_user(char *User)
|
||
{
|
||
struct passwd* Ptr = NULL;
|
||
|
||
if (User == NULL || User[0] == '\0')
|
||
return 0;
|
||
|
||
setpwent();
|
||
|
||
while ((Ptr = getpwent()) != NULL)
|
||
{
|
||
if (!strcmp(Ptr->pw_name,User))
|
||
{
|
||
endpwent();
|
||
return setuid(Ptr->pw_uid);
|
||
}
|
||
}
|
||
|
||
endpwent();
|
||
return 0;
|
||
}
|
||
|
||
/****************************************************************************/
|
||
|
||
static int set_group(char *Group)
|
||
{
|
||
struct group* Ptr = NULL;
|
||
|
||
|
||
if (Group == NULL || Group[0] == '\0')
|
||
return 0;
|
||
|
||
setgrent();
|
||
|
||
while ((Ptr = getgrent()) != NULL)
|
||
{
|
||
if (!strcmp(Ptr->gr_name,Group))
|
||
{
|
||
endgrent();
|
||
return setgid(Ptr->gr_gid);
|
||
}
|
||
}
|
||
|
||
endgrent();
|
||
return 0;
|
||
}
|
||
|
||
/*************************************************************************
|
||
** Ring(-) - Externes Kommando ausfuehren oder loeschen. Bei einem Fehl- **
|
||
** er wird -1 zurueckgegeben; ansonsten die PID des neuen **
|
||
** Prozesses. Wenn das Kommando mit system() aufgerufen wur- **
|
||
** de (Async), wird -1 zurueckgegeben, da die PID nicht ge- **
|
||
** sichert werden muss. **
|
||
*************************************************************************
|
||
** Die : <= 0 Kommando ausfuehren. **
|
||
** > 0 PID killen. **
|
||
** Async: == 1 Kommando mit system() starten. **
|
||
** == 0 Kommando mit eigenem Prozess starten. **
|
||
*************************************************************************/
|
||
|
||
int Ring(info_args *Cmd, char *Opts[], int Die, int Async)
|
||
{
|
||
char Command[SHORT_STRING_SIZE + 1];
|
||
char String[LONG_STRING_SIZE];
|
||
int filedes[2];
|
||
char *Args[64];
|
||
pid_t pid;
|
||
FILE *fp;
|
||
|
||
print_msg(PRT_DEBUG_EXEC, "Ring: Cmd: `%s' Die: %d Async: %d\n", (Cmd&&Cmd->infoarg)?Cmd->infoarg:"NO COMMAND", Die, Async);
|
||
|
||
if (Die <= 0)
|
||
{
|
||
sprintf(Command,"%.*s",SHORT_STRING_SIZE-6,Cmd->infoarg);
|
||
|
||
|
||
/* Kommando soll gestartet werden - 'Async' gibt an, ob dieses */
|
||
/* mit system() oder mit einem eigenen Proze<7A> aufgerufen wer- */
|
||
/* den soll. */
|
||
|
||
if (GetArgs(Command,Args,Opts,64) == -1)
|
||
{
|
||
print_msg(PRT_ERR, "Can't start \"%s\" with execvp().\n", Args[0]);
|
||
return -1;
|
||
}
|
||
|
||
pipe(filedes);
|
||
switch (pid = fork())
|
||
{
|
||
case -1: print_msg(PRT_ERR, "%s\n", "Can't start fork()!");
|
||
return 0;
|
||
break;
|
||
case 0: if (paranoia_check(Args[0]) < 0)
|
||
exit(-1);
|
||
|
||
if (set_group(Cmd->group) < 0)
|
||
{
|
||
print_msg(PRT_ERR, "Can not set group %s: %s\n",Cmd->group,strerror(errno));
|
||
exit(-1);
|
||
}
|
||
|
||
if (set_user(Cmd->user) < 0)
|
||
{
|
||
print_msg(PRT_ERR, "Can not set user %s: %s\n",Cmd->user,strerror(errno));
|
||
exit(-1);
|
||
}
|
||
|
||
dup2(filedes[1],STDOUT_FILENO);
|
||
dup2(filedes[1],STDERR_FILENO);
|
||
|
||
execvp(Args[0], Args);
|
||
print_msg(PRT_ERR, "Can't start \"%s\" with execvp().\n", Args[0]);
|
||
/* Alarm(); */
|
||
exit(-1);
|
||
break;
|
||
}
|
||
|
||
fp = fdopen(filedes[0],"r");
|
||
close(filedes[1]);
|
||
|
||
print_msg(PRT_DEBUG_INFO, "Program \"%s\" \"%s\" started %ssynchronous.\n", Args[0], Args[1], (Async?"a":""));
|
||
|
||
if (Async == 1)
|
||
{
|
||
while(fgets(String,LONG_STRING_SIZE,fp) != NULL)
|
||
print_msg(PRT_PROG_OUT,"%s\n",String);
|
||
|
||
waitpid(pid,NULL,0);
|
||
fclose(fp);
|
||
return(0);
|
||
}
|
||
else
|
||
{
|
||
int sock;
|
||
|
||
if (add_socket(&sockets,filedes[0]))
|
||
return NO_MEMORY;
|
||
|
||
sock = socket_size(sockets)-1;
|
||
sockets[sock].fp = fp;
|
||
sockets[sock].pid = pid;
|
||
|
||
return sock;
|
||
}
|
||
}
|
||
else
|
||
{
|
||
KillCommand(Die);
|
||
return 0;
|
||
}
|
||
|
||
return(-1);
|
||
}
|
||
|
||
/*************************************************************************
|
||
** GetArgs(-) - Zerlegt eine Kommandozeile in einzelne Argumente. **
|
||
*************************************************************************/
|
||
|
||
static int GetArgs(char *Line, char *Args[], char *Opts[], int MaxArgs)
|
||
{
|
||
char *Arg = NULL;
|
||
char *Use = Line;
|
||
char *Ptr = NULL;
|
||
char *Org_Arg;
|
||
int MaxOpts= 0;
|
||
int i = 0;
|
||
int j = 0;
|
||
int Num = 0;
|
||
char HelpString[SHORT_STRING_SIZE];
|
||
static char **MemPtr = NULL;
|
||
|
||
if (MemPtr != NULL)
|
||
{
|
||
while(MemPtr[j] != NULL)
|
||
free(MemPtr[j++]);
|
||
|
||
free(MemPtr);
|
||
MemPtr = NULL;
|
||
j = 0;
|
||
}
|
||
|
||
while (Opts[MaxOpts] != NULL)
|
||
MaxOpts++;
|
||
|
||
while ((Org_Arg = Arg = strtok(Use, " \t")))
|
||
{
|
||
Use = NULL;
|
||
|
||
if (*Arg == '@')
|
||
{
|
||
FILE *fp = fopen(Arg+1,"r");
|
||
|
||
if (fp != NULL)
|
||
{
|
||
fgets(HelpString,SHORT_STRING_SIZE,fp);
|
||
|
||
if (*HelpString != '\0')
|
||
HelpString[strlen(HelpString)-1] = '\0';
|
||
|
||
Arg = strdup(HelpString);
|
||
|
||
MemPtr = (char**) realloc(MemPtr,sizeof(char*)*(j+2));
|
||
MemPtr[j++] = Arg;
|
||
MemPtr[j] = NULL;
|
||
fclose(fp);
|
||
}
|
||
else
|
||
Arg = NULL;
|
||
}
|
||
else
|
||
if (*Arg == '$' && Opts != NULL && (Num = atoi(Arg+1)) > 0 && Num <= MaxOpts)
|
||
Arg = Opts[Num-1];
|
||
|
||
if (Arg == NULL || *Arg == '\0')
|
||
{
|
||
if (Arg == NULL)
|
||
print_msg(PRT_WARN,"Invalid argument `%s' for program start!\n",Org_Arg);
|
||
|
||
Arg = "?";
|
||
}
|
||
|
||
Ptr = Arg;
|
||
while((Ptr = Check_Quote(Ptr, S_QUOTES, QUOTE_DELETE)) != NULL && Ptr[0] != '\0')
|
||
Ptr++;
|
||
|
||
if (i < MaxArgs) Args[i++] = Arg;
|
||
}
|
||
|
||
Args[i] = NULL;
|
||
|
||
return(i);
|
||
}
|
||
|
||
/*************************************************************************
|
||
** KillCommand(-) - Beendet ein Programm anhand seiner PID. **
|
||
*************************************************************************/
|
||
|
||
static void KillCommand(int sock)
|
||
{
|
||
char String[LONG_STRING_SIZE] = "";
|
||
/* Kein Erbarmen - Alles was uns zwischen die Finger kommt wird */
|
||
/* gel<65>scht :-) */
|
||
|
||
if (sock > 0)
|
||
{
|
||
while (fgets(String,LONG_STRING_SIZE,sockets[sock].fp))
|
||
print_msg(PRT_PROG_OUT,"%s\n",String);
|
||
|
||
kill(sockets[sock].pid, SIGTERM);
|
||
kill(sockets[sock].pid, SIGKILL);
|
||
|
||
/* ACHTUNG: Die naechste Zeile kann schwierigkeiten machen!!!
|
||
Der Prozess kann eventuell hier haengen bleiben. Dann Zeile
|
||
auskommentieren. Ich weiss nicht, ob kill den Prozess auch
|
||
sauber beendet. Damit keine Zombies rumfahren vorsichtshaber
|
||
der waitpid.
|
||
Alternativ: waitpid(sockets[sock].pid,NULL,WNOHANG) */
|
||
|
||
waitpid(sockets[sock].pid,NULL,0);
|
||
fclose(sockets[sock].fp);
|
||
del_socket(&sockets,sock);
|
||
}
|
||
}
|
||
|
||
/*************************************************************************
|
||
** Alarm(-) - Gibt ein Alarmsignal <20>ber den internen Lautsprecher aus. **
|
||
*************************************************************************/
|
||
|
||
void Alarm(void)
|
||
{
|
||
#ifdef ALARM
|
||
|
||
int FD;
|
||
int i;
|
||
|
||
if ((FD = open("/dev/console", O_WRONLY)) == -1) FD = 0;
|
||
|
||
for (i = 0; i < 30; i++)
|
||
{
|
||
ioctl(FD, KIOCSOUND, (3000 - (i * 10)));
|
||
|
||
usleep((1 * 1000));
|
||
}
|
||
|
||
ioctl(FD, KIOCSOUND, 0);
|
||
|
||
#endif
|
||
}
|
||
|
||
/*************************************************************************
|
||
** CheckTime(-) - Pr<50>ft ob die Zeitangabe in den lokalen Zeitrahmen **
|
||
** f<>llt. R<>ckgabe ist TRUE/FALSE. **
|
||
*************************************************************************/
|
||
|
||
int CheckTime(char *Line)
|
||
{
|
||
char Temp[SHORT_STRING_SIZE + 1];
|
||
char Time[24];
|
||
char *Use;
|
||
struct tm *tm_Time;
|
||
char *Arg;
|
||
char *Minus;
|
||
int i;
|
||
int r;
|
||
int Beg;
|
||
int End;
|
||
time_t Local;
|
||
|
||
if (Line == NULL || *Line == '\0')
|
||
return 1;
|
||
|
||
strncpy(Temp, Line, SHORT_STRING_SIZE);
|
||
|
||
for (i = 0; i < 24; i++) Time[i] = 0;
|
||
|
||
Use = Temp;
|
||
|
||
/* Zeile in die einzelnen Komponenten trennen, die durch ',', */
|
||
/* ' ' oder ';' voneinander getrennt sein k<>nnen. */
|
||
|
||
while ((Arg = strtok(Use, ", ;")))
|
||
{
|
||
Use = NULL;
|
||
|
||
if (*Arg == '*')
|
||
return 1;
|
||
|
||
if (!isdigit(*Arg))
|
||
{
|
||
print_msg(PRT_WARN, " Wrong time in `%s`: \"%s\"\n", CONFFILE, Arg);
|
||
continue;
|
||
}
|
||
|
||
if ((Minus = strchr(Arg, '-')))
|
||
{
|
||
*Minus++ = 0;
|
||
|
||
Beg = atoi(Arg);
|
||
End = atoi(Minus);
|
||
}
|
||
else
|
||
{
|
||
Beg = atoi(Arg);
|
||
End = Beg+1;
|
||
}
|
||
|
||
if ((Beg < 0) || (End < 0) || (Beg > 24) || (End > 25))
|
||
{
|
||
print_msg(PRT_WARN, "Time range not correct in `%s`: (%d-%d)\n", CONFFILE, Beg, End);
|
||
}
|
||
else
|
||
{
|
||
if (End <= Beg)
|
||
End += 24;
|
||
|
||
for (r = Beg; r < End; r++) Time[r%24] = 1;
|
||
}
|
||
}
|
||
|
||
/* Lokale Zeit errechnen und mit den Stunden im Zeitarray ver- */
|
||
/* gleichen. */
|
||
|
||
Local = time(NULL);
|
||
|
||
if ((tm_Time = localtime(&Local)) != NULL)
|
||
{
|
||
if (Time[tm_Time->tm_hour] == 1)
|
||
return(1);
|
||
}
|
||
else print_msg(PRT_ERR, "Can't get local time.\n");
|
||
|
||
return(0);
|
||
}
|
||
|
||
/****************************************************************************/
|
||
|
||
int Print_Cmd_Output( int sock )
|
||
{
|
||
char String[LONG_STRING_SIZE] = "";
|
||
|
||
|
||
if (feof(sockets[sock].fp))
|
||
{
|
||
KillCommand(sock);
|
||
return -1;
|
||
}
|
||
|
||
fgets(String,LONG_STRING_SIZE,sockets[sock].fp);
|
||
|
||
print_msg(PRT_PROG_OUT,"%s\n",String);
|
||
|
||
return 0;
|
||
}
|
||
|
||
/****************************************************************************/
|
||
|
||
int Get_Sock_From_Info_Args( info_args *Ptr, int Cnt )
|
||
{
|
||
if (socket_size(sockets) > Cnt || Cnt < 0)
|
||
while (sockets[Cnt].descriptor != -2)
|
||
if (sockets[Cnt].info_arg == Ptr)
|
||
return Cnt;
|
||
else
|
||
Cnt++;
|
||
|
||
return -1;
|
||
}
|
||
|
||
/****************************************************************************/
|
||
|
||
int Get_Sock_From_Call( int chan, int Cnt )
|
||
{
|
||
if (socket_size(sockets) > Cnt || Cnt < 0)
|
||
while (sockets[Cnt].descriptor != -2)
|
||
if (sockets[Cnt].chan == chan)
|
||
return Cnt;
|
||
else
|
||
Cnt++;
|
||
|
||
return -1;
|
||
}
|
||
|
||
/****************************************************************************/
|
||
|
||
int Get_Sock_From_Call_And_Info_Args( int chan, info_args *Ptr, int Cnt )
|
||
{
|
||
if (socket_size(sockets) > Cnt || Cnt < 0)
|
||
while (sockets[Cnt].descriptor != -2)
|
||
if (sockets[Cnt].chan == chan && sockets[Cnt].info_arg == Ptr)
|
||
return Cnt;
|
||
else
|
||
Cnt++;
|
||
|
||
return -1;
|
||
}
|
||
|
||
/****************************************************************************/
|
||
|
||
int Condition_Changed( int condition, int flag )
|
||
{
|
||
if ((flag & RING_CONNECT) || (flag & RING_RING))
|
||
{
|
||
if ((flag & RING_CONNECT) && condition == RING_CONNECT)
|
||
return 0;
|
||
|
||
if ((flag & RING_CONNECT) && condition == RING_AOCD)
|
||
return 0;
|
||
|
||
if ((flag & RING_CONNECT) && condition == RING_ERROR)
|
||
return 0;
|
||
|
||
if ((flag & RING_RING) && condition == RING_RING)
|
||
return 0;
|
||
|
||
if ((flag & RING_RING) && condition == RING_ERROR)
|
||
return 0;
|
||
|
||
return 1;
|
||
}
|
||
return 0;
|
||
}
|
||
|
||
/****************************************************************************/
|
||
|
||
const char *Set_Ringer_Flags( int condtion, int InOut )
|
||
{
|
||
char Char = 0;
|
||
static char RetCode[10];
|
||
|
||
if (InOut & RING_INCOMING) Char = 'I';
|
||
else
|
||
if (InOut & RING_OUTGOING) Char = 'O';
|
||
else
|
||
{
|
||
print_msg(PRT_ERR, "Error: Expected flag `I' or `O'!\n");
|
||
return NULL;
|
||
}
|
||
|
||
RetCode[0] = Char;
|
||
|
||
if (condtion & RING_RING ) Char = 'R';
|
||
else
|
||
if (condtion & RING_CONNECT ) Char = 'C';
|
||
else
|
||
if (condtion & RING_BUSY ) Char = 'B';
|
||
else
|
||
if (condtion & RING_AOCD ) Char = 'A';
|
||
else
|
||
if (condtion & RING_ERROR ) Char = 'E';
|
||
else
|
||
if (condtion & RING_HANGUP ) Char = 'H';
|
||
else
|
||
if (condtion & RING_KILL ) Char = 'K';
|
||
else
|
||
if (condtion & RING_SPEAK ) Char = 'S';
|
||
else
|
||
if (condtion & RING_PROVIDER) Char = 'P';
|
||
else
|
||
{
|
||
print_msg(PRT_ERR, "Internal error: Unknown flag %d for flag -S!\n",condtion);
|
||
return NULL;
|
||
}
|
||
|
||
RetCode[1] = Char;
|
||
RetCode[2] = '\0';
|
||
|
||
return RetCode;
|
||
}
|
||
|
||
/****************************************************************************/
|
||
|
||
int Start_Interval(void)
|
||
{
|
||
interval *Ptr = RootIntervall;
|
||
time_t cur_time = time(NULL);
|
||
int RetCode = 0;
|
||
|
||
while (Ptr != NULL)
|
||
{
|
||
if (Ptr->next_start <= cur_time)
|
||
{
|
||
RetCode += Start_Ring(Ptr->chan, Ptr->infoarg, Ptr->event, RING_INTERVAL);
|
||
Ptr->next_start = cur_time + Ptr->infoarg->interval;
|
||
}
|
||
|
||
Ptr = Ptr->next;
|
||
}
|
||
|
||
return RetCode;
|
||
}
|
||
|
||
/****************************************************************************/
|
||
|
||
static interval *Next_Interval(void)
|
||
{
|
||
interval *Ptr = RootIntervall;
|
||
interval *RetCode = NULL;
|
||
time_t next_time = 0;
|
||
|
||
while (Ptr != NULL)
|
||
{
|
||
if (next_time == 0 || Ptr->next_start < next_time)
|
||
{
|
||
next_time = Ptr->next_start;
|
||
RetCode = Ptr;
|
||
}
|
||
|
||
Ptr = Ptr->next;
|
||
}
|
||
|
||
return RetCode;
|
||
}
|
||
|
||
/****************************************************************************/
|
||
|
||
struct timeval *Get_Interval(int Sec)
|
||
{
|
||
static struct timeval timeout;
|
||
interval *Ptr = NULL;
|
||
|
||
|
||
timeout.tv_usec = 0;
|
||
|
||
if (Sec < 0)
|
||
Sec = 0;
|
||
|
||
if ((Ptr = Next_Interval()) != NULL || Sec != 0)
|
||
{
|
||
if (Ptr != NULL && (timeout.tv_sec = (int) (Ptr->next_start - time(NULL))) < 0)
|
||
timeout.tv_sec = 0;
|
||
else if (Sec)
|
||
/* if (Sec != 0 && Sec < timeout.tv_sec) AK:06-Jun-96 */
|
||
timeout.tv_sec = Sec;
|
||
}
|
||
else
|
||
return NULL;
|
||
|
||
return &timeout;
|
||
}
|
||
|
||
/****************************************************************************/
|
||
|
||
int Del_Interval(int chan, info_args *infoarg)
|
||
{
|
||
interval **Ptr = &RootIntervall;
|
||
interval *Ptr2;
|
||
|
||
while (*Ptr != NULL)
|
||
{
|
||
if ((*Ptr)->infoarg == infoarg && (*Ptr)->chan == chan)
|
||
{
|
||
Ptr2 = (*Ptr)->next;
|
||
free(*Ptr);
|
||
*Ptr = Ptr2;
|
||
return 0;
|
||
}
|
||
|
||
Ptr = &((*Ptr)->next);
|
||
}
|
||
|
||
return -1;
|
||
}
|
||
|
||
/****************************************************************************/
|
||
|
||
int New_Interval(int chan, info_args *infoarg, int event)
|
||
{
|
||
interval **Ptr = &RootIntervall;
|
||
|
||
if (infoarg->interval == 0)
|
||
return -1;
|
||
|
||
while (*Ptr != NULL)
|
||
Ptr = &((*Ptr)->next);
|
||
|
||
if ((*Ptr = (interval*) calloc(1,sizeof(interval))) == NULL)
|
||
return -1;
|
||
|
||
(*Ptr)->event = event;
|
||
(*Ptr)->infoarg = infoarg;
|
||
(*Ptr)->chan = chan;
|
||
(*Ptr)->next_start = infoarg->interval + time(NULL);
|
||
|
||
return 0;
|
||
}
|
||
|
||
/****************************************************************************/
|
||
|
||
int Start_Process(int chan, info_args *infoarg, int event)
|
||
{
|
||
char *Opts[4];
|
||
int InOut = call[chan].dialin?RING_INCOMING:RING_OUTGOING;
|
||
int sock = -1;
|
||
|
||
Opts[0] = (char*) Set_Ringer_Flags(event,InOut);
|
||
Opts[1] = call[chan].num[CALLING];
|
||
Opts[2] = call[chan].num[CALLED];
|
||
Opts[3] = NULL;
|
||
|
||
if ((infoarg->flag & event) && (infoarg->flag & InOut) &&
|
||
CheckTime(infoarg->time) && /* wenn die angegebene Zeit passt */
|
||
(sock = Ring(infoarg, Opts, 0, 0)) != -1 )
|
||
{
|
||
sockets[sock].info_arg = infoarg;
|
||
sockets[sock].chan = chan;
|
||
sockets[sock].call_event = event;
|
||
}
|
||
|
||
return sock<0?-1:0;
|
||
}
|
||
|
||
/****************************************************************************/
|
||
|
||
int Start_Ring(int chan, info_args *infoarg, int event, int intervalflag)
|
||
{
|
||
int ProcessStarted = 0;
|
||
char *Opts[4];
|
||
int InOut = call[chan].dialin?RING_INCOMING:RING_OUTGOING;
|
||
int f = infoarg->flag; /* die Flags zu diesem Eintrag */
|
||
int sock = 0;
|
||
|
||
Opts[0] = (char*) Set_Ringer_Flags(event,InOut);
|
||
Opts[1] = call[chan].num[CALLING];
|
||
Opts[2] = call[chan].num[CALLED];
|
||
Opts[3] = NULL;
|
||
|
||
if (intervalflag & RING_INTERVAL)
|
||
{
|
||
if (f & RING_KILL)
|
||
while ((sock = Get_Sock_From_Call_And_Info_Args(chan,infoarg,sock)) != -1)
|
||
if (sockets[sock].call_event == event)
|
||
Ring(NULL, NULL, sock++, 0);
|
||
else
|
||
sock++;
|
||
}
|
||
else
|
||
{
|
||
if (infoarg->interval != 0 && (event == RING_RING || event == RING_CONNECT))
|
||
New_Interval(chan, infoarg, event);
|
||
}
|
||
|
||
if (Condition_Changed(event,f))
|
||
{
|
||
while ((sock = Get_Sock_From_Call_And_Info_Args(chan,infoarg,sock)) != -1)
|
||
Ring(NULL, NULL, sock++, 0);
|
||
|
||
Del_Interval(chan,infoarg);
|
||
}
|
||
|
||
/* Wenn Event (siehe oben) passt, und INCOMING/OUTGOING passen */
|
||
|
||
if (!((f & RING_UNIQUE) &&
|
||
((event == RING_RING) || (event == RING_CONNECT) )) ||
|
||
Get_Sock_From_Call_And_Info_Args(chan,infoarg,0) == -1 )
|
||
{
|
||
if ((f & event) && (f & InOut) &&
|
||
CheckTime(infoarg->time) && /* wenn die angegebene Zeit passt */
|
||
(sock = Ring(infoarg, Opts, 0, 0)) != -1 )
|
||
{
|
||
sockets[sock].info_arg = infoarg;
|
||
sockets[sock].chan = chan;
|
||
sockets[sock].call_event = event;
|
||
ProcessStarted++;
|
||
}
|
||
}
|
||
|
||
return ProcessStarted;
|
||
}
|
||
|
||
/****************************************************************************/
|
||
|
||
int Change_Channel_Ring( int old_channel, int new_channel)
|
||
{
|
||
interval *Ptr = RootIntervall;
|
||
int sock = 0;
|
||
|
||
while ((sock = Get_Sock_From_Call( old_channel, sock )) >= 0)
|
||
{
|
||
sockets[sock].chan = new_channel;
|
||
}
|
||
|
||
while (Ptr != NULL)
|
||
{
|
||
if (Ptr->chan == old_channel)
|
||
Ptr->chan = new_channel;
|
||
|
||
Ptr = Ptr->next;
|
||
}
|
||
|
||
return 0;
|
||
}
|
||
|
||
/****************************************************************************/
|
||
|