123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068 |
- #include <stdio.h>
- #include <unistd.h>
- #include <string.h>
- #include <string>
- #include <vector>
- #include <map>
- #include <ext/stdio_filebuf.h>
- #include <iostream>
- #include <fstream>
- #include <signal.h>
- #include <sys/statvfs.h>
- #include <sys/statfs.h>
- #include <sys/types.h>
- #include <fcntl.h>
- #include <unistd.h>
- #include <limits.h>
- #include <libudev.h>
- #include <poll.h>
- #include <errno.h>
- #include <gfa/gfasitarautils.h>
- #include "../../src/gfaipc.h"
- #include "../../src/ipcpriv.h"
- /////////////////////////////////////////////////////////////////////////////
- #ifdef _DEBUG
- #define TRACE(...) fprintf(stdout, __VA_ARGS__), fflush(stdout)
- #else // _DEBUG
- #define TRACE(...)
- #endif // _DEBUG
- #define UNUSED(v) (void)v
- #define _countof(a) (sizeof(a) / sizeof(*a))
- /////////////////////////////////////////////////////////////////////////////
- #define _BYTE_SIZE_KIB (1ULL << 10) // Kibibyte
- #define _BYTE_SIZE_MIB (1ULL << 20) // Mebibyte
- #define _BYTE_SIZE_GIB (1ULL << 30) // Gibibyte
- #define _BYTE_SIZE_TIB (1ULL << 40) // Tebibyte
- #define _BYTE_SIZE_PIB (1ULL << 50) // Pebibyte
- #define _BYTE_SIZE_EIB (1ULL << 60) // Exbibyte
- #define _APPID GFA_APPCTRL_APPID_SYSINFO
- #define _APPNAME "SysInfo"
- #define _CYCLE_INTV 500
- #define _STR_EQUALS(s, t) (!!s && !strcmp(s, t))
- #define _MOUNTS_FILE "/proc/mounts"
- #define _INTERNAL_EMMC_DISK "mmcblk1"
- #define _INTERNAL_EMMC_PART1 "mmcblk1p1"
- #define _INTERNAL_EMMC_PART2 "mmcblk1p2"
- /////////////////////////////////////////////////////////////////////////////
- typedef std::map<std::string, std::string> MountMap;
- /////////////////////////////////////////////////////////////////////////////
- static volatile bool g_fRun = false;
- static volatile bool g_fPause = false;
- static volatile bool g_fZombie = false;
- /////////////////////////////////////////////////////////////////////////////
- static const char *g_pszStateNames[] =
- {
- "Not running",
- "Initializing",
- "Running",
- "Paused",
- "Hanging",
- "Terminating",
- "Invalid"
- };
- /////////////////////////////////////////////////////////////////////////////
- static long long _NumberFromString(const char *pszString, int base = 10, bool *pbErr = NULL);
- static const char* _ReadDevPropertyValue(struct udev_device* dev, const char *pszKey, char *pszValue, size_t nCChValue, bool bTruncate = false);
- static long long _ReadDevPropertyValue(struct udev_device* dev, const char *pszKey, int base = 10, bool *pbErr = NULL);
- /////////////////////////////////////////////////////////////////////////////
- /////////////////////////////////////////////////////////////////////////////
- /////////////////////////////////////////////////////////////////////////////
- static int _LookupPartition(const GFA_SYSINFO_STORAGE_DEVICE_MAP &sdm, const char *pszDevNode)
- {
- int nIndex = -1;
- if(pszDevNode && *pszDevNode)
- {
- for(size_t i = 0; i < _countof(sdm.parts); ++i)
- {
- if(sdm.parts[i].valid && !strcmp(sdm.parts[i].szDevNode, pszDevNode))
- {
- nIndex = i; // found partition
- break;
- }
- }
- }
- return nIndex;
- }
- static int _AddPartition(GFA_SYSINFO_STORAGE_DEVICE_MAP &sdm, const GFA_SYSINFO_PARTITION &part, bool &bChange)
- {
- int nIndex = -1;
- bChange = false;
- if((nIndex = _LookupPartition(sdm, part.szDevNode)) >= 0)
- return nIndex; // partition already exists
- for(size_t i = 0; i < _countof(sdm.parts); ++i)
- {
- if(!sdm.parts[i].valid)
- {
- memcpy(&sdm.parts[i], &part, sizeof(GFA_SYSINFO_PARTITION));
- sdm.parts[i].valid = true;
- bChange = true;
- nIndex = i;
- break;
- }
- }
- return nIndex;
- }
- static int _RemovePartition(GFA_SYSINFO_STORAGE_DEVICE_MAP &sdm, int nIndex, bool &bChange)
- {
- bChange = false;
- if(nIndex >= 0 && nIndex < (int)_countof(sdm.parts))
- {
- bChange = sdm.parts[nIndex].valid;
- sdm.parts[nIndex].valid = false;
- }
- return nIndex;
- }
- #if 0
- static int _RemovePartition(GFA_SYSINFO_STORAGE_DEVICE_MAP &sdm, const char *pszDevNode, bool &bChange)
- {
- int nIndex = _LookupPartition(sdm, pszDevNode);
- return _RemovePartition(sdm, nIndex, bChange);
- }
- #endif
- static bool _PartitionSetDisk(GFA_SYSINFO_STORAGE_DEVICE_MAP &sdm, int nPartIdx, int nDiskIdx, bool &bChange)
- {
- bChange = false;
- if( (nPartIdx >= 0) && (nPartIdx < (int)_countof(sdm.parts)) &&
- (nDiskIdx >= 0) && (nDiskIdx < (int)_countof(sdm.disks)))
- {
- if(sdm.parts[nPartIdx].nDiskIdx != nDiskIdx)
- {
- sdm.parts[nPartIdx].nDiskIdx = nDiskIdx;
- bChange = true;
- }
- return true;
- }
- return false;
- }
- static int _PartitionGetDisk(GFA_SYSINFO_STORAGE_DEVICE_MAP &sdm, int nPartIdx)
- {
- if((nPartIdx >= 0) && (nPartIdx < (int)_countof(sdm.parts)))
- return sdm.parts[nPartIdx].nDiskIdx;
- return -1;
- }
- static void _ClearMapChanges(GFA_SYSINFO_STORAGE_DEVICE_MAP &sdm)
- {
- sdm.nPartChangeMask = 0;
- }
- static bool _DeviceMapChanged(const GFA_SYSINFO_STORAGE_DEVICE_MAP &sdm)
- {
- return !!sdm.nPartChangeMask;
- }
- static unsigned int _SetPartitionChange(GFA_SYSINFO_STORAGE_DEVICE_MAP &sdm, int nPartIdx)
- {
- if((nPartIdx >= 0) && (nPartIdx < (int)_countof(sdm.parts)))
- {
- unsigned int nChanged = (0x01 << nPartIdx);
- sdm.nPartChangeMask |= nChanged;
- }
- return sdm.nPartChangeMask;
- }
- /////////////////////////////////////////////////////////////////////////////
- static int _LookupDisk(const GFA_SYSINFO_STORAGE_DEVICE_MAP &sdm, const char *pszDevNode)
- {
- int nIndex = -1;
- if(pszDevNode && *pszDevNode)
- {
- for(size_t i = 0; i < _countof(sdm.disks); ++i)
- {
- if(sdm.disks[i].valid && !strcmp(sdm.disks[i].szDevNode, pszDevNode))
- {
- nIndex = i; // found partition
- break;
- }
- }
- }
- return nIndex;
- }
- static int _AddDisk(GFA_SYSINFO_STORAGE_DEVICE_MAP &sdm, const GFA_SYSINFO_DISK &disk, bool &bChange)
- {
- int nIndex = -1;
- bChange = false;
- if((nIndex = _LookupDisk(sdm, disk.szDevNode)) >= 0)
- return nIndex; // partition already exists
- for(size_t i = 0; i < _countof(sdm.disks); ++i)
- {
- if(!sdm.disks[i].valid)
- {
- memcpy(&sdm.disks[i], &disk, sizeof(GFA_SYSINFO_DISK));
- sdm.disks[i].valid = true;
- bChange = true;
- nIndex = i;
- break;
- }
- }
- return nIndex;
- }
- static int _RemoveDisk(GFA_SYSINFO_STORAGE_DEVICE_MAP &sdm, int nIndex, bool &bChange)
- {
- bChange = false;
- if(nIndex >= 0 && nIndex < (int)_countof(sdm.disks))
- {
- bChange = sdm.disks[nIndex].valid;
- sdm.disks[nIndex].valid = false;
- }
- return nIndex;
- }
- #if 0
- static int _RemoveDisk(GFA_SYSINFO_STORAGE_DEVICE_MAP &sdm, const char *pszDevNode, bool &bChange)
- {
- int nIndex = _LookupDisk(sdm, pszDevNode);
- return _RemoveDisk(sdm, nIndex, bChange);
- }
- #endif
- static unsigned int _DiskAddPartition(GFA_SYSINFO_STORAGE_DEVICE_MAP &sdm, int nDiskIdx, int nPartIdx, bool &bChange)
- {
- bChange = false;
- if( (nPartIdx >= 0) && (nPartIdx < (int)_countof(sdm.parts)) &&
- (nDiskIdx >= 0) && (nDiskIdx < (int)_countof(sdm.disks)))
- {
- GFA_SYSINFO_DISK &disk = sdm.disks[nDiskIdx];
- for(unsigned int i = 0; i < disk.nPartCount; ++i)
- {
- if(disk.aPartIdx[i] == nPartIdx)
- return disk.nPartCount;
- }
- if(disk.nPartCount < _countof(disk.aPartIdx))
- {
- disk.aPartIdx[disk.nPartCount++] = nPartIdx;
- bChange = true;
- return disk.nPartCount;
- }
- }
- return 0;
- }
- static unsigned int _DiskRemovePartition(GFA_SYSINFO_STORAGE_DEVICE_MAP &sdm, int nDiskIdx, int nPartIdx, bool &bChange)
- {
- bChange = false;
- if( (nPartIdx >= 0) && (nPartIdx < (int)_countof(sdm.parts)) &&
- (nDiskIdx >= 0) && (nDiskIdx < (int)_countof(sdm.disks)))
- {
- unsigned int i, j;
- GFA_SYSINFO_DISK &disk = sdm.disks[nDiskIdx];
- for(i = 0; i < disk.nPartCount; ++i)
- {
- if(disk.aPartIdx[i] == nPartIdx)
- break;
- }
- if(i < disk.nPartCount)
- {
- for(j = i + 1; j < disk.nPartCount; ++i, ++j)
- {
- disk.aPartIdx[i] = disk.aPartIdx[j];
- }
- bChange = true;
- return --disk.nPartCount;
- }
- return disk.nPartCount;
- }
- return 0;
- }
- /////////////////////////////////////////////////////////////////////////////
- /////////////////////////////////////////////////////////////////////////////
- /////////////////////////////////////////////////////////////////////////////
- static bool _LookupMountPoint(MountMap &mm, const char *pszNode, char *pszMntPoint, size_t nCChMntPoint)
- {
- MountMap::const_iterator it = mm.find(pszNode);
- if(it == mm.end())
- return false;
- const std::string &s = it->second;
- if(s.length() < nCChMntPoint)
- {
- strcpy(pszMntPoint, s.c_str());
- return true;
- }
- return false;
- }
- static bool _UpdatePartitionFsInfo(MountMap &mm, GFA_SYSINFO_PARTITION &part)
- {
- if(_LookupMountPoint(mm, part.szDevNode, part.szMntPoint, sizeof(part.szMntPoint)))
- {
- struct statvfs stvs;
- if(!statvfs(part.szMntPoint, &stvs))
- {
- part.nKiBSize = stvs.f_bsize * stvs.f_blocks / 1024;
- part.nKiBFree = stvs.f_bsize * stvs.f_bfree / 1024;
- part.nKiBUsed = part.nKiBSize - part.nKiBFree;
- }
- else
- {
- TRACE("statvfs failed on \"%s\": %s\n", part.szMntPoint, strerror(errno));
- memset(part.szMntPoint, 0, sizeof(part.szMntPoint));
- part.nKiBSize = 0;
- part.nKiBFree = 0;
- part.nKiBUsed = 0;
- }
- return true;
- }
- else
- {
- memset(part.szMntPoint, 0, sizeof(part.szMntPoint));
- part.nKiBSize = 0;
- part.nKiBFree = 0;
- part.nKiBUsed = 0;
- }
- return false;
- }
- /////////////////////////////////////////////////////////////////////////////
- static std::string _StrReplace(std::string &s, const char *pszFind, const char *pszRepl)
- {
- std::string r = s;
- if(pszFind && *pszFind && pszRepl)
- {
- size_t nFind, nLen = strlen(pszFind);
- while((nFind = r.find(pszFind)) != std::string::npos)
- {
- r = r.replace(nFind, nLen, pszRepl);
- }
- }
-
- return r;
- }
-
- static std::string _UnescapeMountpointString(std::string &s)
- {
- std::string r = s;
- r = _StrReplace(r, "\\040", " ");
- r = _StrReplace(r, "\\011", "\t");
- r = _StrReplace(r, "\\012", "\n");
- r = _StrReplace(r, "\\134", "\\");
- return r;
- }
- static void _UpdateMountMap(MountMap &mm)
- {
- char szLine[512], szNode[512], szMount[512];
- std::ifstream mounts(_MOUNTS_FILE);
- mm.clear();
- while(mounts.getline(szLine, sizeof(szLine)).good())
- {
- if((sscanf(szLine, "%s %s", szNode, szMount) == 2))
- {
- std::string key(szNode);
- key = _UnescapeMountpointString(key);
- std::string val(szMount);
- val = _UnescapeMountpointString(val);
- mm.emplace(key, val);
- }
- }
- }
- /////////////////////////////////////////////////////////////////////////////
- static bool _ProcessMounts(GFA_SYSINFO_STORAGE_DEVICE_MAP &sdm, MountMap &mm)
- {
- bool bChange = false;
- char szMntPoint[_countof(GFA_SYSINFO_PARTITION::szMntPoint)];
- for(size_t i = 0; i < _countof(sdm.parts); ++i)
- {
- GFA_SYSINFO_PARTITION &part = sdm.parts[i];
- if(part.valid)
- {
- bool bMountedOld = !!*part.szMntPoint;
- bool bMountedNew = _LookupMountPoint(mm, part.szDevNode, szMntPoint, sizeof(szMntPoint));
- if(!bMountedOld && bMountedNew)
- {
- memcpy(part.szMntPoint, szMntPoint, sizeof(part.szMntPoint));
- _UpdatePartitionFsInfo(mm, part);
- _SetPartitionChange(sdm, i);
- bChange = true;
- }
- else if(bMountedOld && !bMountedNew)
- {
- memset(part.szMntPoint, 0, sizeof(part.szMntPoint));
- _UpdatePartitionFsInfo(mm, part);
- _SetPartitionChange(sdm, i);
- bChange = true;
- }
- else if(bMountedOld && bMountedNew)
- {
- if(strcmp(part.szMntPoint, szMntPoint))
- {
- memcpy(part.szMntPoint, szMntPoint, sizeof(part.szMntPoint));
- _UpdatePartitionFsInfo(mm, part);
- _SetPartitionChange(sdm, i);
- bChange = true;
- }
- }
- }
- }
- return bChange;
- }
- /////////////////////////////////////////////////////////////////////////////
- static void _ProcessCtrlMessages(HAPPCTRL hAC, HAPPINFO hAI)
- {
- ctrlmsg_t nCtrlMsg;
- while(g_fRun && (nCtrlMsg = ::GfaIpcAppCtrlGetNextCtrlMsg(hAI)))
- {
- switch(nCtrlMsg)
- {
- case GFA_APPCTRL_CTRLMSG_STOP:
- g_fRun = false;
- TRACE("Received Message: STOP!\n");
- break;
- case GFA_APPCTRL_CTRLMSG_PAUSE:
- if(!g_fPause)
- {
- g_fPause = true;
- ::GfaIpcAppCtrlSetState(hAC, GIAS_Paused);
- TRACE("%-8s: State: %s\n", "Me", g_pszStateNames[GIAS_Paused]);
- }
- break;
- case GFA_APPCTRL_CTRLMSG_RESUME:
- if(g_fPause)
- {
- g_fPause = false;
- ::GfaIpcAppCtrlSetState(hAC, GIAS_Running);
- TRACE("%-8s: State: %s\n", "Me", g_pszStateNames[GIAS_Running]);
- }
- break;
- default:
- break;
- }
- }
- }
- static const char* _GetFileSpec(const char *pszPathname)
- {
- if(pszPathname && *pszPathname)
- {
- const char *pSlash = strrchr(pszPathname, '/');
- if(pSlash)
- return ++pSlash;
- else
- return pszPathname;
- }
- return NULL;
- }
- static bool _IsInternalEmmc(const char *pszDevNode)
- {
- if(pszDevNode)
- {
- const char *pszDevName = _GetFileSpec(pszDevNode);
- return _STR_EQUALS(pszDevName, _INTERNAL_EMMC_PART2) || _STR_EQUALS(pszDevName, _INTERNAL_EMMC_PART1);
- }
- return false;
- }
- #if 0
- static void _EnumDevProperties(struct udev_device *dev, int nIndent)
- {
- if(dev)
- {
- struct udev_list_entry *prop;
- struct udev_list_entry *props = ::udev_device_get_properties_list_entry(dev);
- if(props)
- {
- udev_list_entry_foreach(prop, props)
- {
- const char *pszName = ::udev_list_entry_get_name(prop);
- const char *pszValue = ::udev_list_entry_get_value(prop);
- if(pszName && pszValue)
- {
- TRACE("%-*s+ %s = \"%s\"\n", nIndent + 2, " ", pszName, pszValue);
- }
- }
- }
- }
- }
- static void _EnumDevSysAttributes(struct udev_device *dev, int nIndent)
- {
- if(dev)
- {
- struct udev_list_entry *att;
- struct udev_list_entry *atts = ::udev_device_get_sysattr_list_entry(dev);
- if(atts)
- {
- udev_list_entry_foreach(att, atts)
- {
- const char *pszName = ::udev_list_entry_get_name(att);
- const char *pszValue = ::udev_device_get_sysattr_value(dev, pszName);
- if(pszName && pszValue && strcmp(pszName, "uevent"))
- {
- TRACE("%-*s- %s = \"%s\"\n", nIndent + 2, " ", pszName, pszValue);
- }
- }
- }
- }
- }
- #endif
- static const char *_FormatByteSize(unsigned long long nCb, char *pszBuf, size_t nCChBuf)
- {
- if(pszBuf && nCChBuf)
- {
- int nPrec = 2;
- double val = nCb;
-
- if(nCb < _BYTE_SIZE_KIB)
- {
- snprintf(pszBuf, nCChBuf, "%llu B", nCb); // Byte
- }
- else if(nCb < _BYTE_SIZE_MIB)
- {
- val /= _BYTE_SIZE_KIB;
- snprintf(pszBuf, nCChBuf, "%.*f KiB", nPrec, val); // KiB
- }
- else if(nCb < _BYTE_SIZE_GIB)
- {
- val /= _BYTE_SIZE_MIB;
- snprintf(pszBuf, nCChBuf, "%.*f MiB", nPrec, val); // MiB
- }
- else if(nCb < _BYTE_SIZE_TIB)
- {
- val /= _BYTE_SIZE_GIB;
- snprintf(pszBuf, nCChBuf, "%.*f GiB", nPrec, val); // GiB
- }
- else if(nCb < _BYTE_SIZE_PIB)
- {
- val /= _BYTE_SIZE_TIB;
- snprintf(pszBuf, nCChBuf, "%.*f TiB", nPrec, val); // TiB
- }
- else if(nCb < _BYTE_SIZE_EIB)
- {
- val /= _BYTE_SIZE_PIB;
- snprintf(pszBuf, nCChBuf, "%.*f PiB", nPrec, val); // PiB
- }
-
- return pszBuf;
- }
-
- return NULL;
- }
- static void _DumpDeviceMap(const GFA_SYSINFO_STORAGE_DEVICE_MAP &sdm)
- {
- TRACE("\n");
- for(size_t i = 0; i < _countof(sdm.disks); ++i)
- {
- char szByteBuf[16];
- const GFA_SYSINFO_DISK &disk = sdm.disks[i];
- if(disk.valid && !disk.internal)
- {
- TRACE("Disk:\n");
- TRACE(" |-Label: %s\n", disk.szName);
- TRACE(" |-Vendor: %s\n", *disk.szVendor ? disk.szVendor : "n/a");
- TRACE(" |-Node: %s\n", disk.szDevNode);
- TRACE(" |-Type: %s\n", *disk.szBus ? disk.szBus : "mmc");
- for(unsigned int j = 0; j < disk.nPartCount; ++j)
- {
- int nIndex = disk.aPartIdx[j];
- const GFA_SYSINFO_PARTITION &part = sdm.parts[nIndex];
- bool bMounted = !!*part.szMntPoint;
- TRACE(" |-Partition:\n");
- TRACE(" |-Label: %s\n", part.szFsLabel);
- TRACE(" |-Node: %s\n", part.szDevNode);
- TRACE(" |-PA-Size: %s\n", _FormatByteSize(part.nKiBPartSize * _BYTE_SIZE_KIB, szByteBuf, sizeof(szByteBuf)));
- TRACE(" |-Mount: %s\n", bMounted ? part.szMntPoint : "Not mounted");
- if(bMounted)
- {
- TRACE(" |-FS-Type: %s\n", part.szFsType);
- TRACE(" |-FS-Ver.: %s\n", part.szFsVersion);
- TRACE(" |-FS-Size: %s\n", _FormatByteSize(part.nKiBSize * _BYTE_SIZE_KIB, szByteBuf, sizeof(szByteBuf)));
- TRACE(" |-FS-Used: %s\n", _FormatByteSize(part.nKiBUsed * _BYTE_SIZE_KIB, szByteBuf, sizeof(szByteBuf)));
- TRACE(" |-FS-Free: %s\n", _FormatByteSize(part.nKiBFree * _BYTE_SIZE_KIB, szByteBuf, sizeof(szByteBuf)));
- }
- }
- }
- }
- TRACE("\n");
- }
- static long long _NumberFromString(const char *pszString, int base, bool *pbErr)
- {
- if(!pszString || !*pszString)
- {
- if(pbErr)
- *pbErr = true;
- return 0;
- }
- char *endptr;
- long long nRet = strtoll(pszString, &endptr, base);
- if( (((nRet == LLONG_MAX) || (nRet == LLONG_MIN)) && (errno == ERANGE)) ||
- ((nRet == 0) && (errno == EINVAL)) ||
- (!!*endptr))
- {
- if(pbErr)
- *pbErr = true;
- return 0;
- }
- if(pbErr)
- *pbErr = false;
- return nRet;
- }
- static long long _ReadDevPropertyValue(struct udev_device* dev, const char *pszKey, int base, bool *pbErr)
- {
- char szNum[64];
- return _NumberFromString(_ReadDevPropertyValue(dev, pszKey, szNum, sizeof(szNum), false), base, pbErr);
- }
- static const char* _ReadDevPropertyValue(struct udev_device* dev, const char *pszKey, char *pszValue, size_t nCChValue, bool bTruncate)
- {
- if(!pszValue || !nCChValue)
- return NULL;
- memset(pszValue, 0, nCChValue);
- const char *pszVal = ::udev_device_get_property_value(dev, pszKey);
- if(pszVal)
- {
- size_t nLen = strlen(pszVal);
- if(nLen < nCChValue)
- {
- strcpy(pszValue, pszVal);
- return pszValue;
- }
- else if(bTruncate)
- {
- memcpy(pszValue, pszVal, nCChValue);
- pszValue[nCChValue - 1] = '\0';
- return pszValue;
- }
- }
- return NULL;
- }
- static void _ProcessPartition(GFA_SYSINFO_STORAGE_DEVICE_MAP &sdm, MountMap &mm, struct udev_device* dev)
- {
- if(dev)
- {
- bool bChange;
- GFA_SYSINFO_PARTITION part;
- memset(&part, 0, sizeof(part));
- part.nDiskIdx = -1;
- int nPartIdx = -1;
- int nDiskIdx = -1;
- const char *pszDevNode = ::udev_device_get_devnode(dev);
- if(!pszDevNode)
- return;
- // if(_IsInternalEmmc(pszDevNode))
- // return; // skip internal emmc
- bool bInternalEmmc = _IsInternalEmmc(pszDevNode);
- strncpy(part.szDevNode, pszDevNode, sizeof(part.szDevNode) - 1);
- const char *pszAction = ::udev_device_get_action(dev);
- bool bAdd = _STR_EQUALS(pszAction, "add");
- bool bRem = _STR_EQUALS(pszAction, "remove");
- bool bEnum = !pszAction;
- if(bAdd || bEnum)
- {
- if(_LookupPartition(sdm, part.szDevNode) >= 0)
- return;
- part.internal = bInternalEmmc;
- _ReadDevPropertyValue(dev, "ID_FS_LABEL", part.szFsLabel, sizeof(part.szFsLabel), true);
- _ReadDevPropertyValue(dev, "ID_FS_TYPE", part.szFsType, sizeof(part.szFsType), true);
- _ReadDevPropertyValue(dev, "ID_FS_VERSION", part.szFsVersion, sizeof(part.szFsVersion), true);
- part.nKiBPartSize = _ReadDevPropertyValue(dev, "ID_PART_ENTRY_SIZE") / 2;
- _UpdatePartitionFsInfo(mm, part);
- struct udev_device* cur = dev;
- while((cur = ::udev_device_get_parent(cur)))
- {
- const char *pszSs = ::udev_device_get_subsystem(cur);
- const char *pszDt = ::udev_device_get_devtype(cur);
- const char *pszDn = ::udev_device_get_devnode(cur);
- if(!pszDn)
- break;
- if(_STR_EQUALS(pszSs, "usb") || _STR_EQUALS(pszSs, "block"))
- {
- if(_STR_EQUALS(pszDt, "disk"))
- {
- GFA_SYSINFO_DISK disk;
- memset(&disk, 0, sizeof(disk));
- strncpy(disk.szDevNode, pszDn, sizeof(disk.szDevNode) - 1);
- disk.internal = bInternalEmmc;
- if(!_ReadDevPropertyValue(cur, "ID_NAME", disk.szName, sizeof(disk.szName), true))
- _ReadDevPropertyValue(cur, "ID_MODEL", disk.szName, sizeof(disk.szName), true);
- _ReadDevPropertyValue(cur, "ID_VENDOR", disk.szVendor, sizeof(disk.szVendor), true);
- _ReadDevPropertyValue(cur, "ID_BUS", disk.szBus, sizeof(disk.szBus), true);
- disk.nVendorID = _ReadDevPropertyValue(cur, "ID_VENDOR_ID", 16);
- disk.nProductID = _ReadDevPropertyValue(cur, "ID_MODEL_ID", 16);
- if((nDiskIdx = _AddDisk(sdm, disk, bChange)) >= 0)
- {
- if((nPartIdx = _AddPartition(sdm, part, bChange)) < 0)
- {
- if(sdm.disks[nDiskIdx].nPartCount == 0)
- _RemoveDisk(sdm, nDiskIdx, bChange);
- break;
- }
- _DiskAddPartition(sdm, nDiskIdx, nPartIdx, bChange);
- _PartitionSetDisk(sdm, nPartIdx, nDiskIdx, bChange);
- _SetPartitionChange(sdm, nPartIdx);
- }
- break;
- }
- }
- }
- }
- else if(bRem)
- {
- if((nPartIdx = _LookupPartition(sdm, pszDevNode)) >= 0)
- {
- _RemovePartition(sdm, nPartIdx, bChange);
- _SetPartitionChange(sdm, nPartIdx);
- if((nDiskIdx = _PartitionGetDisk(sdm, nPartIdx)) >= 0)
- {
- if(!_DiskRemovePartition(sdm, nDiskIdx, nPartIdx, bChange))
- {
- _RemoveDisk(sdm, nDiskIdx, bChange);
- }
- }
- }
- }
- }
- }
- static void _EnumStorageDevices(GFA_SYSINFO_STORAGE_DEVICE_MAP &sdm, MountMap &mm, struct udev *pUdev)
- {
- struct udev_enumerate *pEnum = ::udev_enumerate_new(pUdev);
- ::udev_enumerate_add_match_subsystem(pEnum, "block");
- ::udev_enumerate_add_match_property(pEnum, "DEVTYPE", "partition");
- ::udev_enumerate_scan_devices(pEnum);
- struct udev_list_entry *devices = ::udev_enumerate_get_list_entry(pEnum);
- struct udev_list_entry *entry;
- udev_list_entry_foreach(entry, devices)
- {
- const char *pszPath = ::udev_list_entry_get_name(entry);
- struct udev_device* dev = ::udev_device_new_from_syspath(pUdev, pszPath);
- _ProcessPartition(sdm, mm, dev);
- ::udev_device_unref(dev);
- }
- ::udev_enumerate_unref(pEnum);
- }
- /////////////////////////////////////////////////////////////////////////////
- static void _SigHandler(int sig)
- {
- UNUSED(sig);
- g_fPause = false;
- g_fRun = false;
- g_fZombie = false;
- }
- /////////////////////////////////////////////////////////////////////////////
- /////////////////////////////////////////////////////////////////////////////
- /////////////////////////////////////////////////////////////////////////////
- int main(int argc, char *argv[])
- {
- UNUSED(argc);
- UNUSED(argv);
- HAPPCTRL hAC = NULL;
- HAPPINFO hAI;
- CCycleTimer ct(_CYCLE_INTV);
- cy_time_t wStart, wEnd, wCur = 0;
- struct udev *pUdev = NULL;
- struct timeval tv;
- memset(&tv, 0, sizeof(tv));
- struct udev_monitor *pUdevMon = NULL;
- GFA_SYSINFO_STORAGE_DEVICE_MAP sdm;
- memset(&sdm, 0, sizeof(sdm));
- MountMap mm;
- pollfd pfd[2];
- memset(&pfd, 0, sizeof(pfd));
- /////////////////////////////////////////////////////////////////////////
- /////////////////////////////////////////////////////////////////////////
- /////////////////////////////////////////////////////////////////////////
- // signal handling
- struct sigaction sa;
- memset(&sa, 0, sizeof(sa));
- // handle signals
- sa.sa_handler = _SigHandler;
- sigaction(SIGHUP, &sa, NULL); // handles user's terminal disconnect
- sigaction(SIGQUIT, &sa, NULL); // handles Ctrl + '\'
- sigaction(SIGTERM, &sa, NULL); // handles normal termination
- sigaction(SIGABRT, &sa, NULL); // handles abnormal termination (i.e. abort())
- sigaction(SIGINT, &sa, NULL); // handles Ctrl + 'C'
- // ignore signals
- sa.sa_handler = SIG_IGN;
- sigaction(SIGTSTP, &sa, NULL); // ignores Ctrl + 'Z'
- sigaction(SIGCHLD, &sa, NULL); // ignores child process termination
- sigaction(0, &sa, NULL); // ignores shell termination
- /////////////////////////////////////////////////////////////////////////
- /////////////////////////////////////////////////////////////////////////
- /////////////////////////////////////////////////////////////////////////
- // initialize
- do
- {
- g_fZombie = true;
- if(!(hAC = ::GfaIpcAppCtrlAcquire(_APPID, _APPNAME, _CYCLE_INTV * 1000, _CYCLE_INTV * 3000)))
- {
- TRACE("GfaIpcAppCtrlAcquire failed\n");
- break;
- }
- ::GfaIpcAppCtrlSetState(hAC, GIAS_Initializing);
- if(!::GfaIpcAppCtrlCreateSysInfo(hAC))
- {
- TRACE("GfaIpcAppCtrlCreateSysInfo failed\n");
- break;
- }
- if(!(pUdev = ::udev_new()))
- {
- TRACE("udev_new failed\n");
- break;
- }
- _UpdateMountMap(mm);
- _EnumStorageDevices(sdm, mm, pUdev);
- if(!(pUdevMon = ::udev_monitor_new_from_netlink(pUdev, "udev")))
- {
- TRACE("udev_monitor_new_from_netlink failed\n");
- break;
- }
- if(::udev_monitor_filter_add_match_subsystem_devtype(pUdevMon, "block", "partition") < 0)
- {
- TRACE("udev_monitor_filter_add_match_subsystem_devtype failed\n");
- break;
- }
- if(::udev_monitor_enable_receiving(pUdevMon) < 0)
- {
- TRACE("udev_monitor_enable_receiving failed\n");
- break;
- }
- pfd[0].fd = ::udev_monitor_get_fd(pUdevMon);
- pfd[0].events = POLLIN;
- pfd[0].revents = 0;
- pfd[1].fd = open(_MOUNTS_FILE, O_RDONLY, 0);
- pfd[1].events = POLLPRI;
- pfd[1].revents = 0;
- ;;GfaIpcDumpSHMROT();
- TRACE("My Name: %s\n", _APPNAME);
- TRACE("My AppID: %llu\n", _APPID);
- TRACE("My PID: %d\n", getpid());
- TRACE("My Cycle: %d\n", _CYCLE_INTV);
- g_fZombie = false;
- g_fRun = true;
- ::GfaIpcAppCtrlSetState(hAC, GIAS_Running);
- ::GfaIpcAppCtrlUpdateStorageDeviceMap(hAC, sdm);
- // _DumpDeviceMap(sdm);
- }
- while(false);
- /////////////////////////////////////////////////////////////////////////
- /////////////////////////////////////////////////////////////////////////
- /////////////////////////////////////////////////////////////////////////
- // run
- while(g_fRun)
- {
- /////////////////////////////////////////////////////////////////////
- // trigger cycle timer
- ct.Trigger();
- /////////////////////////////////////////////////////////////////////
- // update app control info
- if((hAI = ::GfaIpcAppCtrlInfoUpdate(hAC, wCur)))
- {
- _ProcessCtrlMessages(hAC, hAI);
- }
- /////////////////////////////////////////////////////////////////////
- // if not paused, do work
- if(!g_fPause && g_fRun)
- {
- wStart = ct.GetMicroTick();
- ::GfaIpcAppCtrlUpdateSysInfo(hAC);
- wEnd = ct.GetMicroTick();
- wCur = wEnd - wStart;
- _ClearMapChanges(sdm);
- while(poll(pfd, 2, _CYCLE_INTV / 5) > 0)
- {
- _UpdateMountMap(mm);
- if(pfd[0].revents & POLLIN)
- {
- struct udev_device* dev;
- while((dev = ::udev_monitor_receive_device(pUdevMon)))
- {
- _ProcessPartition(sdm, mm, dev);
- }
- }
- if(pfd[1].revents & POLLPRI)
- {
- _ProcessMounts(sdm, mm);
- }
- }
- if(_DeviceMapChanged(sdm))
- {
- ::GfaIpcAppCtrlUpdateStorageDeviceMap(hAC, sdm);
- // _DumpDeviceMap(sdm);
- }
- }
- /////////////////////////////////////////////////////////////////////
- // if running, sleep
- if(g_fRun)
- ct.Sleep1();
- }
- /////////////////////////////////////////////////////////////////////////
- /////////////////////////////////////////////////////////////////////////
- /////////////////////////////////////////////////////////////////////////
- // terminate
- if(pfd[0].fd >= 0)
- close(pfd[0].fd);
- if(pfd[1].fd >= 0)
- close(pfd[1].fd);
- if(pUdevMon)
- ::udev_monitor_unref(pUdevMon);
- if(pUdev)
- ::udev_unref(pUdev);
-
- if(g_fZombie)
- {
- if(hAC)
- ::GfaIpcAppCtrlSetState(hAC, GIAS_Zombie);
- TRACE("%-8s: State: %s\n", "Me", ::GfaIpcAppCtrlGetStateText(GIAS_Zombie));
- pause();
- }
- if(hAC)
- {
- ::GfaIpcAppCtrlSetState(hAC, GIAS_Terminating);
- ::GfaIpcAppCtrlReleaseSysInfo(hAC);
- ::GfaIpcAppCtrlRelease(hAC);
- }
- return 0;
- }
|