Ultimately, your enterprise will certainly experience issues that may well effect production, performance, in addition to comfort. Possessing a firm signifies that you'll want lots of documents. Right after old corporation is completed, brand new business is usually talked about. This identifies uncertain items which had been discussed throughout a previous assembly. Phoning in The english language may be a significant portion associated with performing enterprise within The english language.
An agenda can enable you to get back target in case the discussions veer down keep tabs on, that help a person idea how long you predict paying inside the achieving. That presents a carrier's on-going method. This company program stands out as the point where the actions is–the component of the particular meeting the location where the affiliates disagreement and have your vote on many different actions items. An enterprise meeting schedule hopes to facilitate effective plus well-organized exploration of concerns relevant to the actual and way forward for the business.
To succeed in your current gathering goals, your plan needs to be particular. Every single agenda will require to have got a overview for the platform background, plan purpose and even objectives. A gathering program may be set up in several ways. In most cases an index of exactly what subjects will probably be reviewed with the web-site of an business gathering. Make sure later plans in the assembly in addition to use this. Price range getting together with agendas usually are grouped by means of past internet business performance in addition to current enterprise specifications.
You will find a mixture of approaches by which someone can lead to your current conference effectively while not having to show up at. Your section gathering can be described as sort of laid-back appointment. A new thriving gathering is a consequence of a well-organized and prepared program. It happens when ever participants specifically the actual really need to complete. In accordance with processionals if you want to maintain a flourishing achieving then you need to make a achieving platform beforehand. The point is, you ought to recognize regarding various forms of gatherings and what circumstances to prepare for from each. In some instances, you should phone an enterprise interacting with to help keep and improve workforce onesto.
one particular sort of getting together with is surely an recognized conference. To place this different, you can phone a meeting to set-up recommendations in terms of a brand new products or perhaps to produce a fresh advertising and marketing strategy. Before getting in touch with a gathering, it needs to first of all become chose whether it is important. When you can stay clear of reserving only one even more getting together with, it is advisable to. There are many forms of conferences. To ensure that you can build group meetings more effective, a person must be comfortable with the many down sides and solutions to take care of all of them. A possibility essential to call a gathering for each and every trouble of which comes up at your workplace, however you have to immediately tackle any kind of problems that have an impact on natural business or employee spirits.
Bear in mind a meeting merely generally the best ways. Moreover get togethers can also be important as it is often a process of relationship with other folks. A gathering is named a event involving at the very least two people that was organised using typically the intent to get a mutual target by using spoken conversation, such as spreading details or even hitting set up. 1 form is an genuine interacting with. Stand-up appointments usually are somewhat even more effective. A wonderful gathering takes organizing, ideally what kind that has the employees or even attendees that will be going to your current achieving. If you intend to keep typical appointments, ensure to discover a working day and even period absolutely hassle-free to your personnel. Learning much more: www.eltrampoli.org .


Businesses are increasingly in need of powerful mobile testing solutions as mobile usage climbs worldwide. There were an estimated 4.3 billion mobile phone users in 2016, more than half the world's population, which will only continue to rise to an estimated 4.78 billion in just a few years. Moreover, time spent on digital media increased by 53% over the past few years in the US, primarily because of mobile.
Mobile apps change the way people live and interact with the world, from communications to entertainment to finance, healthcare, and transportation. They also change the way consumers interact with businesses and brands.
There's a significant untapped potential in this billion-dollar mobile market but what's prevented m-commerce from becoming the lead channel for buying is poor user experience. And while both user experience and revenue rely heavily on mobile apps and their quality, mobile teams are facing challenges when trying to adopt robust testing and monitoring into their mobile development processes.
Some QA teams turn to emulators and virtual devices to test their mobile apps and, while these may be part of one's testing environment, they are not the end-all solution. Because applications on emulators and virtual devices are not interacting with real physical hardware, certain, real-life conditions and scenarios cannot be tested. That is why real devices using real carriers placed in real locations, is the only testing means to get the most thorough insights about app quality, performance, and user experience.
The challenge for businesses is the frequent rollout of new mobile devices and operating systems, and the associated costs of purchasing a wide-enough range of expensive OEM hardware that will provide the most complete mobile testing environment. And it's simply not enough to be testing on a few selected devices and operating systems in limited, perhaps just local, locations to get thorough insights on app performance and user experience.
The two biggest mistakes when analyzing the cost of investment for mobile testing is missing the bigger picture and leveraging the data, tools, and best practices available. It used to be that many businesses could not even afford to have a mobile app because app developers were too costly. But with the growth of open software development kits and speedy development cycles, mobile apps are now more readily accessible than ever before.
But despite the increasing ease of developing an inexpensive app, which serves the purpose of benefiting the business, all too often, testing is shoved aside or becomes a low (or non-) priority to meet rapid-release deadlines. This might not present alarming issues at first but to ensure proper functioning and performance across the board and scale with users, testing is essential from the start. Otherwise, the cost of resolving both technical problems and even branding issues can become significantly greater than if testing and monitoring were implemented all along.
Moreover, app data is available at unprecedented rates, whether it be signaling bugs and crashes, or how users are navigating through an app. All of this information has the potential to enable businesses to leverage the data to the benefit of their business and upward trend of their ROI. While user feedback is important, negative reviews and complaints shouldn't be how issues are identified. Comprehensive mobile testing prior to a release can assure minimal negative feedback after product rollout, and real-time monitoring can identify issues before large numbers of users have time to complain.
Mobile apps that don't undergo rigorous testing can significantly impact business goals. Users these days have notoriously low tolerance for apps that don't work. Only 16% of users will try a failing app more than twice. Consequently, poor user experiences and negative reviews impact adoption and usage rates, and ultimately, business can be lost to competitors who have better apps and can give better experiences.
Mobile applications are increasingly becoming the way to gain more customers but engaging them effectively is key. Having a seamless mobile app that is reliable is imperative. Mobile app testing and app monitoring eliminates the cost of mobile app failure and poor user experiences, and quality mobile apps help businesses differentiate in an already-saturated market and thus attract and maintain their user bases. In the end, apps that can meet and exceed expectations, and delight, is the one that can generate more users, more business, and higher ROI.
From within the company's perspective, not testing can also be harmful because it leaves the QA and development team exposed to criticism for failure to meet criteria and quality, and could hinder the relations of vested stakeholders. By running functional and performance tests, critical issues can be resolved before rollout and concise reports shared to leadership. There is also accountability.
Emulators and virtual devices are one affordable solution but by no means a complete one. Luckily, there are powerful solutions on the market today that support both functional regression testing, and performance testing and monitoring, on a variety of real physical devices located across the globe with remote access. Tests can be run in parallel, optimizing test coverage, cutting down on test time, and producing higher level results and quality apps. With better quality apps come better business.


» Young and Hypertense: Do You Know if You Have High Blood Pressure?
According to a recent study, lower back pain may be heightened if a spouse is unsupportive or critical of their partner. Published in August, the report involved observing 71 couples during a 10-minute discussion. The researchers were looking to see how a spouse's perspective could influence a patient's ability to deal with pain when they were suffering from a herniated disc, spinal stenosis, or a degenerative disc. After the discussion, the patients suffering from chronic back pain were asked to do a 10-minute activity which involved stretching, bending, reclining, walking, standing, and sitting, while their partner watched on. The research team measured the levels of hostility and criticism from the spouse along with how much criticism was perceived by the patient. They also monitored the patients' depressive symptoms, pain behaviors, and pain intensity.
It was intended for the initial 10-minute discussion to create conflict, but the amount of hostility or criticism given wasn't manipulated. The researchers were successful in creating this conflict, with all patients reporting significant increases in their feelings of sadness, anger, and anxiety. Throughout the activity, the patients who experienced greater pain and were more likely to observe greater criticism from their spouses have been found to have higher depression scores.
Speaking about the study, John Burns who was their lead researcher suggested that until now, most studies have focused on how adequate social support can positively influence someone with chronic pain. However, this study has demonstrated how negative communication from a spouse can have a harmful effect on pain patients, with these negative responses often creating a vicious cycle. Spouse criticism can cause pain among patients as expressed by straining, groaning, and grimacing up to three hours later. This can also lead to further spouse criticism up to three hours later. When someone is experiencing back pain, it's very easy to criticize, dismiss them, or even act in a hostile manner toward them. However, when a patient is enduring pain, the best type of support is to help them lead the best life they can despite their pain. For back pain sufferers, this may also include getting the help of a chiropractor. As studies suggest, this noninvasive treatment is effective at relieving this type of pain. If you've got chronic back pain, don't suffer in silence. Seek the professional advice and care of your local chiropractor.
Young and Hypertense: Do You Know if You Have High Blood Pressure?
If you are a male between the ages of 18 and 39, there is a good chance you have high blood pressure and may not know it. Research findings in eight national health surveys conducted between 1999 and 2014 suggest that only half of the 6.7 million young adults between the ages of 18 and 39 who actually have high blood pressure or hypertension received treatment for it.
Approximately 75 million adults in the US, which is roughly 32% of the population, have high blood pressure. While awareness of and treatment for hypertension and high blood pressure has improved in recent years, a significant number of people still go undiagnosed and untreated every year. And a large percentage of those people are men under the age of 39. Over 86% of women with high blood pressure have been diagnosed and sought treatment, compared with 44% of young men. High blood pressure and hypertension are the leading cause of stroke and heart attack, and contribute to one in 4 deaths every year in the US alone. High blood pressure can be caused by many factors, including obesity, smoking, stress, and genetics. In many cases the risk factors can be reduced or eliminated and the condition can be controlled. However, failure to seek medical opinion and treatment can have serious consequences.
Studies conducted at Harvard Medical School and Brigham & Women's Hospital in Boston, MA show that individuals who have shown elevated blood pressure in adolescence and early adulthood are at greater risk for heart attacks later in life. Researches suggest that preventing high blood pressure in the first place by exercising, eating a healthy diet, and avoiding tobacco is one of the best ways to reduce the likelihood of hypertension or high blood pressure. If medication I required to control the condition, patients tend to get better results when they are young. Chiropractic care can also help alleviate or eliminate sources of stress caused by chronic pain, which can contribute to an overall reduction in blood pressure. If you have a history of high blood pressure or heart disease in your family, or think you may be suffering from the condition, you are encouraged to seek a medical evaluation and treatment.
Source: Hypertension, online August 28, 2017.


To create more value for Sanding Sponge Block , Abrasive Sanding Sponge Block , Sanding Block , and we'll do our greatest to serve you.
We have been committed to offering easy,time-saving and money-saving one-stop purchasing service of consumer for Sanding Sponge Block , Abrasive Sanding Sponge Block , Sanding Block , Corporate goal: Customers' satisfaction is our goal and sincerely hope to establish long-terms stable cooperative relations with customers to jointly develop the market. Building brilliant tomorrow together!Our company regards "reasonable prices efficient production time and good after-sales service" as our tenet. We hope to cooperate with more customers for mutual development and benefits. We welcome potential buyers to contact us.


