*** empty log message ***
This commit is contained in:
parent
9693113f21
commit
3223e679cb
|
@ -1,4 +1,6 @@
|
|||
2009-01-04 P. A. Bagyenda <bagyenda@dsmagic.com>
|
||||
2010-01-25 P. A. Bagyenda <bagyenda@dsmagic.com>
|
||||
* SunOS locking fixes (thanks to Ian Donaldson (iand at ekit-inc.com)
|
||||
2010-01-04 P. A. Bagyenda <bagyenda@dsmagic.com>
|
||||
* Minor fix, throttling in MMSC VASP connections
|
||||
2009-12-01 P. A. Bagyenda <bagyenda@dsmagic.com>
|
||||
* Change queue location for MM1 notifications
|
||||
|
|
|
@ -71,7 +71,7 @@ dnl Change a few things (a la kannel config)
|
|||
EXE_EXT=""
|
||||
LIB_EXT="a"
|
||||
case "$host" in
|
||||
*-sun-solaris* | *SunOS*)
|
||||
*-sun-solaris* | *SunOS* | *-pc-solaris*)
|
||||
CFLAGS="$CFLAGS -DSunOS=1 -D_POSIX_PTHREAD_SEMANTICS"
|
||||
;;
|
||||
*-cygwin*)
|
||||
|
|
|
@ -178,7 +178,7 @@ static int mkdf(char df[64], char *mmbox_home)
|
|||
if (fd >= 0 &&
|
||||
mm_lockfile(fd,ctmp,1) != 0) {
|
||||
unlink(ctmp);
|
||||
close(fd);
|
||||
unlock_and_close(fd);
|
||||
fd = -1;
|
||||
}
|
||||
octstr_destroy(tmp);
|
||||
|
@ -202,7 +202,7 @@ static int open_mmbox_index(char *mmbox_dir, int shouldblock)
|
|||
fbuf, strerror(errno));
|
||||
break;
|
||||
} else if (mm_lockfile(fd, fbuf, shouldblock) != 0) {
|
||||
close(fd);
|
||||
unlock_and_close(fd);
|
||||
fd = -1;
|
||||
}
|
||||
while (i++ < MAXTRIES && fd < 0);
|
||||
|
@ -272,7 +272,7 @@ static int update_mmbox_index(int fd, char *mmbox_dir, int cmd,
|
|||
mms_error(0, "mmbox", NULL,"Failed lock temp file %s: error = %s\n",
|
||||
fbuf, strerror(errno));
|
||||
|
||||
close(tempfd);
|
||||
unlock_and_close(tempfd);
|
||||
tempfd = -1;
|
||||
goto done;
|
||||
|
||||
|
@ -284,7 +284,7 @@ static int update_mmbox_index(int fd, char *mmbox_dir, int cmd,
|
|||
|
||||
fbuf, strerror(errno));
|
||||
|
||||
close(tempfd);
|
||||
unlock_and_close(tempfd);
|
||||
tempfd = -1;
|
||||
goto done;
|
||||
}
|
||||
|
@ -434,17 +434,13 @@ Octstr *mms_mmbox_addmsg(char *mmbox_root, char *user, MmsMsg *msg, List *flag_c
|
|||
octstr_replace(sdf, octstr_imm("/"), octstr_imm("-"));
|
||||
done:
|
||||
if (dfd > 0)
|
||||
close(dfd);
|
||||
unlock_and_close(dfd);
|
||||
if (ifd > 0)
|
||||
close(ifd);
|
||||
unlock_and_close(ifd);
|
||||
|
||||
if (s)
|
||||
octstr_destroy(s);
|
||||
if (home)
|
||||
octstr_destroy(home);
|
||||
if (state)
|
||||
octstr_destroy(state);
|
||||
if (flags)
|
||||
gwlist_destroy(flags, (gwlist_item_destructor_t *)octstr_destroy);
|
||||
|
||||
return sdf;
|
||||
|
|
|
@ -21,8 +21,8 @@
|
|||
#include <ctype.h>
|
||||
#ifdef SunOS
|
||||
#include <strings.h>
|
||||
#include <fcntl.h>
|
||||
#endif
|
||||
#include <fcntl.h>
|
||||
#include <dirent.h>
|
||||
|
||||
#include "mms_queue.h"
|
||||
|
@ -208,7 +208,7 @@ static MmsEnvelope *mms_queue_readenvelope(char *qf, char *mms_queuedir, int sho
|
|||
octstr_destroy(fname);
|
||||
return NULL;
|
||||
} else if (mm_lockfile(fd, octstr_get_cstr(fname), shouldblock) != 0) {
|
||||
close(fd);
|
||||
unlock_and_close(fd);
|
||||
octstr_destroy(fname);
|
||||
return NULL;
|
||||
}
|
||||
|
@ -566,7 +566,7 @@ static int writeenvelope(MmsEnvelope *e, int newenv)
|
|||
close(fd); /* Close new one, keep old one. */
|
||||
res = -1;
|
||||
} else { /* On success, new descriptor replaces old one and we close old one. */
|
||||
close(qfs->fd);
|
||||
unlock_and_close(qfs->fd);
|
||||
qfs->fd = fd;
|
||||
}
|
||||
octstr_destroy(qfname);
|
||||
|
@ -630,7 +630,7 @@ static int mkqf(char qf[QFNAMEMAX], char subdir[64], char *mms_queuedir)
|
|||
if (fd >= 0 &&
|
||||
mm_lockfile(fd,ctmp,1) != 0) {
|
||||
unlink(ctmp);
|
||||
close(fd);
|
||||
unlock_and_close(fd);
|
||||
fd = -1;
|
||||
}
|
||||
octstr_destroy(tmp);
|
||||
|
@ -804,7 +804,7 @@ static int free_envelope(MmsEnvelope *e, int removefromqueue)
|
|||
snprintf(fname, -1 + sizeof fname, "%s/%s%s", qfs->dir, qfs->subdir, qfs->name);
|
||||
unlink(fname);
|
||||
}
|
||||
close(qfs->fd); /* close and unlock now that we have deleted it. */
|
||||
unlock_and_close(qfs->fd); /* close and unlock now that we have deleted it. */
|
||||
|
||||
mms_queue_free_envelope(e);
|
||||
|
||||
|
|
|
@ -20,6 +20,8 @@
|
|||
|
||||
#ifdef SunOS
|
||||
#include <fcntl.h>
|
||||
#include <pthread.h>
|
||||
#include <sys/types.h>
|
||||
#endif
|
||||
|
||||
#include <errno.h>
|
||||
|
@ -913,25 +915,203 @@ void mms_log(char *logmsg, Octstr *from, List *to,
|
|||
}
|
||||
|
||||
|
||||
static int lockfile(int fd, int shouldblock)
|
||||
/* Compare a file_lock(lhs) to the file_key(rhs)
|
||||
* and see if they match
|
||||
*/
|
||||
int file_lock_inode_cmp(void *_lhs, void *_rhs);
|
||||
|
||||
/* Each file gets a condition, there is only a single file_loc
|
||||
for each inode number. Assumes a uni
|
||||
*/
|
||||
typedef struct {
|
||||
dev_t dev;
|
||||
ino_t inode;
|
||||
} file_key;
|
||||
|
||||
typedef struct {
|
||||
file_key key;
|
||||
pthread_cond_t condition;
|
||||
int fd;
|
||||
} file_lock;
|
||||
|
||||
static List *openFileList = NULL;
|
||||
static pthread_mutex_t listMutex = PTHREAD_MUTEX_INITIALIZER;
|
||||
|
||||
void release_file_lock(int fd, file_key *key)
|
||||
{
|
||||
debug("mm_util",0,"----->Locked");
|
||||
pthread_mutex_lock(&listMutex);
|
||||
|
||||
if (openFileList == NULL) {
|
||||
openFileList = (List *)gwlist_create();
|
||||
}
|
||||
|
||||
file_lock *item = (file_lock*)gwlist_search(openFileList, key, file_lock_inode_cmp);
|
||||
if (item && item->fd == fd) {
|
||||
/* we own the lock */
|
||||
gwlist_delete_equal(openFileList, item);
|
||||
pthread_cond_broadcast(&item->condition);
|
||||
pthread_cond_destroy(&item->condition);
|
||||
gw_free(item);
|
||||
}
|
||||
debug("mm_util",0,"<-----UnLocked");
|
||||
pthread_mutex_unlock(&listMutex);
|
||||
}
|
||||
|
||||
int unlock_and_close(int fd)
|
||||
{
|
||||
int n, stop;
|
||||
#ifdef SunOS
|
||||
struct stat buf;
|
||||
if (fstat(fd, &buf)) {
|
||||
perror("Unable to fstat file for lock");
|
||||
return close(fd);
|
||||
}
|
||||
|
||||
file_key key;
|
||||
key.inode = buf.st_ino;
|
||||
key.dev = buf.st_dev;
|
||||
|
||||
release_file_lock(fd, &key);
|
||||
#endif
|
||||
|
||||
return close(fd);
|
||||
}
|
||||
|
||||
int unlock_and_fclose(FILE *fp)
|
||||
{
|
||||
#ifdef SunOS
|
||||
int fd = fileno(fp);
|
||||
struct stat buf;
|
||||
if (fstat(fd, &buf)) {
|
||||
perror("Unable to fstat file for lock");
|
||||
return fclose(fp);
|
||||
}
|
||||
|
||||
file_key key;
|
||||
key.inode = buf.st_ino;
|
||||
key.dev = buf.st_dev;
|
||||
|
||||
release_file_lock(fd, &key);
|
||||
#endif
|
||||
return fclose(fp);
|
||||
}
|
||||
|
||||
/* Compare a file_lock(lhs) to the file_key(rhs)
|
||||
and see if they match
|
||||
*/
|
||||
int file_lock_inode_cmp(void *_lhs, void *_rhs) {
|
||||
file_key *rhs = (file_key*)_rhs;
|
||||
file_lock *lhs = (file_lock *)_lhs;
|
||||
|
||||
return (
|
||||
lhs &&
|
||||
lhs->key.inode == rhs->inode &&
|
||||
lhs->key.dev == rhs->dev
|
||||
);
|
||||
}
|
||||
|
||||
int sun_lockfile(int fd, int shouldblock)
|
||||
{
|
||||
|
||||
#ifdef SunOS
|
||||
int n, stop;
|
||||
int flg = shouldblock ? F_SETLKW : F_SETLK;
|
||||
flock_t lock;
|
||||
#else
|
||||
unsigned flg = shouldblock ? 0 : LOCK_NB;
|
||||
#endif
|
||||
|
||||
struct stat buf;
|
||||
if (fstat(fd, &buf)) {
|
||||
int e = errno;
|
||||
perror("Unable to fstat file for lock");
|
||||
errno = e;
|
||||
return(-1);
|
||||
}
|
||||
|
||||
file_key key;
|
||||
key.inode = buf.st_ino;
|
||||
key.dev = buf.st_dev;
|
||||
|
||||
debug("mm_util",0,"----->Locked");
|
||||
pthread_mutex_lock(&listMutex);
|
||||
|
||||
if (openFileList == NULL) {
|
||||
openFileList = (List *)gwlist_create();
|
||||
}
|
||||
|
||||
/* See if the inode exists in the list */
|
||||
file_lock *item = NULL;
|
||||
do {
|
||||
item = (file_lock*)gwlist_search(openFileList, &key, file_lock_inode_cmp);
|
||||
if (item) {
|
||||
/* It exists, that means that someone has already locked the file */
|
||||
if (!shouldblock) {
|
||||
n = -1;
|
||||
debug("mm_util",0,"<-----UnLocked");
|
||||
pthread_mutex_unlock(&listMutex);
|
||||
errno = EWOULDBLOCK;
|
||||
return n;
|
||||
}
|
||||
|
||||
pthread_cond_wait(&item->condition, &listMutex);
|
||||
/* O.k. we've got the file, but now item is invalid,
|
||||
the unlock_and_close removes it.
|
||||
*/
|
||||
}
|
||||
} while (item != NULL);
|
||||
|
||||
/* No one else has locked the file, create the condition for
|
||||
anyone else.
|
||||
*/
|
||||
item = (file_lock*)gw_malloc(sizeof(file_lock));
|
||||
item->key.inode = key.inode;
|
||||
item->key.dev = key.dev;
|
||||
item->fd = fd;
|
||||
pthread_cond_init(&item->condition, NULL);
|
||||
gwlist_append(openFileList, item);
|
||||
|
||||
/* Release the global lock so that we don't block the
|
||||
entire system waiting for fnctl to return
|
||||
*/
|
||||
debug("mm_util",0,"<-----UnLocked");
|
||||
pthread_mutex_unlock(&listMutex);
|
||||
|
||||
do {
|
||||
#ifdef SunOS
|
||||
lock.l_whence = SEEK_SET;
|
||||
lock.l_start = 0;
|
||||
lock.l_len = 0;
|
||||
lock.l_type = F_WRLCK;
|
||||
n = fcntl(fd, flg, &lock);
|
||||
if (n < 0) {
|
||||
if (errno == EINTR)
|
||||
stop = 0;
|
||||
else
|
||||
stop = 1;
|
||||
} else
|
||||
stop = 1;
|
||||
} while (!stop);
|
||||
|
||||
/* If we failed to get the fcntl lock, then we need to
|
||||
release the local lock */
|
||||
if (n != 0) {
|
||||
release_file_lock(fd, &key);
|
||||
}
|
||||
|
||||
return (n == 0) ? 0 : errno;
|
||||
#else
|
||||
n = flock(fd, LOCK_EX|flg);
|
||||
panic(0, "Attempt to call sun_lockfile on a non-solaris system");
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
int lockfile(int fd, int shouldblock)
|
||||
{
|
||||
#ifdef SunOS
|
||||
return sun_lockfile(fd, shouldblock);
|
||||
#else
|
||||
int n, stop;
|
||||
unsigned flg = shouldblock ? 0 : LOCK_NB;
|
||||
|
||||
do {
|
||||
n = flock(fd, LOCK_EX|flg);
|
||||
if (n < 0) {
|
||||
if (errno == EINTR)
|
||||
stop = 0;
|
||||
|
@ -942,6 +1122,7 @@ static int lockfile(int fd, int shouldblock)
|
|||
} while (!stop);
|
||||
|
||||
return (n == 0) ? 0 : errno;
|
||||
#endif
|
||||
}
|
||||
|
||||
static int check_lock(int fd, char *fname)
|
||||
|
@ -969,6 +1150,12 @@ int mm_lockfile(int fd, char *fname, int shouldblock)
|
|||
{
|
||||
int ret = lockfile(fd,shouldblock);
|
||||
|
||||
if (ret != 0 && errno != EWOULDBLOCK) {
|
||||
debug("mm_util", 0, "Unable to lock '%s', error= %d, %s, shouldblock=%d",
|
||||
fname, errno, strerror(errno), shouldblock);
|
||||
perror("Unable to lock file");
|
||||
}
|
||||
|
||||
if (ret != 0 ||
|
||||
(ret = check_lock(fd,fname)) != 0)
|
||||
return ret;
|
||||
|
@ -1284,7 +1471,7 @@ int parse_cgivars(List *request_headers, Octstr *request_body,
|
|||
|
||||
} else /* else it is nothing that we know about, so simply go away... */
|
||||
ret = -1;
|
||||
done:
|
||||
done:
|
||||
octstr_destroy(ctype);
|
||||
octstr_destroy(charset);
|
||||
return ret;
|
||||
|
@ -1551,7 +1738,7 @@ int mms_url_fetch_content(int method, Octstr *url, List *request_headers,
|
|||
return status;
|
||||
}
|
||||
|
||||
Octstr *get_stripped_param_value(Octstr *value, Octstr *param)
|
||||
Octstr *get_stripped_param_value(Octstr *value, Octstr *param)
|
||||
{
|
||||
Octstr *x = http_get_header_parameter(value, param);
|
||||
|
||||
|
|
|
@ -147,6 +147,14 @@ int mm_lockfile(int fd, char *fname, int shouldblock);
|
|||
/* Returns true if the character is printable or space */
|
||||
int _mms_gw_isprint(int c);
|
||||
|
||||
int lockfile(int fd, int shouldblock);
|
||||
/*
|
||||
* unlock_and_fclose/unlock_and_close are wrappers around fclose/close
|
||||
* needed to maintain the state of the global list on Solaris.
|
||||
*/
|
||||
int unlock_and_fclose(FILE *fp);
|
||||
int unlock_and_close(int fd);
|
||||
|
||||
/* Special form of cfg_get which returns zero-length string when there is nothing. */
|
||||
Octstr *_mms_cfg_getx(mCfg *cfg, mCfgGrp *grp, Octstr *item);
|
||||
|
||||
|
|
|
@ -72,7 +72,7 @@ static int dlr_entry_fname(char *msgid, char *rtype, Octstr *mmc_gid, Octstr **e
|
|||
p, strerror(errno));
|
||||
break;
|
||||
} else if (mm_lockfile(fd, p, 1) != 0) {
|
||||
close(fd);
|
||||
unlock_and_close(fd);
|
||||
fd = -1;
|
||||
}
|
||||
while (i++ < MAXTRIES && fd < 0);
|
||||
|
@ -92,7 +92,7 @@ void mms_dlr_url_put(Octstr *msgid, char *rtype, Octstr *mmc_gid, Octstr *dlr_ur
|
|||
if (fd >= 0) {
|
||||
Octstr *x = octstr_format("%S %S", transid ? transid : octstr_imm("x"), dlr_url); /* better have no spaces in transid! */
|
||||
octstr_write_data(x, fd, 0);
|
||||
close(fd);
|
||||
unlock_and_close(fd);
|
||||
octstr_destroy(x);
|
||||
}
|
||||
}
|
||||
|
@ -106,7 +106,7 @@ int mms_dlr_url_get(Octstr *msgid, char *rtype, Octstr *mmc_gid, Octstr **dlr_u
|
|||
Octstr *s = octstr_read_pipe(f);
|
||||
int i, ret;
|
||||
|
||||
fclose(f);
|
||||
unlock_and_fclose(f);
|
||||
if (s && octstr_len(s) == 0) {
|
||||
ret = -1;
|
||||
} else if ((i = octstr_search_char(s, ' ', 0)) >= 0) {
|
||||
|
@ -118,7 +118,7 @@ int mms_dlr_url_get(Octstr *msgid, char *rtype, Octstr *mmc_gid, Octstr **dlr_u
|
|||
octstr_destroy(s);
|
||||
return ret;
|
||||
} else if (fd >= 0)
|
||||
close(fd);
|
||||
unlock_and_close(fd);
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
@ -132,6 +132,6 @@ void mms_dlr_url_remove(Octstr *msgid, char *rtype, Octstr *mmc_gid)
|
|||
octstr_destroy(fname);
|
||||
}
|
||||
if (fd >= 0)
|
||||
close(fd);
|
||||
unlock_and_close(fd);
|
||||
|
||||
}
|
||||
|
|
|
@ -78,7 +78,7 @@ static MIMEEntity *find_textpart(MIMEEntity *m)
|
|||
goto done2;
|
||||
}
|
||||
}
|
||||
done:
|
||||
done:
|
||||
if (res) { /* We got it! Convert charset if needed. */
|
||||
List *params_h = get_value_parameters(params);
|
||||
Octstr *charset = http_header_value(params_h, octstr_imm("charset"));
|
||||
|
@ -98,7 +98,7 @@ done:
|
|||
octstr_destroy(charset);
|
||||
}
|
||||
|
||||
done2:
|
||||
done2:
|
||||
|
||||
octstr_destroy(ctype);
|
||||
octstr_destroy(params);
|
||||
|
@ -228,7 +228,7 @@ static void add_all_matching_parts(MIMEEntity *plist, MmsServiceUrlParam *pm,
|
|||
data = mime_entity_body(me);
|
||||
}
|
||||
|
||||
done:
|
||||
done:
|
||||
if (data) {
|
||||
MIMEEntity *p = mime_entity_create();
|
||||
Octstr *cd = octstr_format("form-data; name=\"%S\"", pm->name);
|
||||
|
@ -494,7 +494,7 @@ static int fetch_serviceurl(MmsEnvelope *e,
|
|||
octstr_destroy(base_url);
|
||||
}
|
||||
|
||||
done:
|
||||
done:
|
||||
octstr_destroy(ctype);
|
||||
octstr_destroy(rb);
|
||||
http_destroy_headers(rph);
|
||||
|
@ -681,7 +681,7 @@ static int mmsbox_service_dispatch(MmsEnvelope *e)
|
|||
e->_x = ms; /* Remember it for later. */
|
||||
|
||||
res = fetch_serviceurl(e, ms, msg, me, keyword, &err);
|
||||
done:
|
||||
done:
|
||||
|
||||
if (err && res != 0)
|
||||
mms_error(0, "mmsbox", NULL, "Error: %s", octstr_get_cstr(err));
|
||||
|
@ -759,7 +759,18 @@ int main(int argc, char *argv[])
|
|||
mms_info(0, "mmsbox", NULL," " MM_NAME " MMSBox version %s starting", MMSC_VERSION);
|
||||
|
||||
|
||||
#ifdef SA_RESTART
|
||||
{
|
||||
struct sigaction nact;
|
||||
|
||||
memset(&nact, 0, sizeof(nact));
|
||||
nact.sa_handler = relog_now;
|
||||
nact.sa_flags = SA_RESTART;
|
||||
sigaction(SIGHUP, &nact, (struct sigaction *)0);
|
||||
}
|
||||
#else
|
||||
signal(SIGHUP, relog_now);
|
||||
#endif
|
||||
signal(SIGTERM, quit_now);
|
||||
signal(SIGINT, quit_now);
|
||||
signal(SIGPIPE,SIG_IGN); /* Ignore pipe errors. They kill us sometimes for nothing*/
|
||||
|
@ -988,7 +999,7 @@ static int add_msg_part(MIMEEntity *res, xmlNodePtr node, Octstr *base_url,
|
|||
http_destroy_headers(headers);
|
||||
}
|
||||
|
||||
done:
|
||||
done:
|
||||
|
||||
octstr_destroy(curl);
|
||||
octstr_destroy(ctype);
|
||||
|
@ -1355,7 +1366,7 @@ static int make_and_queue_msg(Octstr *data, Octstr *ctype, List *reply_headers,
|
|||
octstr_get_cstr(x));
|
||||
*err = x;
|
||||
res = 0;
|
||||
done:
|
||||
done:
|
||||
|
||||
octstr_destroy(dlr_url);
|
||||
octstr_destroy(rr_url);
|
||||
|
|
|
@ -12,7 +12,9 @@
|
|||
*/
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#ifndef DARWIN
|
||||
#include <wait.h>
|
||||
#endif
|
||||
#include <sys/wait.h>
|
||||
|
||||
|
||||
|
|
|
@ -59,8 +59,18 @@ int main(int argc, char *argv[])
|
|||
if (!settings)
|
||||
panic(0, "No MMSC configuration!");
|
||||
|
||||
#ifdef SA_RESTART
|
||||
{
|
||||
struct sigaction nact;
|
||||
|
||||
memset(&nact, 0, sizeof(nact));
|
||||
nact.sa_handler = relog_now;
|
||||
nact.sa_flags = SA_RESTART;
|
||||
sigaction(SIGHUP, &nact, (struct sigaction *)0);
|
||||
}
|
||||
#else
|
||||
signal(SIGHUP, relog_now);
|
||||
#endif
|
||||
signal(SIGTERM, quit_now);
|
||||
signal(SIGINT, quit_now);
|
||||
signal(SIGPIPE,SIG_IGN); /* Ignore pipe errors. They kill us sometimes for no reason*/
|
||||
|
|
Loading…
Reference in New Issue