text:
Crushing 1-0 loss ends Hawks' season
Shelby BlackleyFebruary 24, 20132 mins read
(Photo by Kate Turner).
Time wound down on the Wilfrid Laurier women's hockey team's season the first time when the Western Mustangs took a 1-0 lead in the series.
And in the final five minutes of the deciding game three of the Ontario University Athletics (OUA) semifinal, the Hawks again saw the clock tick to the end. Except this time, when the clock expired, it meant the end of their season.
The Mustangs defeated the Hawks 1-0 Sunday evening to take the series 2-1 and advance to the OUA finals against the Queen's Gaels. Laurier's season comes to a close and for the first time since 2002-03, the WLU women's hockey team will not be going to the Canadian Interuniversity Sport (CIS) national championships.
"My hats go off to them. It's their party tonight," said head coach Rick Osborne after the game.
In a very close affair that had the shots 30-29 in favour of Western and five Laurier penalties in the first period, both teams kept a high tempo. Laurier spent half of the first period on the penalty kill, where second-year Erika Thunder would muster up 14 saves to keep the game scoreless.
Laurier only had three shots on net in the first 20 minutes.
In the second period, Laurier was able to find some comfort, throwing 17 shots on Western netminder Kelly Campbell while holding the Mustangs to seven. However, the game remained scoreless.
With end-to-end action and multiple opportunities for both teams, it was not until there was five minutes left in the third period that Western was able to solve Thunder. A bounce off the end boards came out in front of the Hawks' net and second-year Kendra Deller was in the right place at the right time and found the mesh.
That would be the deciding goal as the Hawks couldn't muster another opportunity against Campbell and the Mustangs in the final minutes.
"The third period we were playing a 0-0 game and you're playing for one bounce," Osborne said. "We had a ton of bounces around their net. They've got a great team and a great goaltender and they got the bounce and made it pay off."
Laurier will graduate fifth-year Caitlin Muirhead and fourth-years Fiona Lester, Brittany Crago, Paula Lagamba and Maureen Mommersteeg.
A look at the current uncertain nature of junior hockey competition in Ontario
Training in the time of COVID-19: Women's hockey's return to training on campus
Golden Hawks honour seven impressive inductees into hall of fame
Women's Hockey announces eight recruits as part of 2020 recruiting class:
Chemistry, skill and OHL experience headline Men's Hockey recruiting class
Golden Hawks announce award winners through online banquet

redpajama_set_name: RedPajamaCommonCrawl


Seeing spots? We completely co-sign polka dot shirts as one of this summer's most underrated trends. But like most trends, this one can be a bit risky to pull-off. It's not for everyone, but when paired with simple khaki chinos or denim, you'll definitely look like a style pro. Whether you like small or large dots, we've got you covered from brands like 11after11 and Stüssy. Check out Summer Trend: Polka Dot Shirts.


text:
layout: page
title: About
permalink: /about/
---

JOMWEB merupakan satu inisiatif yang digerakkan oleh komuniti pembangun tempatan dalam mengangkat darjat dan menceriakan lagi industri IT di Malaysia. Kami percaya dengan konsep perkongsian ilmu dalam mengukuhkan lagi industri ini ke tahap yang seterusnya.

Sertai Kami:-

* Laman Utama: [JOMWEB.my](http://www.JOMWEB.my)
* Grup FB Utama: [fb.com/groups/JOMWEB](http://fb.com/groups/JOMWEB)
* Chapter Johor:
	* [jomwebjohor.github.io](http://jomwebjohor.github.io)
	* [fb.com/groups/jomwebjohor](http://fb.com/groups/jomwebjohor)

redpajama_set_name: RedPajamaGithub


Gum disease is caused by the bacteria found in plaque. The toxins produced by these bacteria cause our bodies to destroy the bone that supports the teeth. If plaque is not removed, it can harden and form calculus (tartar) that can exacerbate the periodontal problem. Studies have shown that tartar buildup already attaches to teeth in three months.
Even someone with good oral hygiene will be unable to completely prevent the formation of all calculus on the teeth. Calculus forms when the minerals in the saliva harden, or calcify, the plaque on the teeth. Plaque is soft and sticky, and is continually forming. It is therefore important to ensure proper, thorough brushing and flossing on a daily basis to remove the plaque before it has the chance to solidify into calculus.
Dr. Kwok will recommend how often you should have a periodontal maintenance visit, but it is best to get a cleaning every three months. The frequency will be determined by the type of periodontal disease you have, the type of periodontal treatment you have had in the past, how you have responded to those treatments, and how quickly you accumulate plaque. The most important factor, however, is how dedicated you are to good hygiene at home.


The 3 D's of the nutrition department -Dietary service, Diet counselling and Diet analysis- contribute significantly to the control of diabetes by prescribing a suitable diet, thus preventing complications.
The Department of Nutrition and Dietetics is an essential part of the hospital and dietitians/diabetes educators are a vital link in the paramedical team. The 3 D's of the nutrition department -Dietary service, Diet counselling and Diet analysis- contribute significantly to the control of diabetes by prescribing a suitable diabetic diet, thus preventing complications. In addition to the obvious function of catering to the nutritional requirements of patients, such a program supplements therapy. It has a direct influence on the morale and attitudes of patients and their families.
The dietitian/diabetes educators at Dr. Mohan's Diabetes Specialities Centre undertake the responsibility of reviewing a patient's diet and medication as well as educating them about insulin techniques, home monitoring of blood glucose and demonstrating the use of kits. They also conduct education programmes to create awareness of diabetes and a healthy diet for patients and attendants. Through counselling services like group therapy sessions for type-1 patients every month as well as group therapy programmes for in-patients using 'conversation maps' can improve a patient's mental and emotional well-being.
What are the foods which a individual with diabetes needs to avoid?
Sugar, honey, glucose, jam, jaggery, sweets, cakes.
High calorie fruits like banana, mango, jack fruits, chikku, custard apple, grapes.
I have diabetes, suggest me what I should choose to eat?
Foods that contain little or no carbohydrates include meats, poultry, fish, egg, non starchy vegetables and fats.Carbohydrates get converted into blood glucose quickly and thereby increase the blood glucose level. Therefore the quantity and quality of carbohydrate consumed is important. Hence it is essential to choose low carbohydrate foods .
It is better to prefer complex carbohydrates and high fiber foods like whole grains, whole pulses and non starchy vegetables as it delays digestion and helps for a better glycemic control.
Insoluble fibre- found is whole grains and whole pulses.
Increasing dietary fibre also helps to promote weight loss and maintenance.High-fibre foods tend to be more filling than low-fiber foods. A high-fiber food tends to take longer time to eat and to be less "energy dense," which means the calories are less for the same volume of food.
How does 4 meal pattern help in diabetes?
How should I fill my plate?
Fill half of your plate with vegetables and greens, one fourth with whole grams and pulses (if non-vegetarian pulses & non-vegetarian food) and the remaining one fourth with cereals (whole grains) like unpolished/minimally polished rice, Dr.Mohan's brown rice, high fibre rice or wheat. Watch your portion sizes.
I have been recently diagnosed with type 1 diabetes and treated with insulin; I am scared to go to school, please advise.
Type 1 Diabetes Mellitus (T1DM) is one of the most common endocrine and metabolic conditions in childhood. Despite having Type 1 diabetes, a person can lead a healthy life provided the treatment is adhered. There is no need to panic after the diagnosis as there are number of children with Type 1 Diabetes with lot of potential and leading a healthy life irrespective of the duration of diabetes.Do not restrict on any of the routine activities, i.e-do not get scared of going to school.
To overcome fear, follow the below mentioned guidelines and tips and learn to live with type 1 diabetes.
Many schools have little experience caring for a student with diabetes and may not know what is involved in diabetes management. It will take some time for the school to get used to caring for your child, just as it took some time for the child's parents and the child as well.Talk to the school administrators and all staff members about what diabetes means for the child.Make sure the child always has everything required to manage diabetes at school.
Share helpful information about diabetes with school personnel.
Link the school to a diabetes educator who can help to train and educate teachers and other school personnel about diabetes.
Describe the child's usual symptoms of hypoglycemia and hyperglycemia.
Provide updated phone numbers. Develop a plan for when you should be called.
Talk about what to do in an emergency. Make sure a trained school staff member know when and how to manage hypoglycemia.
Provide diabetes management materials and equipment that should be kept at school.


Gardaí have arrested a man in his 30s following a burglary incident at a business premises in Limerick City on December 3, 2018.
At approximately 3am, Gardaí from Henry Street responded to a call of a burglary in progress at a business premises on O Connell Street.
A man in his 30s was arrested at the scene and brought to Henry Street Garda Station. He is currently detained under Section 4 of the Criminal Justice Act 1984.


This listing is for random dead house flies in the insect order Diptera, family Muscidae.
Seasonal availabilities on insects I'm able to collect, as well as the number of orders I'm currently working on may affect my ability to get your order to you immediately. When possible, please plan ahead!


It's our favourite event of the year! Come in you PJ's to the 3rd annual Library After Dark Party for fun and stories and a whopping good time.
Doors will open at 6:15pm and promptly lock at 6:30pm.
A PAL tutor from the Cariboo Chilcotin Patrner's for Literacy is on hand at the library twice a month to teach basic computer skills. Preregistration is required. Call 250-392-3630 or come the library to register.
Begins September 11th, 2012, and then the 2nd and 4th Tuesday of the month.


Robeco QI Emerging Markets Active Equities invests in stocks in emerging countries across the world. The selection of these stocks is based on a quantitative model. The fund follows a bottom-up driven investment strategy to gain exposure to the proven return factors value, quality and momentum within a tracking error budget. The fund's objective is to achieve a better return than the index consistently, by taking well-diversified exposure to an integrated multi-factor stock selection model.
Robeco QI Emerging Markets Active Equities invests in stocks of companies in emerging economies throughout the world, such as Korea, Taiwan, Poland and Brazil. These economies can show rapid growth, so the risks can be greater than those in developed countries. The fund uses a quantitative stock selection model. This model ranks stocks on their expected future relative performance using valuation (including quality) and momentum factors. Highly ranked stocks are overweighted against the benchmark, whereas low-ranked stocks are underweighted. This Sub-fund may invest in China A-shares via the QFII and/or a Stock Connect Programme which may entail additional clearing and settlement, regulatory, operational and counterparty risks.


text:
Fort Collins Colorado Temple
Reliable Water Restoration » Fort Collins » Fort Collins Colorado Temple
The Fort Collins Colorado Temple is a temple of The Church of Jesus Christ of Latter-day Saints in Fort Collins, Colorado. It was completed in 2016 and the announcement was first made by Thomas Monson on April 2nd, 2011 before construction began.
The Fort Collins temple is on the southeast corner of the Trilby Road and Timberline Road intersection. The Latter-day Saint chapel is across the street.
The new 42,000-square-foot (3,900 m2) building in Fort Collins will serve the needs of more than 20,000 church members in Northern Colorado, Southern Wyoming, and Western Nebraska.
The developers are applying to re-zone an area of land so that it can be used to build a structure that will service the tri-state region.
The current zoning on the property is for homes and neighborhood centers that act as a focal point for community activities like grocery stores.
The developer first pursued rezoning through Larimer County as part of an intergovernmental agreement with the City of Fort Collins and was successful.
Back in 2011, the city planning board in Fort Collins recommended annexation with a rezoning of the temple. The groundbreaking ceremony was conducted by Ronald A. Rasband on August 24, 2013.
Read more: Fort Collins Municipal Railway
Construction on the temple began a few years ago and as they progressed, they were vandalized on August 23, 2015. On August 26, 2015, an identical angel Moroni statue was erected.
The public open house dates of the temple are from August 19-September 10, excluding Sundays. The temple was officially opened on October 16 by Dieter F. Uchtdorf.
Plans call for a 30,389 square-foot temple to be erected 112 feet high with a statue of an angel Moroni sculpted atop.
One resident has asked for the steeple to be lowered to 100 feet, but it was explained that the steeple height already matches the lowest possible height and is exempt from the limitations.
The Church agreed to turn off the steeple and angel Moroni statue by 10:00 p.m. Timberline Road will be widened to include turning lanes, a sidewalk, and additional street lighting
Elder Ronald A. Rasband presided over the groundbreaking ceremony of the Fort Collins Colorado Temple on Saturday, August 24, 2013, and marked the formal commencement of construction.
Read more: Fort Collins Museum of Discovery
When talking about the church's history, Elder Rasband mentioned how our modern temples are just an extension of structures that have been around for a long time.
The Lord answered to him 'my name shall be there.' This sounds the same as Fort Collins, Colorado where we just started. When the construction of the temple is done, it will be a house of prayer, revelation, and teaching.


The Arts and Crafts movement is defined by design paired with hand made and natural materials. Stair components are sometimes square and boxy with Art Nouveau design. These earthy attributes give the house a handmade feel. Arts and Crafts styles later inspired bungalow style homes, which are wood homes with touches of Spanish, and even Japanese, influences that share the rustic simplicity of the craftsman.


Cashing in your points from various travel reward programs varies depends on the terms and agreements of the exact program and company you are working with. No matter what the terms and agreements are, there are two main ways to redeem accrued reward points in exchange for airfare: either directly through the air carrier or through your credit card company. Most air carriers and credit card companies will allow you to redeem the points both over the phone and via the Internet.
Call the air carrier your points are currently with and find out how many points are eligible for redemption.
Narrow your trip choices by discussing your options with the phone representative to those that fall within your eligible points range.
Book your flight and pay any other additional fees as requested by the airline such as airport tax, baggage fees and more that may not be eligible to be paid for with accrued points.
Request that the points be used to pay for the airfare. The representative will perform the necessary transactions to cash the points for airfare. Alternately, you could also perform the same transaction by logging onto the air carrier's website and request the points be used to pay for the trip during the online booking process.
Call the air carrier or log onto their website. Discuss your options with the phone representative or view your trip choices from the menu choices displayed online.
Book your flight with your credit card. Write down or print your itinerary or other confirmation documents.
Call your credit card company or log onto the credit card's website and log into your account. Redeem your credit card reward points as reimbursement for the trip you just purchased.
Since all travel rewards programs are different, you may find it more helpful to call a phone representative since they can offer helpful advice or advise you of other options for your trip that you might otherwise overlook. Working with a phone representative can also help you avoid restriction dates and identify flights that are not eligible to be purchased with cashed-out points.
Some air carriers do not accept points from outside of their own pre-established air carrier preferred networks. Before making flight choices, you'll want to double check to determine if the points accumulated in your rewards program can be cashed for just one specific airline or several different ones. Some airlines prohibit using points for certain flights, such as first class, or on certain days like blackouts or holidays.
S., Misty. "How to Cash in Points for Airfare." Travel Tips - USA Today, https://traveltips.usatoday.com/cash-points-airfare-19299.html. Accessed 23 April 2019.
Can I Get Coupons for Enterprise Rental Cars?


Hey guys today I'm going to be reviewing these two amazing products. They are such good quality, both products smell amazing.although if you don't like coconut you'll probably hate it!!!
So lets start with the shampoo this is meant to help restore moisture and shine. After using this for a couple of weeks my hair is feeling less brittle and a lot less damaged, on the shine front I'm not to sure I can't say I've seen a huge improvement. Onto the conditioner this little pot is liquid Gold it's AMAZING ! I use it once a week and the obvious results last about two days. It makes hair super shiny and lovely and light I've found after using these two products my hair is soooo much healthier and at 0.99p for the shampoo and £1.49 for the conditioner it's such a steal. I can't wait to try out there range for coloured hair!!!
posts like this make me wish we had a superdrug! I'd love to try that conditioner.
I've never actually tried any of the superdrug range, but I'm dying to after reading this, sounds great!


text:
#include "rtpudpv4transmitter.h"
#include "rtprawpacket.h"
#include "rtpipv4address.h"
#include "rtptimeutilities.h"
#include "rtpdefines.h"
#include "rtpstructs.h"
#include "rtpsocketutilinternal.h"
#include "rtpinternalutils.h"
#include "rtpselect.h"
#include <stdio.h>
#include <assert.h>
#include <vector>
#ifdef RTPDEBUG
	#include <iostream>
#endif // RTPDEBUG

#include <iostream>

#include "rtpdebug.h"

#define RTPUDPV4TRANS_MAXPACKSIZE							65535
#define RTPUDPV4TRANS_IFREQBUFSIZE							8192

#define RTPUDPV4TRANS_IS_MCASTADDR(x)							(((x)&0xF0000000) == 0xE0000000)

#define RTPUDPV4TRANS_MCASTMEMBERSHIP(socket,type,mcastip,status)	{\
										struct ip_mreq mreq;\
										\
										mreq.imr_multiaddr.s_addr = htonl(mcastip);\
										mreq.imr_interface.s_addr = htonl(mcastifaceIP);\
										status = setsockopt(socket,IPPROTO_IP,type,(const char *)&mreq,sizeof(struct ip_mreq));\
									}
#ifdef RTP_SUPPORT_THREAD
	#define MAINMUTEX_LOCK 		{ if (threadsafe) mainmutex.Lock(); }
	#define MAINMUTEX_UNLOCK	{ if (threadsafe) mainmutex.Unlock(); }
	#define WAITMUTEX_LOCK		{ if (threadsafe) waitmutex.Lock(); }
	#define WAITMUTEX_UNLOCK	{ if (threadsafe) waitmutex.Unlock(); }
#else
	#define MAINMUTEX_LOCK
	#define MAINMUTEX_UNLOCK
	#define WAITMUTEX_LOCK
	#define WAITMUTEX_UNLOCK
#endif // RTP_SUPPORT_THREAD

#define CLOSESOCKETS do { \
	if (closesocketswhendone) \
	{\
		if (rtpsock != rtcpsock) \
			RTPCLOSE(rtcpsock); \
		RTPCLOSE(rtpsock); \
	} \
} while(0)

namespace jrtplib
{

RTPUDPv4Transmitter::RTPUDPv4Transmitter(RTPMemoryManager *mgr) : RTPTransmitter(mgr),destinations(mgr,RTPMEM_TYPE_CLASS_DESTINATIONLISTHASHELEMENT),
#ifdef RTP_SUPPORT_IPV4MULTICAST
								  multicastgroups(mgr,RTPMEM_TYPE_CLASS_MULTICASTHASHELEMENT),
#endif // RTP_SUPPORT_IPV4MULTICAST
								  acceptignoreinfo(mgr,RTPMEM_TYPE_CLASS_ACCEPTIGNOREHASHELEMENT)
{
	created = false;
	init = false;
}

RTPUDPv4Transmitter::~RTPUDPv4Transmitter()
{
	Destroy();
}

int RTPUDPv4Transmitter::Init(bool tsafe)
{
	if (init)
		return ERR_RTP_UDPV4TRANS_ALREADYINIT;

#ifdef RTP_SUPPORT_THREAD
	threadsafe = tsafe;
	if (threadsafe)
	{
		int status;

		status = mainmutex.Init();
		if (status < 0)
			return ERR_RTP_UDPV4TRANS_CANTINITMUTEX;
		status = waitmutex.Init();
		if (status < 0)
			return ERR_RTP_UDPV4TRANS_CANTINITMUTEX;
	}
#else
	if (tsafe)
		return ERR_RTP_NOTHREADSUPPORT;
#endif // RTP_SUPPORT_THREAD

	init = true;
	return 0;
}

static int GetIPv4SocketPort(SocketType s, uint16_t *pPort)
{
	assert(pPort != 0);

	struct sockaddr_in addr;
	memset(&addr, 0, sizeof(struct sockaddr_in));

	RTPSOCKLENTYPE size = sizeof(struct sockaddr_in);
	if (getsockname(s,(struct sockaddr*)&addr,&size) != 0)
		return ERR_RTP_UDPV4TRANS_CANTGETSOCKETPORT;

	if (addr.sin_family != AF_INET)
		return ERR_RTP_UDPV4TRANS_NOTANIPV4SOCKET;

	uint16_t port = ntohs(addr.sin_port);
	if (port == 0)
		return ERR_RTP_UDPV4TRANS_SOCKETPORTNOTSET;

	int type = 0;
	RTPSOCKLENTYPE length = sizeof(type);

	if (getsockopt(s, SOL_SOCKET, SO_TYPE, (char*)&type, &length) != 0)
		return ERR_RTP_UDPV4TRANS_CANTGETSOCKETTYPE;

	if (type != SOCK_DGRAM)
		return ERR_RTP_UDPV4TRANS_INVALIDSOCKETTYPE;

	*pPort = port;
	return 0;
}

int GetAutoSockets(uint32_t bindIP, bool allowOdd, bool rtcpMux,
                   SocketType *pRtpSock, SocketType *pRtcpSock,
                   uint16_t *pRtpPort, uint16_t *pRtcpPort)
{
	const int maxAttempts = 1024;
	int attempts = 0;
	std::vector<SocketType> toClose;

	while (attempts++ < maxAttempts)
	{
		SocketType sock = socket(PF_INET, SOCK_DGRAM, 0);
		if (sock == RTPSOCKERR)
		{
			for (size_t i = 0 ; i < toClose.size() ; i++)
				RTPCLOSE(toClose[i]);
			return ERR_RTP_UDPV4TRANS_CANTCREATESOCKET;
		}

		// First we get an automatically chosen port

		struct sockaddr_in addr;
		memset(&addr,0,sizeof(struct sockaddr_in));

		addr.sin_family = AF_INET;
		addr.sin_port = 0;
		addr.sin_addr.s_addr = htonl(bindIP);
		if (bind(sock,(struct sockaddr *)&addr,sizeof(struct sockaddr_in)) != 0)
		{
			RTPCLOSE(sock);
			for (size_t i = 0 ; i < toClose.size() ; i++)
				RTPCLOSE(toClose[i]);
			return ERR_RTP_UDPV4TRANS_CANTGETVALIDSOCKET;
		}

		uint16_t basePort = 0;
		int status = GetIPv4SocketPort(sock, &basePort);
		if (status < 0)
		{
			RTPCLOSE(sock);
			for (size_t i = 0 ; i < toClose.size() ; i++)
				RTPCLOSE(toClose[i]);
			return status;
		}

		if (rtcpMux) // only need one socket
		{
			if (basePort%2 == 0 || allowOdd)
			{
				*pRtpSock = sock;
				*pRtcpSock = sock;
				*pRtpPort = basePort;
				*pRtcpPort = basePort;
				for (size_t i = 0 ; i < toClose.size() ; i++)
					RTPCLOSE(toClose[i]);

				return 0;
			}
			else
				toClose.push_back(sock);
		}
		else
		{
			SocketType sock2 = socket(PF_INET, SOCK_DGRAM, 0);
			if (sock2 == RTPSOCKERR)
			{
				RTPCLOSE(sock);
				for (size_t i = 0 ; i < toClose.size() ; i++)
					RTPCLOSE(toClose[i]);
				return ERR_RTP_UDPV4TRANS_CANTCREATESOCKET;
			}

			// Try the next port or the previous port
			uint16_t secondPort = basePort;
			bool possiblyValid = false;

			if (basePort%2 == 0)
			{
				secondPort++;
				possiblyValid = true;
			}
			else if (basePort > 1) // avoid landing on port 0
			{
				secondPort--;
				possiblyValid = true;
			}

			if (possiblyValid)
			{
				memset(&addr,0,sizeof(struct sockaddr_in));

				addr.sin_family = AF_INET;
				addr.sin_port = htons(secondPort);
				addr.sin_addr.s_addr = htonl(bindIP);
				if (bind(sock2,(struct sockaddr *)&addr,sizeof(struct sockaddr_in)) == 0)
				{
					// In this case, we have two consecutive port numbers, the lower of
					// which is even

					if (basePort < secondPort)
					{
						*pRtpSock = sock;
						*pRtcpSock = sock2;
						*pRtpPort = basePort;
						*pRtcpPort = secondPort;
					}
					else
					{
						*pRtpSock = sock2;
						*pRtcpSock = sock;
						*pRtpPort = secondPort;
						*pRtcpPort = basePort;
					}

					for (size_t i = 0 ; i < toClose.size() ; i++)
						RTPCLOSE(toClose[i]);

					return 0;
				}
			}

			toClose.push_back(sock);
			toClose.push_back(sock2);
		}
	}

	for (size_t i = 0 ; i < toClose.size() ; i++)
		RTPCLOSE(toClose[i]);

	return ERR_RTP_UDPV4TRANS_TOOMANYATTEMPTSCHOOSINGSOCKET;
}

int RTPUDPv4Transmitter::Create(size_t maximumpacketsize,const RTPTransmissionParams *transparams)
{
	const RTPUDPv4TransmissionParams *params,defaultparams;
	struct sockaddr_in addr;
	RTPSOCKLENTYPE size;
	int status;

	if (!init)
		return ERR_RTP_UDPV4TRANS_NOTINIT;

	MAINMUTEX_LOCK

	if (created)
	{
		MAINMUTEX_UNLOCK
		return ERR_RTP_UDPV4TRANS_ALREADYCREATED;
	}

	// Obtain transmission parameters

	if (transparams == 0)
		params = &defaultparams;
	else
	{
		if (transparams->GetTransmissionProtocol() != RTPTransmitter::IPv4UDPProto)
		{
			MAINMUTEX_UNLOCK
			return ERR_RTP_UDPV4TRANS_ILLEGALPARAMETERS;
		}
		params = (const RTPUDPv4TransmissionParams *)transparams;
	}

	if (params->GetUseExistingSockets(rtpsock, rtcpsock))
	{
		closesocketswhendone = false;

		// Determine the port numbers
		int status = GetIPv4SocketPort(rtpsock, &m_rtpPort);
		if (status < 0)
		{
			MAINMUTEX_UNLOCK
			return status;
		}
		status = GetIPv4SocketPort(rtcpsock, &m_rtcpPort);
		if (status < 0)
		{
			MAINMUTEX_UNLOCK
			return status;
		}
	}
	else
	{
		closesocketswhendone = true;

		if (params->GetPortbase() == 0)
		{
			int status = GetAutoSockets(params->GetBindIP(), params->GetAllowOddPortbase(), params->GetRTCPMultiplexing(),
			                            &rtpsock, &rtcpsock, &m_rtpPort, &m_rtcpPort);
			if (status < 0)
			{
				MAINMUTEX_UNLOCK
				return status;
			}
		}
		else
		{
			// Check if portbase is even (if necessary)
			if (!params->GetAllowOddPortbase() && params->GetPortbase()%2 != 0)
			{
				MAINMUTEX_UNLOCK
				return ERR_RTP_UDPV4TRANS_PORTBASENOTEVEN;
			}

			// create sockets

			rtpsock = socket(PF_INET,SOCK_DGRAM,0);
			if (rtpsock == RTPSOCKERR)
			{
				MAINMUTEX_UNLOCK
				return ERR_RTP_UDPV4TRANS_CANTCREATESOCKET;
			}

			// If we're multiplexing, we're just going to set the RTCP socket to equal the RTP socket
			if (params->GetRTCPMultiplexing())
				rtcpsock = rtpsock;
			else
			{
				rtcpsock = socket(PF_INET,SOCK_DGRAM,0);
				if (rtcpsock == RTPSOCKERR)
				{
					RTPCLOSE(rtpsock);
					MAINMUTEX_UNLOCK
					return ERR_RTP_UDPV4TRANS_CANTCREATESOCKET;
				}
			}

			// bind sockets

			uint32_t bindIP = params->GetBindIP();

			m_rtpPort = params->GetPortbase();

			memset(&addr,0,sizeof(struct sockaddr_in));
			addr.sin_family = AF_INET;
			addr.sin_port = htons(params->GetPortbase());
			addr.sin_addr.s_addr = htonl(bindIP);
			if (bind(rtpsock,(struct sockaddr *)&addr,sizeof(struct sockaddr_in)) != 0)
			{
				CLOSESOCKETS;
				MAINMUTEX_UNLOCK
				return ERR_RTP_UDPV4TRANS_CANTBINDRTPSOCKET;
			}

			if (rtpsock != rtcpsock) // no need to bind same socket twice when multiplexing
			{
				uint16_t rtpport = params->GetPortbase();
				uint16_t rtcpport = params->GetForcedRTCPPort();

				if (rtcpport == 0)
				{
					rtcpport = rtpport;
					if (rtcpport < 0xFFFF)
						rtcpport++;
				}

				memset(&addr,0,sizeof(struct sockaddr_in));
				addr.sin_family = AF_INET;
				addr.sin_port = htons(rtcpport);
				addr.sin_addr.s_addr = htonl(bindIP);
				if (bind(rtcpsock,(struct sockaddr *)&addr,sizeof(struct sockaddr_in)) != 0)
				{
					CLOSESOCKETS;
					MAINMUTEX_UNLOCK
					return ERR_RTP_UDPV4TRANS_CANTBINDRTCPSOCKET;
				}

				m_rtcpPort = rtcpport;
			}
			else
				m_rtcpPort = m_rtpPort;
		}

		// set socket buffer sizes

		size = params->GetRTPReceiveBuffer();
		if (setsockopt(rtpsock,SOL_SOCKET,SO_RCVBUF,(const char *)&size,sizeof(int)) != 0)
		{
			CLOSESOCKETS;
			MAINMUTEX_UNLOCK
			return ERR_RTP_UDPV4TRANS_CANTSETRTPRECEIVEBUF;
		}
		size = params->GetRTPSendBuffer();
		if (setsockopt(rtpsock,SOL_SOCKET,SO_SNDBUF,(const char *)&size,sizeof(int)) != 0)
		{
			CLOSESOCKETS;
			MAINMUTEX_UNLOCK
			return ERR_RTP_UDPV4TRANS_CANTSETRTPTRANSMITBUF;
		}

		if (rtpsock != rtcpsock) // no need to set RTCP flags when multiplexing
		{
			size = params->GetRTCPReceiveBuffer();
			if (setsockopt(rtcpsock,SOL_SOCKET,SO_RCVBUF,(const char *)&size,sizeof(int)) != 0)
			{
				CLOSESOCKETS;
				MAINMUTEX_UNLOCK
				return ERR_RTP_UDPV4TRANS_CANTSETRTCPRECEIVEBUF;
			}
			size = params->GetRTCPSendBuffer();
			if (setsockopt(rtcpsock,SOL_SOCKET,SO_SNDBUF,(const char *)&size,sizeof(int)) != 0)
			{
				CLOSESOCKETS;
				MAINMUTEX_UNLOCK
				return ERR_RTP_UDPV4TRANS_CANTSETRTCPTRANSMITBUF;
			}
		}
	}

	// Try to obtain local IP addresses

	localIPs = params->GetLocalIPList();
	if (localIPs.empty()) // User did not provide list of local IP addresses, calculate them
	{
		int status;

		if ((status = CreateLocalIPList()) < 0)
		{
			CLOSESOCKETS;
			MAINMUTEX_UNLOCK
			return status;
		}
#ifdef RTPDEBUG
		std::cout << "Found these local IP addresses:" << std::endl;

		std::list<uint32_t>::const_iterator it;

		for (it = localIPs.begin() ; it != localIPs.end() ; it++)
		{
			RTPIPv4Address a(*it);

			std::cout << a.GetAddressString() << std::endl;
		}
#endif // RTPDEBUG
	}

#ifdef RTP_SUPPORT_IPV4MULTICAST
	if (SetMulticastTTL(params->GetMulticastTTL()))
		supportsmulticasting = true;
	else
		supportsmulticasting = false;
#else // no multicast support enabled
	supportsmulticasting = false;
#endif // RTP_SUPPORT_IPV4MULTICAST

	if (maximumpacketsize > RTPUDPV4TRANS_MAXPACKSIZE)
	{
		CLOSESOCKETS;
		MAINMUTEX_UNLOCK
		return ERR_RTP_UDPV4TRANS_SPECIFIEDSIZETOOBIG;
	}

	if (!params->GetCreatedAbortDescriptors())
	{
		if ((status = m_abortDesc.Init()) < 0)
		{
			CLOSESOCKETS;
			MAINMUTEX_UNLOCK
			return status;
		}
		m_pAbortDesc = &m_abortDesc;
	}
	else
	{
		m_pAbortDesc = params->GetCreatedAbortDescriptors();
		if (!m_pAbortDesc->IsInitialized())
		{
			CLOSESOCKETS;
			MAINMUTEX_UNLOCK
			return ERR_RTP_ABORTDESC_NOTINIT;
		}
	}

	maxpacksize = maximumpacketsize;
	multicastTTL = params->GetMulticastTTL();
	mcastifaceIP = params->GetMulticastInterfaceIP();
	receivemode = RTPTransmitter::AcceptAll;

	localhostname = 0;
	localhostnamelength = 0;

	waitingfordata = false;
	created = true;
	MAINMUTEX_UNLOCK
	return 0;
}

void RTPUDPv4Transmitter::Destroy()
{
	if (!init)
		return;

	MAINMUTEX_LOCK
	if (!created)
	{
		MAINMUTEX_UNLOCK;
		return;
	}

	if (localhostname)
	{
		RTPDeleteByteArray(localhostname,GetMemoryManager());
		localhostname = 0;
		localhostnamelength = 0;
	}

	CLOSESOCKETS;
	destinations.Clear();
#ifdef RTP_SUPPORT_IPV4MULTICAST
	multicastgroups.Clear();
#endif // RTP_SUPPORT_IPV4MULTICAST
	FlushPackets();
	ClearAcceptIgnoreInfo();
	localIPs.clear();
	created = false;

	if (waitingfordata)
	{
		m_pAbortDesc->SendAbortSignal();
		m_abortDesc.Destroy(); // Doesn't do anything if not initialized
		MAINMUTEX_UNLOCK
		WAITMUTEX_LOCK // to make sure that the WaitForIncomingData function ended
		WAITMUTEX_UNLOCK
	}
	else
		m_abortDesc.Destroy(); // Doesn't do anything if not initialized

	MAINMUTEX_UNLOCK
}

RTPTransmissionInfo *RTPUDPv4Transmitter::GetTransmissionInfo()
{
	if (!init)
		return 0;

	MAINMUTEX_LOCK
	RTPTransmissionInfo *tinf = RTPNew(GetMemoryManager(),RTPMEM_TYPE_CLASS_RTPTRANSMISSIONINFO) RTPUDPv4TransmissionInfo(localIPs,rtpsock,rtcpsock,m_rtpPort,m_rtcpPort);
	MAINMUTEX_UNLOCK
	return tinf;
}

void RTPUDPv4Transmitter::DeleteTransmissionInfo(RTPTransmissionInfo *i)
{
	if (!init)
		return;

	RTPDelete(i, GetMemoryManager());
}

int RTPUDPv4Transmitter::GetLocalHostName(uint8_t *buffer,size_t *bufferlength)
{
	if (!init)
		return ERR_RTP_UDPV4TRANS_NOTINIT;

	MAINMUTEX_LOCK
	if (!created)
	{
		MAINMUTEX_UNLOCK
		return ERR_RTP_UDPV4TRANS_NOTCREATED;
	}

	if (localhostname == 0)
	{
		if (localIPs.empty())
		{
			MAINMUTEX_UNLOCK
			return ERR_RTP_UDPV4TRANS_NOLOCALIPS;
		}

		std::list<uint32_t>::const_iterator it;
		std::list<std::string> hostnames;

		for (it = localIPs.begin() ; it != localIPs.end() ; it++)
		{
			bool founddouble = false;
			bool foundentry = true;

			while (!founddouble && foundentry)
			{
				struct hostent *he;
				uint8_t addr[4];
				uint32_t ip = (*it);

				addr[0] = (uint8_t)((ip>>24)&0xFF);
				addr[1] = (uint8_t)((ip>>16)&0xFF);
				addr[2] = (uint8_t)((ip>>8)&0xFF);
				addr[3] = (uint8_t)(ip&0xFF);
				he = gethostbyaddr((char *)addr,4,AF_INET);
				if (he != 0)
				{
					std::string hname = std::string(he->h_name);
					std::list<std::string>::const_iterator it;

					for (it = hostnames.begin() ; !founddouble && it != hostnames.end() ; it++)
						if ((*it) == hname)
							founddouble = true;

					if (!founddouble)
						hostnames.push_back(hname);

					int i = 0;
					while (!founddouble && he->h_aliases[i] != 0)
					{
						std::string hname = std::string(he->h_aliases[i]);

						for (it = hostnames.begin() ; !founddouble && it != hostnames.end() ; it++)
							if ((*it) == hname)
								founddouble = true;

						if (!founddouble)
						{
							hostnames.push_back(hname);
							i++;
						}
					}
				}
				else
					foundentry = false;
			}
		}

		bool found  = false;

		if (!hostnames.empty())	// try to select the most appropriate hostname
		{
			std::list<std::string>::const_iterator it;

			hostnames.sort();
			for (it = hostnames.begin() ; !found && it != hostnames.end() ; it++)
			{
				if ((*it).find('.') != std::string::npos)
				{
					found = true;
					localhostnamelength = (*it).length();
					localhostname = RTPNew(GetMemoryManager(),RTPMEM_TYPE_OTHER) uint8_t [localhostnamelength+1];
					if (localhostname == 0)
					{
						MAINMUTEX_UNLOCK
						return ERR_RTP_OUTOFMEM;
					}
					memcpy(localhostname,(*it).c_str(),localhostnamelength);
					localhostname[localhostnamelength] = 0;
				}
			}
		}

		if (!found) // use an IP address
		{
			uint32_t ip;
			int len;
			char str[16];

			it = localIPs.begin();
			ip = (*it);

			RTP_SNPRINTF(str,16,"%d.%d.%d.%d",(int)((ip>>24)&0xFF),(int)((ip>>16)&0xFF),(int)((ip>>8)&0xFF),(int)(ip&0xFF));
			len = strlen(str);

			localhostnamelength = len;
			localhostname = RTPNew(GetMemoryManager(),RTPMEM_TYPE_OTHER) uint8_t [localhostnamelength + 1];
			if (localhostname == 0)
			{
				MAINMUTEX_UNLOCK
				return ERR_RTP_OUTOFMEM;
			}
			memcpy(localhostname,str,localhostnamelength);
			localhostname[localhostnamelength] = 0;
		}
	}

	if ((*bufferlength) < localhostnamelength)
	{
		*bufferlength = localhostnamelength; // tell the application the required size of the buffer
		MAINMUTEX_UNLOCK
		return ERR_RTP_TRANS_BUFFERLENGTHTOOSMALL;
	}

	memcpy(buffer,localhostname,localhostnamelength);
	*bufferlength = localhostnamelength;

	MAINMUTEX_UNLOCK
	return 0;
}

bool RTPUDPv4Transmitter::ComesFromThisTransmitter(const RTPAddress *addr)
{
	if (!init)
		return false;

	if (addr == 0)
		return false;

	MAINMUTEX_LOCK

	bool v;

	if (created && addr->GetAddressType() == RTPAddress::IPv4Address)
	{
		const RTPIPv4Address *addr2 = (const RTPIPv4Address *)addr;
		bool found = false;
		std::list<uint32_t>::const_iterator it;

		it = localIPs.begin();
		while (!found && it != localIPs.end())
		{
			if (addr2->GetIP() == *it)
				found = true;
			else
				++it;
		}

		if (!found)
			v = false;
		else
		{
			if (addr2->GetPort() == m_rtpPort || addr2->GetPort() == m_rtcpPort) // check for RTP port and RTCP port
				v = true;
			else
				v = false;
		}
	}
	else
		v = false;

	MAINMUTEX_UNLOCK
	return v;
}

int RTPUDPv4Transmitter::Poll()
{
	if (!init)
		return ERR_RTP_UDPV4TRANS_NOTINIT;

	int status;

	MAINMUTEX_LOCK
	if (!created)
	{
		MAINMUTEX_UNLOCK
		return ERR_RTP_UDPV4TRANS_NOTCREATED;
	}
	status = PollSocket(true); // poll RTP socket
	if (rtpsock != rtcpsock) // no need to poll twice when multiplexing
	{
		if (status >= 0)
			status = PollSocket(false); // poll RTCP socket
	}
	MAINMUTEX_UNLOCK
	return status;
}

int RTPUDPv4Transmitter::WaitForIncomingData(const RTPTime &delay,bool *dataavailable)
{
	if (!init)
		return ERR_RTP_UDPV4TRANS_NOTINIT;

	MAINMUTEX_LOCK

	if (!created)
	{
		MAINMUTEX_UNLOCK
		return ERR_RTP_UDPV4TRANS_NOTCREATED;
	}
	if (waitingfordata)
	{
		MAINMUTEX_UNLOCK
		return ERR_RTP_UDPV4TRANS_ALREADYWAITING;
	}

	SocketType abortSocket = m_pAbortDesc->GetAbortSocket();

	SocketType socks[3] = { rtpsock, rtcpsock, abortSocket };
	int8_t readflags[3] = { 0, 0, 0 };
	const int idxRTP = 0;
	const int idxRTCP = 1;
	const int idxAbort = 2;

	waitingfordata = true;

	WAITMUTEX_LOCK
	MAINMUTEX_UNLOCK

	int status = RTPSelect(socks, readflags, 3, delay);
	if (status < 0)
	{
		MAINMUTEX_LOCK
		waitingfordata = false;
		MAINMUTEX_UNLOCK
		WAITMUTEX_UNLOCK
		return status;
	}

	MAINMUTEX_LOCK
	waitingfordata = false;
	if (!created) // destroy called
	{
		MAINMUTEX_UNLOCK;
		WAITMUTEX_UNLOCK
		return 0;
	}

	// if aborted, read from abort buffer
	if (readflags[idxAbort])
		m_pAbortDesc->ReadSignallingByte();

	if (dataavailable != 0)
	{
		if (readflags[idxRTP] || readflags[idxRTCP])
			*dataavailable = true;
		else
			*dataavailable = false;
	}

	MAINMUTEX_UNLOCK
	WAITMUTEX_UNLOCK
	return 0;
}

int RTPUDPv4Transmitter::AbortWait()
{
	if (!init)
		return ERR_RTP_UDPV4TRANS_NOTINIT;

	MAINMUTEX_LOCK
	if (!created)
	{
		MAINMUTEX_UNLOCK
		return ERR_RTP_UDPV4TRANS_NOTCREATED;
	}
	if (!waitingfordata)
	{
		MAINMUTEX_UNLOCK
		return ERR_RTP_UDPV4TRANS_NOTWAITING;
	}

	m_pAbortDesc->SendAbortSignal();

	MAINMUTEX_UNLOCK
	return 0;
}

int RTPUDPv4Transmitter::SendRTPData(const void *data,size_t len)
{
	if (!init)
		return ERR_RTP_UDPV4TRANS_NOTINIT;

	MAINMUTEX_LOCK

	if (!created)
	{
		MAINMUTEX_UNLOCK
		return ERR_RTP_UDPV4TRANS_NOTCREATED;
	}
	if (len > maxpacksize)
	{
		MAINMUTEX_UNLOCK
		return ERR_RTP_UDPV4TRANS_SPECIFIEDSIZETOOBIG;
	}

	destinations.GotoFirstElement();
	while (destinations.HasCurrentElement())
	{
		sendto(rtpsock,(const char *)data,len,0,(const struct sockaddr *)destinations.GetCurrentElement().GetRTPSockAddr(),sizeof(struct sockaddr_in));
		destinations.GotoNextElement();
	}

	MAINMUTEX_UNLOCK
	return 0;
}

int RTPUDPv4Transmitter::SendRTCPData(const void *data,size_t len)
{
	if (!init)
		return ERR_RTP_UDPV4TRANS_NOTINIT;

	MAINMUTEX_LOCK

	if (!created)
	{
		MAINMUTEX_UNLOCK
		return ERR_RTP_UDPV4TRANS_NOTCREATED;
	}
	if (len > maxpacksize)
	{
		MAINMUTEX_UNLOCK
		return ERR_RTP_UDPV4TRANS_SPECIFIEDSIZETOOBIG;
	}

	destinations.GotoFirstElement();
	while (destinations.HasCurrentElement())
	{
		sendto(rtcpsock,(const char *)data,len,0,(const struct sockaddr *)destinations.GetCurrentElement().GetRTCPSockAddr(),sizeof(struct sockaddr_in));
		destinations.GotoNextElement();
	}

	MAINMUTEX_UNLOCK
	return 0;
}

int RTPUDPv4Transmitter::AddDestination(const RTPAddress &addr)
{
	if (!init)
		return ERR_RTP_UDPV4TRANS_NOTINIT;

	MAINMUTEX_LOCK

	if (!created)
	{
		MAINMUTEX_UNLOCK
		return ERR_RTP_UDPV4TRANS_NOTCREATED;
	}

	RTPIPv4Destination dest;
	if (!RTPIPv4Destination::AddressToDestination(addr, dest))
	{
		MAINMUTEX_UNLOCK
		return ERR_RTP_UDPV4TRANS_INVALIDADDRESSTYPE;
	}

	int status = destinations.AddElement(dest);

	MAINMUTEX_UNLOCK
	return status;
}

int RTPUDPv4Transmitter::DeleteDestination(const RTPAddress &addr)
{
	if (!init)
		return ERR_RTP_UDPV4TRANS_NOTINIT;

	MAINMUTEX_LOCK

	if (!created)
	{
		MAINMUTEX_UNLOCK
		return ERR_RTP_UDPV4TRANS_NOTCREATED;
	}
	RTPIPv4Destination dest;
	if (!RTPIPv4Destination::AddressToDestination(addr, dest))
	{
		MAINMUTEX_UNLOCK
		return ERR_RTP_UDPV4TRANS_INVALIDADDRESSTYPE;
	}

	int status = destinations.DeleteElement(dest);

	MAINMUTEX_UNLOCK
	return status;
}

void RTPUDPv4Transmitter::ClearDestinations()
{
	if (!init)
		return;

	MAINMUTEX_LOCK
	if (created)
		destinations.Clear();
	MAINMUTEX_UNLOCK
}

bool RTPUDPv4Transmitter::SupportsMulticasting()
{
	if (!init)
		return false;

	MAINMUTEX_LOCK

	bool v;

	if (!created)
		v = false;
	else
		v = supportsmulticasting;

	MAINMUTEX_UNLOCK
	return v;
}

#ifdef RTP_SUPPORT_IPV4MULTICAST

int RTPUDPv4Transmitter::JoinMulticastGroup(const RTPAddress &addr)
{
	if (!init)
		return ERR_RTP_UDPV4TRANS_NOTINIT;

	MAINMUTEX_LOCK

	int status;

	if (!created)
	{
		MAINMUTEX_UNLOCK
		return ERR_RTP_UDPV4TRANS_NOTCREATED;
	}
	if (addr.GetAddressType() != RTPAddress::IPv4Address)
	{
		MAINMUTEX_UNLOCK
		return ERR_RTP_UDPV4TRANS_INVALIDADDRESSTYPE;
	}

	const RTPIPv4Address &address = (const RTPIPv4Address &)addr;
	uint32_t mcastIP = address.GetIP();

	if (!RTPUDPV4TRANS_IS_MCASTADDR(mcastIP))
	{
		MAINMUTEX_UNLOCK
		return ERR_RTP_UDPV4TRANS_NOTAMULTICASTADDRESS;
	}

	status = multicastgroups.AddElement(mcastIP);
	if (status >= 0)
	{
		RTPUDPV4TRANS_MCASTMEMBERSHIP(rtpsock,IP_ADD_MEMBERSHIP,mcastIP,status);
		if (status != 0)
		{
			multicastgroups.DeleteElement(mcastIP);
			MAINMUTEX_UNLOCK
			return ERR_RTP_UDPV4TRANS_COULDNTJOINMULTICASTGROUP;
		}

		if (rtpsock != rtcpsock) // no need to join multicast group twice when multiplexing
		{
			RTPUDPV4TRANS_MCASTMEMBERSHIP(rtcpsock,IP_ADD_MEMBERSHIP,mcastIP,status);
			if (status != 0)
			{
				RTPUDPV4TRANS_MCASTMEMBERSHIP(rtpsock,IP_DROP_MEMBERSHIP,mcastIP,status);
				multicastgroups.DeleteElement(mcastIP);
				MAINMUTEX_UNLOCK
				return ERR_RTP_UDPV4TRANS_COULDNTJOINMULTICASTGROUP;
			}
		}
	}
	MAINMUTEX_UNLOCK
	return status;
}

int RTPUDPv4Transmitter::LeaveMulticastGroup(const RTPAddress &addr)
{
	if (!init)
		return ERR_RTP_UDPV4TRANS_NOTINIT;

	MAINMUTEX_LOCK

	int status;

	if (!created)
	{
		MAINMUTEX_UNLOCK
		return ERR_RTP_UDPV4TRANS_NOTCREATED;
	}
	if (addr.GetAddressType() != RTPAddress::IPv4Address)
	{
		MAINMUTEX_UNLOCK
		return ERR_RTP_UDPV4TRANS_INVALIDADDRESSTYPE;
	}

	const RTPIPv4Address &address = (const RTPIPv4Address &)addr;
	uint32_t mcastIP = address.GetIP();

	if (!RTPUDPV4TRANS_IS_MCASTADDR(mcastIP))
	{
		MAINMUTEX_UNLOCK
		return ERR_RTP_UDPV4TRANS_NOTAMULTICASTADDRESS;
	}

	status = multicastgroups.DeleteElement(mcastIP);
	if (status >= 0)
	{
		RTPUDPV4TRANS_MCASTMEMBERSHIP(rtpsock,IP_DROP_MEMBERSHIP,mcastIP,status);
		if (rtpsock != rtcpsock) // no need to leave multicast group twice when multiplexing
			RTPUDPV4TRANS_MCASTMEMBERSHIP(rtcpsock,IP_DROP_MEMBERSHIP,mcastIP,status);

		status = 0;
	}

	MAINMUTEX_UNLOCK
	return status;
}

void RTPUDPv4Transmitter::LeaveAllMulticastGroups()
{
	if (!init)
		return;

	MAINMUTEX_LOCK
	if (created)
	{
		multicastgroups.GotoFirstElement();
		while (multicastgroups.HasCurrentElement())
		{
			uint32_t mcastIP;
			int status = 0;

			mcastIP = multicastgroups.GetCurrentElement();

			RTPUDPV4TRANS_MCASTMEMBERSHIP(rtpsock,IP_DROP_MEMBERSHIP,mcastIP,status);
			if (rtpsock != rtcpsock) // no need to leave multicast group twice when multiplexing
				RTPUDPV4TRANS_MCASTMEMBERSHIP(rtcpsock,IP_DROP_MEMBERSHIP,mcastIP,status);
			JRTPLIB_UNUSED(status);

			multicastgroups.GotoNextElement();
		}
		multicastgroups.Clear();
	}
	MAINMUTEX_UNLOCK
}

#else // no multicast support

int RTPUDPv4Transmitter::JoinMulticastGroup(const RTPAddress &addr)
{
	return ERR_RTP_UDPV4TRANS_NOMULTICASTSUPPORT;
}

int RTPUDPv4Transmitter::LeaveMulticastGroup(const RTPAddress &addr)
{
	return ERR_RTP_UDPV4TRANS_NOMULTICASTSUPPORT;
}

void RTPUDPv4Transmitter::LeaveAllMulticastGroups()
{
}

#endif // RTP_SUPPORT_IPV4MULTICAST

int RTPUDPv4Transmitter::SetReceiveMode(RTPTransmitter::ReceiveMode m)
{
	if (!init)
		return ERR_RTP_UDPV4TRANS_NOTINIT;

	MAINMUTEX_LOCK
	if (!created)
	{
		MAINMUTEX_UNLOCK
		return ERR_RTP_UDPV4TRANS_NOTCREATED;
	}
	if (m != receivemode)
	{
		receivemode = m;
		acceptignoreinfo.Clear();
	}
	MAINMUTEX_UNLOCK
	return 0;
}

int RTPUDPv4Transmitter::AddToIgnoreList(const RTPAddress &addr)
{
	if (!init)
		return ERR_RTP_UDPV4TRANS_NOTINIT;

	MAINMUTEX_LOCK

	int status;

	if (!created)
	{
		MAINMUTEX_UNLOCK
		return ERR_RTP_UDPV4TRANS_NOTCREATED;
	}
	if (addr.GetAddressType() != RTPAddress::IPv4Address)
	{
		MAINMUTEX_UNLOCK
		return ERR_RTP_UDPV4TRANS_INVALIDADDRESSTYPE;
	}
	if (receivemode != RTPTransmitter::IgnoreSome)
	{
		MAINMUTEX_UNLOCK
		return ERR_RTP_UDPV4TRANS_DIFFERENTRECEIVEMODE;
	}

	const RTPIPv4Address &address = (const RTPIPv4Address &)addr;
	status = ProcessAddAcceptIgnoreEntry(address.GetIP(),address.GetPort());

	MAINMUTEX_UNLOCK
	return status;
}

int RTPUDPv4Transmitter::DeleteFromIgnoreList(const RTPAddress &addr)
{
	if (!init)
		return ERR_RTP_UDPV4TRANS_NOTINIT;

	MAINMUTEX_LOCK

	int status;

	if (!created)
	{
		MAINMUTEX_UNLOCK
		return ERR_RTP_UDPV4TRANS_NOTCREATED;
	}
	if (addr.GetAddressType() != RTPAddress::IPv4Address)
	{
		MAINMUTEX_UNLOCK
		return ERR_RTP_UDPV4TRANS_INVALIDADDRESSTYPE;
	}
	if (receivemode != RTPTransmitter::IgnoreSome)
	{
		MAINMUTEX_UNLOCK
		return ERR_RTP_UDPV4TRANS_DIFFERENTRECEIVEMODE;
	}

	const RTPIPv4Address &address = (const RTPIPv4Address &)addr;
	status = ProcessDeleteAcceptIgnoreEntry(address.GetIP(),address.GetPort());

	MAINMUTEX_UNLOCK
	return status;
}

void RTPUDPv4Transmitter::ClearIgnoreList()
{
	if (!init)
		return;

	MAINMUTEX_LOCK
	if (created && receivemode == RTPTransmitter::IgnoreSome)
		ClearAcceptIgnoreInfo();
	MAINMUTEX_UNLOCK
}

int RTPUDPv4Transmitter::AddToAcceptList(const RTPAddress &addr)
{
	if (!init)
		return ERR_RTP_UDPV4TRANS_NOTINIT;

	MAINMUTEX_LOCK

	int status;

	if (!created)
	{
		MAINMUTEX_UNLOCK
		return ERR_RTP_UDPV4TRANS_NOTCREATED;
	}
	if (addr.GetAddressType() != RTPAddress::IPv4Address)
	{
		MAINMUTEX_UNLOCK
		return ERR_RTP_UDPV4TRANS_INVALIDADDRESSTYPE;
	}
	if (receivemode != RTPTransmitter::AcceptSome)
	{
		MAINMUTEX_UNLOCK
		return ERR_RTP_UDPV4TRANS_DIFFERENTRECEIVEMODE;
	}

	const RTPIPv4Address &address = (const RTPIPv4Address &)addr;
	status = ProcessAddAcceptIgnoreEntry(address.GetIP(),address.GetPort());

	MAINMUTEX_UNLOCK
	return status;
}

int RTPUDPv4Transmitter::DeleteFromAcceptList(const RTPAddress &addr)
{
	if (!init)
		return ERR_RTP_UDPV4TRANS_NOTINIT;

	MAINMUTEX_LOCK

	int status;

	if (!created)
	{
		MAINMUTEX_UNLOCK
		return ERR_RTP_UDPV4TRANS_NOTCREATED;
	}
	if (addr.GetAddressType() != RTPAddress::IPv4Address)
	{
		MAINMUTEX_UNLOCK
		return ERR_RTP_UDPV4TRANS_INVALIDADDRESSTYPE;
	}
	if (receivemode != RTPTransmitter::AcceptSome)
	{
		MAINMUTEX_UNLOCK
		return ERR_RTP_UDPV4TRANS_DIFFERENTRECEIVEMODE;
	}

	const RTPIPv4Address &address = (const RTPIPv4Address &)addr;
	status = ProcessDeleteAcceptIgnoreEntry(address.GetIP(),address.GetPort());

	MAINMUTEX_UNLOCK
	return status;
}

void RTPUDPv4Transmitter::ClearAcceptList()
{
	if (!init)
		return;

	MAINMUTEX_LOCK
	if (created && receivemode == RTPTransmitter::AcceptSome)
		ClearAcceptIgnoreInfo();
	MAINMUTEX_UNLOCK
}

int RTPUDPv4Transmitter::SetMaximumPacketSize(size_t s)
{
	if (!init)
		return ERR_RTP_UDPV4TRANS_NOTINIT;

	MAINMUTEX_LOCK
	if (!created)
	{
		MAINMUTEX_UNLOCK
		return ERR_RTP_UDPV4TRANS_NOTCREATED;
	}
	if (s > RTPUDPV4TRANS_MAXPACKSIZE)
	{
		MAINMUTEX_UNLOCK
		return ERR_RTP_UDPV4TRANS_SPECIFIEDSIZETOOBIG;
	}
	maxpacksize = s;
	MAINMUTEX_UNLOCK
	return 0;
}

bool RTPUDPv4Transmitter::NewDataAvailable()
{
	if (!init)
		return false;

	MAINMUTEX_LOCK

	bool v;

	if (!created)
		v = false;
	else
	{
		if (rawpacketlist.empty())
			v = false;
		else
			v = true;
	}

	MAINMUTEX_UNLOCK
	return v;
}

RTPRawPacket *RTPUDPv4Transmitter::GetNextPacket()
{
	if (!init)
		return 0;

	MAINMUTEX_LOCK

	RTPRawPacket *p;

	if (!created)
	{
		MAINMUTEX_UNLOCK
		return 0;
	}
	if (rawpacketlist.empty())
	{
		MAINMUTEX_UNLOCK
		return 0;
	}

	p = *(rawpacketlist.begin());
	rawpacketlist.pop_front();

	MAINMUTEX_UNLOCK
	return p;
}

// Here the private functions start...

#ifdef RTP_SUPPORT_IPV4MULTICAST
bool RTPUDPv4Transmitter::SetMulticastTTL(uint8_t ttl)
{
	int ttl2,status;

	ttl2 = (int)ttl;
	status = setsockopt(rtpsock,IPPROTO_IP,IP_MULTICAST_TTL,(const char *)&ttl2,sizeof(int));
	if (status != 0)
		return false;

	if (rtpsock != rtcpsock) // no need to set TTL twice when multiplexing
	{
		status = setsockopt(rtcpsock,IPPROTO_IP,IP_MULTICAST_TTL,(const char *)&ttl2,sizeof(int));
		if (status != 0)
			return false;
	}
	return true;
}
#endif // RTP_SUPPORT_IPV4MULTICAST

void RTPUDPv4Transmitter::FlushPackets()
{
	std::list<RTPRawPacket*>::const_iterator it;

	for (it = rawpacketlist.begin() ; it != rawpacketlist.end() ; ++it)
		RTPDelete(*it,GetMemoryManager());
	rawpacketlist.clear();
}

int RTPUDPv4Transmitter::PollSocket(bool rtp)
{
	RTPSOCKLENTYPE fromlen;
	int recvlen;
	char packetbuffer[RTPUDPV4TRANS_MAXPACKSIZE];
#ifdef RTP_SOCKETTYPE_WINSOCK
	SOCKET sock;
	unsigned long len;
#else
	size_t len;
	int sock;
#endif // RTP_SOCKETTYPE_WINSOCK
	struct sockaddr_in srcaddr;
	bool dataavailable;

	if (rtp)
		sock = rtpsock;
	else
		sock = rtcpsock;

	do
	{
		len = 0;
		RTPIOCTL(sock,FIONREAD,&len);

		if (len <= 0) // make sure a packet of length zero is not queued
		{
			// An alternative workaround would be to just use non-blocking sockets.
			// However, since the user does have access to the sockets and I do not
			// know how this would affect anyone else's code, I chose to do it using
			// an extra select call in case ioctl says the length is zero.

			int8_t isset = 0;
			int status = RTPSelect(&sock, &isset, 1, RTPTime(0));
			if (status < 0)
				return status;

			if (isset)
				dataavailable = true;
			else
				dataavailable = false;
		}
		else
			dataavailable = true;

		if (dataavailable)
		{
			RTPTime curtime = RTPTime::CurrentTime();
			fromlen = sizeof(struct sockaddr_in);
			recvlen = recvfrom(sock,packetbuffer,RTPUDPV4TRANS_MAXPACKSIZE,0,(struct sockaddr *)&srcaddr,&fromlen);
			if (recvlen > 0)
			{
				bool acceptdata;

				// got data, process it
				if (receivemode == RTPTransmitter::AcceptAll)
					acceptdata = true;
				else
					acceptdata = ShouldAcceptData(ntohl(srcaddr.sin_addr.s_addr),ntohs(srcaddr.sin_port));

				if (acceptdata)
				{
					RTPRawPacket *pack;
					RTPIPv4Address *addr;
					uint8_t *datacopy;

					addr = RTPNew(GetMemoryManager(),RTPMEM_TYPE_CLASS_RTPADDRESS) RTPIPv4Address(ntohl(srcaddr.sin_addr.s_addr),ntohs(srcaddr.sin_port));
					if (addr == 0)
						return ERR_RTP_OUTOFMEM;
					datacopy = RTPNew(GetMemoryManager(),(rtp)?RTPMEM_TYPE_BUFFER_RECEIVEDRTPPACKET:RTPMEM_TYPE_BUFFER_RECEIVEDRTCPPACKET) uint8_t[recvlen];
					if (datacopy == 0)
					{
						RTPDelete(addr,GetMemoryManager());
						return ERR_RTP_OUTOFMEM;
					}
					memcpy(datacopy,packetbuffer,recvlen);

					bool isrtp = rtp;
					if (rtpsock == rtcpsock) // check payload type when multiplexing
					{
						isrtp = true;

						if ((size_t)recvlen > sizeof(RTCPCommonHeader))
						{
							RTCPCommonHeader *rtcpheader = (RTCPCommonHeader *)datacopy;
							uint8_t packettype = rtcpheader->packettype;

    						if (packettype >= 200 && packettype <= 204)
								isrtp = false;
						}
					}

					pack = RTPNew(GetMemoryManager(),RTPMEM_TYPE_CLASS_RTPRAWPACKET) RTPRawPacket(datacopy,recvlen,addr,curtime,isrtp,GetMemoryManager());
					if (pack == 0)
					{
						RTPDelete(addr,GetMemoryManager());
						RTPDeleteByteArray(datacopy,GetMemoryManager());
						return ERR_RTP_OUTOFMEM;
					}
					rawpacketlist.push_back(pack);
				}
			}
		}
	} while (dataavailable);

	return 0;
}

int RTPUDPv4Transmitter::ProcessAddAcceptIgnoreEntry(uint32_t ip,uint16_t port)
{
	acceptignoreinfo.GotoElement(ip);
	if (acceptignoreinfo.HasCurrentElement()) // An entry for this IP address already exists
	{
		PortInfo *portinf = acceptignoreinfo.GetCurrentElement();

		if (port == 0) // select all ports
		{
			portinf->all = true;
			portinf->portlist.clear();
		}
		else if (!portinf->all)
		{
			std::list<uint16_t>::const_iterator it,begin,end;

			begin = portinf->portlist.begin();
			end = portinf->portlist.end();
			for (it = begin ; it != end ; it++)
			{
				if (*it == port) // already in list
					return 0;
			}
			portinf->portlist.push_front(port);
		}
	}
	else // got to create an entry for this IP address
	{
		PortInfo *portinf;
		int status;

		portinf = RTPNew(GetMemoryManager(),RTPMEM_TYPE_CLASS_ACCEPTIGNOREPORTINFO) PortInfo();
		if (port == 0) // select all ports
			portinf->all = true;
		else
			portinf->portlist.push_front(port);

		status = acceptignoreinfo.AddElement(ip,portinf);
		if (status < 0)
		{
			RTPDelete(portinf,GetMemoryManager());
			return status;
		}
	}

	return 0;
}

void RTPUDPv4Transmitter::ClearAcceptIgnoreInfo()
{
	acceptignoreinfo.GotoFirstElement();
	while (acceptignoreinfo.HasCurrentElement())
	{
		PortInfo *inf;

		inf = acceptignoreinfo.GetCurrentElement();
		RTPDelete(inf,GetMemoryManager());
		acceptignoreinfo.GotoNextElement();
	}
	acceptignoreinfo.Clear();
}

int RTPUDPv4Transmitter::ProcessDeleteAcceptIgnoreEntry(uint32_t ip,uint16_t port)
{
	acceptignoreinfo.GotoElement(ip);
	if (!acceptignoreinfo.HasCurrentElement())
		return ERR_RTP_UDPV4TRANS_NOSUCHENTRY;

	PortInfo *inf;

	inf = acceptignoreinfo.GetCurrentElement();
	if (port == 0) // delete all entries
	{
		inf->all = false;
		inf->portlist.clear();
	}
	else // a specific port was selected
	{
		if (inf->all) // currently, all ports are selected. Add the one to remove to the list
		{
			// we have to check if the list doesn't contain the port already
			std::list<uint16_t>::const_iterator it,begin,end;

			begin = inf->portlist.begin();
			end = inf->portlist.end();
			for (it = begin ; it != end ; it++)
			{
				if (*it == port) // already in list: this means we already deleted the entry
					return ERR_RTP_UDPV4TRANS_NOSUCHENTRY;
			}
			inf->portlist.push_front(port);
		}
		else // check if we can find the port in the list
		{
			std::list<uint16_t>::iterator it,begin,end;

			begin = inf->portlist.begin();
			end = inf->portlist.end();
			for (it = begin ; it != end ; ++it)
			{
				if (*it == port) // found it!
				{
					inf->portlist.erase(it);
					return 0;
				}
			}
			// didn't find it
			return ERR_RTP_UDPV4TRANS_NOSUCHENTRY;
		}
	}
	return 0;
}

bool RTPUDPv4Transmitter::ShouldAcceptData(uint32_t srcip,uint16_t srcport)
{
	if (receivemode == RTPTransmitter::AcceptSome)
	{
		PortInfo *inf;

		acceptignoreinfo.GotoElement(srcip);
		if (!acceptignoreinfo.HasCurrentElement())
			return false;

		inf = acceptignoreinfo.GetCurrentElement();
		if (!inf->all) // only accept the ones in the list
		{
			std::list<uint16_t>::const_iterator it,begin,end;

			begin = inf->portlist.begin();
			end = inf->portlist.end();
			for (it = begin ; it != end ; it++)
			{
				if (*it == srcport)
					return true;
			}
			return false;
		}
		else // accept all, except the ones in the list
		{
			std::list<uint16_t>::const_iterator it,begin,end;

			begin = inf->portlist.begin();
			end = inf->portlist.end();
			for (it = begin ; it != end ; it++)
			{
				if (*it == srcport)
					return false;
			}
			return true;
		}
	}
	else // IgnoreSome
	{
		PortInfo *inf;

		acceptignoreinfo.GotoElement(srcip);
		if (!acceptignoreinfo.HasCurrentElement())
			return true;

		inf = acceptignoreinfo.GetCurrentElement();
		if (!inf->all) // ignore the ports in the list
		{
			std::list<uint16_t>::const_iterator it,begin,end;

			begin = inf->portlist.begin();
			end = inf->portlist.end();
			for (it = begin ; it != end ; it++)
			{
				if (*it == srcport)
					return false;
			}
			return true;
		}
		else // ignore all, except the ones in the list
		{
			std::list<uint16_t>::const_iterator it,begin,end;

			begin = inf->portlist.begin();
			end = inf->portlist.end();
			for (it = begin ; it != end ; it++)
			{
				if (*it == srcport)
					return true;
			}
			return false;
		}
	}
	return true;
}

int RTPUDPv4Transmitter::CreateLocalIPList()
{
	 // first try to obtain the list from the network interface info

	if (!GetLocalIPList_Interfaces())
	{
		// If this fails, we'll have to depend on DNS info
		GetLocalIPList_DNS();
	}
	AddLoopbackAddress();
	return 0;
}

#ifdef RTP_SOCKETTYPE_WINSOCK

bool RTPUDPv4Transmitter::GetLocalIPList_Interfaces()
{
	unsigned char buffer[RTPUDPV4TRANS_IFREQBUFSIZE];
	DWORD outputsize;
	DWORD numaddresses,i;
	SOCKET_ADDRESS_LIST *addrlist;

	if (WSAIoctl(rtpsock,SIO_ADDRESS_LIST_QUERY,NULL,0,&buffer,RTPUDPV4TRANS_IFREQBUFSIZE,&outputsize,NULL,NULL))
		return false;

	addrlist = (SOCKET_ADDRESS_LIST *)buffer;
	numaddresses = addrlist->iAddressCount;
	for (i = 0 ; i < numaddresses ; i++)
	{
		SOCKET_ADDRESS *sockaddr = &(addrlist->Address[i]);
		if (sockaddr->iSockaddrLength == sizeof(struct sockaddr_in)) // IPv4 address
		{
			struct sockaddr_in *addr = (struct sockaddr_in *)sockaddr->lpSockaddr;

			localIPs.push_back(ntohl(addr->sin_addr.s_addr));
		}
	}

	if (localIPs.empty())
		return false;

	return true;
}

#else // use either getifaddrs or ioctl

#ifdef RTP_SUPPORT_IFADDRS

bool RTPUDPv4Transmitter::GetLocalIPList_Interfaces()
{
	struct ifaddrs *addrs,*tmp;

	getifaddrs(&addrs);
	tmp = addrs;

	while (tmp != 0)
	{
		if (tmp->ifa_addr != 0 && tmp->ifa_addr->sa_family == AF_INET)
		{
			struct sockaddr_in *inaddr = (struct sockaddr_in *)tmp->ifa_addr;
			localIPs.push_back(ntohl(inaddr->sin_addr.s_addr));
		}
		tmp = tmp->ifa_next;
	}

	freeifaddrs(addrs);

	if (localIPs.empty())
		return false;
	return true;
}

#else // user ioctl

bool RTPUDPv4Transmitter::GetLocalIPList_Interfaces()
{
	int status;
	char buffer[RTPUDPV4TRANS_IFREQBUFSIZE];
	struct ifconf ifc;
	struct ifreq *ifr;
	struct sockaddr *sa;
	char *startptr,*endptr;
	int remlen;

	ifc.ifc_len = RTPUDPV4TRANS_IFREQBUFSIZE;
	ifc.ifc_buf = buffer;
	status = ioctl(rtpsock,SIOCGIFCONF,&ifc);
	if (status < 0)
		return false;

	startptr = (char *)ifc.ifc_req;
	endptr = startptr + ifc.ifc_len;
	remlen = ifc.ifc_len;
	while((startptr < endptr) && remlen >= (int)sizeof(struct ifreq))
	{
		ifr = (struct ifreq *)startptr;
		sa = &(ifr->ifr_addr);
#ifdef RTP_HAVE_SOCKADDR_LEN
		if (sa->sa_len <= sizeof(struct sockaddr))
		{
			if (sa->sa_len == sizeof(struct sockaddr_in) && sa->sa_family == PF_INET)
			{
				uint32_t ip;
				struct sockaddr_in *addr = (struct sockaddr_in *)sa;

				ip = ntohl(addr->sin_addr.s_addr);
				localIPs.push_back(ip);
			}
			remlen -= sizeof(struct ifreq);
			startptr += sizeof(struct ifreq);
		}
		else
		{
			int l = sa->sa_len-sizeof(struct sockaddr)+sizeof(struct ifreq);

			remlen -= l;
			startptr += l;
		}
#else // don't have sa_len in struct sockaddr
		if (sa->sa_family == PF_INET)
		{
			uint32_t ip;
			struct sockaddr_in *addr = (struct sockaddr_in *)sa;

			ip = ntohl(addr->sin_addr.s_addr);
			localIPs.push_back(ip);
		}
		remlen -= sizeof(struct ifreq);
		startptr += sizeof(struct ifreq);

#endif // RTP_HAVE_SOCKADDR_LEN
	}

	if (localIPs.empty())
		return false;
	return true;
}

#endif // RTP_SUPPORT_IFADDRS

#endif // RTP_SOCKETTYPE_WINSOCK

void RTPUDPv4Transmitter::GetLocalIPList_DNS()
{
	struct hostent *he;
	char name[1024];
	bool done;
	int i,j;

	gethostname(name,1023);
	name[1023] = 0;
	he = gethostbyname(name);
	if (he == 0)
		return;

	i = 0;
	done = false;
	while (!done)
	{
		if (he->h_addr_list[i] == NULL)
			done = true;
		else
		{
			uint32_t ip = 0;

			for (j = 0 ; j < 4 ; j++)
				ip |= ((uint32_t)((unsigned char)he->h_addr_list[i][j])<<((3-j)*8));
			localIPs.push_back(ip);
			i++;
		}
	}
}

void RTPUDPv4Transmitter::AddLoopbackAddress()
{
	uint32_t loopbackaddr = (((uint32_t)127)<<24)|((uint32_t)1);
	std::list<uint32_t>::const_iterator it;
	bool found = false;

	for (it = localIPs.begin() ; !found && it != localIPs.end() ; it++)
	{
		if (*it == loopbackaddr)
			found = true;
	}

	if (!found)
		localIPs.push_back(loopbackaddr);
}

#ifdef RTPDEBUG
void RTPUDPv4Transmitter::Dump()
{
	if (!init)
		std::cout << "Not initialized" << std::endl;
	else
	{
		MAINMUTEX_LOCK

		if (!created)
			std::cout << "Not created" << std::endl;
		else
		{
			char str[16];
			uint32_t ip;
			std::list<uint32_t>::const_iterator it;

			std::cout << "RTP Port:                       " << m_rtpPort << std::endl;
			std::cout << "RTCP Port:                      " << m_rtcpPort << std::endl;
			std::cout << "RTP socket descriptor:          " << rtpsock << std::endl;
			std::cout << "RTCP socket descriptor:         " << rtcpsock << std::endl;
			ip = mcastifaceIP;
			RTP_SNPRINTF(str,16,"%d.%d.%d.%d",(int)((ip>>24)&0xFF),(int)((ip>>16)&0xFF),(int)((ip>>8)&0xFF),(int)(ip&0xFF));
			std::cout << "Multicast interface IP address: " << str << std::endl;
			std::cout << "Local IP addresses:" << std::endl;
			for (it = localIPs.begin() ; it != localIPs.end() ; it++)
			{
				ip = (*it);
				RTP_SNPRINTF(str,16,"%d.%d.%d.%d",(int)((ip>>24)&0xFF),(int)((ip>>16)&0xFF),(int)((ip>>8)&0xFF),(int)(ip&0xFF));
				std::cout << "    " << str << std::endl;
			}
			std::cout << "Multicast TTL:                  " << (int)multicastTTL << std::endl;
			std::cout << "Receive mode:                   ";
			switch (receivemode)
			{
			case RTPTransmitter::AcceptAll:
				std::cout << "Accept all";
				break;
			case RTPTransmitter::AcceptSome:
				std::cout << "Accept some";
				break;
			case RTPTransmitter::IgnoreSome:
				std::cout << "Ignore some";
			}
			std::cout << std::endl;
			if (receivemode != RTPTransmitter::AcceptAll)
			{
				acceptignoreinfo.GotoFirstElement();
				while(acceptignoreinfo.HasCurrentElement())
				{
					ip = acceptignoreinfo.GetCurrentKey();
					RTP_SNPRINTF(str,16,"%d.%d.%d.%d",(int)((ip>>24)&0xFF),(int)((ip>>16)&0xFF),(int)((ip>>8)&0xFF),(int)(ip&0xFF));
					PortInfo *pinfo = acceptignoreinfo.GetCurrentElement();
					std::cout << "    " << str << ": ";
					if (pinfo->all)
					{
						std::cout << "All ports";
						if (!pinfo->portlist.empty())
							std::cout << ", except ";
					}

					std::list<uint16_t>::const_iterator it;

					for (it = pinfo->portlist.begin() ; it != pinfo->portlist.end() ; )
					{
						std::cout << (*it);
						it++;
						if (it != pinfo->portlist.end())
							std::cout << ", ";
					}
					std::cout << std::endl;
				}
			}

			std::cout << "Local host name:                ";
			if (localhostname == 0)
				std::cout << "Not set";
			else
				std::cout << localhostname;
			std::cout << std::endl;

			std::cout << "List of destinations:           ";
			destinations.GotoFirstElement();
			if (destinations.HasCurrentElement())
			{
				std::cout << std::endl;
				do
				{
					std::cout << "    " << destinations.GetCurrentElement().GetDestinationString() << std::endl;
					destinations.GotoNextElement();
				} while (destinations.HasCurrentElement());
			}
			else
				std::cout << "Empty" << std::endl;

			std::cout << "Supports multicasting:          " << ((supportsmulticasting)?"Yes":"No") << std::endl;
#ifdef RTP_SUPPORT_IPV4MULTICAST
			std::cout << "List of multicast groups:       ";
			multicastgroups.GotoFirstElement();
			if (multicastgroups.HasCurrentElement())
			{
				std::cout << std::endl;
				do
				{
					ip = multicastgroups.GetCurrentElement();
					RTP_SNPRINTF(str,16,"%d.%d.%d.%d",(int)((ip>>24)&0xFF),(int)((ip>>16)&0xFF),(int)((ip>>8)&0xFF),(int)(ip&0xFF));
					std::cout << "    " << str << std::endl;
					multicastgroups.GotoNextElement();
				} while (multicastgroups.HasCurrentElement());
			}
			else
				std::cout << "Empty" << std::endl;
#endif // RTP_SUPPORT_IPV4MULTICAST

			std::cout << "Number of raw packets in queue: " << rawpacketlist.size() << std::endl;
			std::cout << "Maximum allowed packet size:    " << maxpacksize << std::endl;
		}

		MAINMUTEX_UNLOCK
	}
}
#endif // RTPDEBUG

} // end namespace


text:
RARE Antique 1892 TEXAS COTTON BOOK Ledger? Waldeck Texas Fayette County 11x17
RARE Antique 1892 TEXAS COTTON BOOK Ledger? Waldeck Texas Fayette County 11x17. Fantastic Texas and Fayette County History from the time when Cotton was King. And Postmarked JUL 13 1893 and a copy of the book From Can See to Can't - detailing cotton farming in the 1920's in the same area represented in the ledger (more detail further below). A beautiful front cover label with a large superimposed red "1". 214, 216, 218, 220 Tremont St. In Exceptional Antiquarian Condition - 1/2 Leather Bound with Marbleized Boards and Page Edges - Binding Holding Well - Museum Worthy. Only one other example found for sale - in poor condition and listed at twice the price. Dimensions (Ledger): 11.5"W x 17 1/8"H x 3/8D. Dimensions (Trade Card): 9"W x 4"H. History in a Pecan Shell. Count Ludwig Joseph von Boos-Waldeck is the community's namesake. The count was head of a German Immigration Society when that organization bought the site in 1843.
First known as Long Prairie, Texas, a post office was opened under that name in 1860. The Long Prairie German Company (Infantry) was mustered in at the start of the Civil War. This was ironic since most German immigration was undertaken to avoid conscription in Europe.
Long Prairie's post office closed in 1876 but reopened under the name Waldeck in 1881. It stayed open until its permanent closure in 1925. In 1900 Waldeck was peaking. Besides the post office, the community was a voting precinct and had a saloon, store, blacksmith and cotton gin. Corn and cotton were principle crops although the soil was considered poor and the area was prone to flooding. By 1950 Waldeck had just two businesses to serve a population of 60. From Can See to Can't? Southern Prairies Texas Cotton Farmers 1997 1st Ed SIGNED. University of Texas Press, Austin, Texas, 1997. Inscribed, SIGNED and dated (2005) by Dan K. Utley on the title page. Cotton farming was the only way of life that many Texans knew from the days of Austin's Colony up until World War II.
For those who worked the land, it was a dawn-till-dark, "can see to can't, " process that required not only a wide range of specialized skills but also a willingness to gamble on forces often beyond a farmer's control - weather, insects, plant diseases, and the cotton market. This unique book offers an insider's view of Texas cotton farming in the late 1920s. Drawing on the memories of farmers and their descendants, many of whom are quoted here, the authors trace a year in the life of south central Texas cotton farms. From breaking ground to planting, cultivating, and harvesting, they describe the typical tasks of farm families - as well as their houses, food, and clothing; the farm animals they depended on; their communities; and the holidays, activities, and observances that offered the farmers respite from hard work. Although cotton farming still goes on in Texas, the lifeways described here have nearly vanished as the state has become highly urbanized.
Thus, this book preserves a fascinating record of an important part of Texas' rural heritage. SCARCE as a signed volume. Dimensions: 6.25"W x 9.25"H x 1D. This item is in the category "Books & Magazines\Antiquarian & Collectible". The seller is "imgonnamissyou" and is located in this country: US.
Place of Publication: Galveston, Texas
Topic: Cotton
Subject: Texana