static void viewer_fam_monitor(viewer_t *viewer, char *filename) { if ( viewer->fc_tag < 0 ) return; if ( FAMMonitorFile(&(viewer->fc), filename, &(viewer->fc_req), viewer) ) { fprintf(stderr, NAME ": WARNING: Failed to setup FAM monitor on file '%s': %s\n", filename, FamErrlist[FAMErrno]); } else { viewer->fc_req_ok = 1; } }
static void reconnect_fam( gpointer key, gpointer value, gpointer user_data ) { struct stat file_stat; // skip stat64 VFSFileMonitor* monitor = ( VFSFileMonitor* ) value; const char* path = ( const char* ) key; if ( lstat( path, &file_stat ) != -1 ) { #ifdef USE_INOTIFY /* Linux inotify */ monitor->wd = inotify_add_watch ( inotify_fd, path, IN_MODIFY | IN_CREATE | IN_DELETE | IN_MOVE ); if ( monitor->wd < 0 ) { /* * FIXME: add monitor to an ancestor which does actually exist, * or do the equivalent of inotify-missing.c by maintaining * a list of monitors on non-existent files/directories * which you retry in a timeout. */ g_warning ( "Failed to add monitor on '%s': %s", path, g_strerror ( errno ) ); return ; } #else if ( S_ISDIR( file_stat.st_mode ) ) { FAMMonitorDirectory( &fam, path, &monitor->request, monitor ); } else { FAMMonitorFile( &fam, path, &monitor->request, monitor ); } #endif } }
static void g_fam_file_monitor_start (GLocalFileMonitor *local_monitor, const gchar *dirname, const gchar *basename, const gchar *filename, GFileMonitorSource *source) { GFamFileMonitor *gffm = G_FAM_FILE_MONITOR (local_monitor); g_mutex_lock (&fam_lock); g_assert (fam_initialised); g_source_ref ((GSource *) source); if (dirname) FAMMonitorDirectory (&fam_connection, dirname, &gffm->request, source); else FAMMonitorFile (&fam_connection, filename, &gffm->request, source); g_mutex_unlock (&fam_lock); }
VFSFileMonitor* vfs_file_monitor_add( char* path, gboolean is_dir, VFSFileMonitorCallback cb, gpointer user_data ) { VFSFileMonitor * monitor; VFSFileMonitorCallbackEntry cb_ent; struct stat file_stat; // skip stat64 gchar* real_path = NULL; //printf( "vfs_file_monitor_add %s\n", path ); if ( ! monitor_hash ) return NULL; monitor = ( VFSFileMonitor* ) g_hash_table_lookup ( monitor_hash, path ); if ( ! monitor ) { monitor = g_slice_new0( VFSFileMonitor ); monitor->path = g_strdup( path ); monitor->callbacks = g_array_new ( FALSE, FALSE, sizeof( VFSFileMonitorCallbackEntry ) ); g_hash_table_insert ( monitor_hash, monitor->path, monitor ); /* NOTE: Since gamin, FAM and inotify don't follow symlinks, we need to do some special processing here. */ if ( lstat( path, &file_stat ) == 0 ) { const char* link_file = path; while( G_UNLIKELY( S_ISLNK(file_stat.st_mode) ) ) { char* link = g_file_read_link( link_file, NULL ); char* dirname = g_path_get_dirname( link_file ); real_path = vfs_file_resolve_path( dirname, link ); g_free( link ); g_free( dirname ); if( lstat( real_path, &file_stat ) == -1 ) break; link_file = real_path; } } #ifdef USE_INOTIFY /* Linux inotify */ monitor->wd = inotify_add_watch ( inotify_fd, real_path ? real_path : path, IN_MODIFY | IN_CREATE | IN_DELETE | IN_DELETE_SELF | IN_MOVE | IN_MOVE_SELF | IN_UNMOUNT | IN_ATTRIB); if ( monitor->wd < 0 ) { g_warning ( "Failed to add monitor on '%s': %s", path, g_strerror ( errno ) ); return NULL; } #else /* Use FAM|gamin */ //MOD see NOTE1 in vfs-mime-type.c - what happens here if path doesn't exist? // inotify returns NULL - does fam? if ( is_dir ) { FAMMonitorDirectory( &fam, real_path ? real_path : path, &monitor->request, monitor ); } else { FAMMonitorFile( &fam, real_path ? real_path : path, &monitor->request, monitor ); } #endif g_free( real_path ); } if( G_LIKELY(monitor) ) { /* g_debug( "monitor installed: %s, %p", path, monitor ); */ if ( cb ) { /* Install a callback */ cb_ent.callback = cb; cb_ent.user_data = user_data; monitor->callbacks = g_array_append_val( monitor->callbacks, cb_ent ); } g_atomic_int_inc( &monitor->n_ref ); } return monitor; }
static int processCommand(char *line, int no) { int ret, args; char *command = NULL; char *arg = NULL; char *arg2 = NULL; if (line == NULL) return (-1); if (line[0] == '#') return (0); args = scanCommand(line, &command, &arg, &arg2); if (args < 0) return (-1); if (args == 0) return (0); if (!strcmp(command, "connect")) { if (testState.connected) { fprintf(stderr, "connect line %d: already connected\n", no); return (-1); } if (arg != NULL) { #ifdef HAVE_SETENV setenv("GAM_CLIENT_ID", arg, 1); #elif HAVE_PUTENV char *client_id = malloc (strlen (arg) + sizeof "GAM_CLIENT_ID="); if (client_id) { strcpy (client_id, "GAM_CLIENT_ID="); strcat (client_id, arg); putenv (client_id); } #endif /* HAVE_SETENV */ } ret = FAMOpen(&(testState.fc)); if (ret < 0) { fprintf(stderr, "connect line %d: failed to connect\n", no); return (-1); } testState.connected = 1; if (arg != NULL) printf("connected to %s\n", arg); else printf("connected\n"); } else if (!strcmp(command, "kill")) { /* * okay, it's heavy but that's the simplest way since we do not have * the pid(s) of the servers running. */ ret = system("killall gam_server"); if (ret < 0) { fprintf(stderr, "kill line %d: failed to killall gam_server\n", no); return (-1); } printf("killall gam_server\n"); } else if (!strcmp(command, "disconnect")) { if (testState.connected == 0) { fprintf(stderr, "disconnect line %d: not connected\n", no); return (-1); } ret = FAMClose(&(testState.fc)); if (ret < 0) { fprintf(stderr, "connect line %d: failed to disconnect\n", no); return (-1); } testState.connected = 0; printf("disconnected\n"); } else if (!strcmp(command, "mondir")) { if (args >= 2) { if (arg[0] != '/') snprintf(filename, sizeof(filename), "%s/%s", pwd, arg); else snprintf(filename, sizeof(filename), "%s", arg); } if (args == 2) { ret = FAMMonitorDirectory(&(testState.fc), filename, &(testState. fr[testState.nb_requests]), NULL); } else if (args == 3) { int index; if (sscanf(arg2, "%d", &index) <= 0) { fprintf(stderr, "mondir line %d: invalid index value %s\n", no, arg2); return (-1); } testState.fr[testState.nb_requests].reqnum = index; ret = FAMMonitorDirectory2(&(testState.fc), filename, &(testState. fr[testState.nb_requests])); } else { fprintf(stderr, "mondir line %d: invalid format\n", no); return (-1); } if (ret < 0) { fprintf(stderr, "mondir line %d: failed to monitor %s\n", no, arg); return (-1); } printf("mondir %s %d\n", arg, testState.nb_requests); testState.nb_requests++; } else if (!strcmp(command, "monfile")) { if (args != 2) { fprintf(stderr, "monfile line %d: lacks name\n", no); return (-1); } if (arg[0] != '/') snprintf(filename, sizeof(filename), "%s/%s", pwd, arg); else snprintf(filename, sizeof(filename), "%s", arg); ret = FAMMonitorFile(&(testState.fc), filename, &(testState.fr[testState.nb_requests]), NULL); if (ret < 0) { fprintf(stderr, "monfile line %d: failed to monitor %s\n", no, arg); return (-1); } printf("monfile %s %d\n", arg, testState.nb_requests); testState.nb_requests++; } else if (!strcmp(command, "pending")) { if (args != 1) { fprintf(stderr, "pending line %d: extra argument %s\n", no, arg); return (-1); } ret = FAMPending(&(testState.fc)); if (ret < 0) { fprintf(stderr, "pending line %d: failed\n", no); return (-1); } printf("pending %d\n", ret); } else if (!strcmp(command, "mkdir")) { if (args != 2) { fprintf(stderr, "mkdir line %d: lacks name\n", no); return (-1); } ret = mkdir(arg, 0755); if (ret < 0) { fprintf(stderr, "mkdir line %d: failed to create %s\n", no, arg); return (-1); } printf("mkdir %s\n", arg); } else if (!strcmp(command, "chmod")) { if (args != 3) { fprintf(stderr, "chmod line %d: lacks path and mode\n", no); return (-1); } ret = chmod(arg, strtol (arg2, NULL, 8)); if (ret < 0) { fprintf(stderr, "chmod line %d: failed to chmod %s to %s\n", no, arg, arg2); return (-1); } printf("chmod %s to %s\n", arg, arg2); } else if (!strcmp(command, "chown")) { if (args != 3) { fprintf(stderr, "chown line %d: lacks path and owner\n", no); return (-1); } struct stat sb; if (!lstat (arg, &sb)) { ret = (S_ISLNK (sb.st_mode)) ? lchown(arg, strtol(arg2, NULL, 10), -1) : chown(arg, strtol(arg2, NULL, 10), -1); } else ret=-1; if (ret < 0) { fprintf(stderr, "chown line %d: failed to chown %s to %s\n", no, arg, arg2); return (-1); } printf("chown %s to %s\n", arg, arg2); } else if (!strcmp(command, "mkfile")) { if (args != 2) { fprintf(stderr, "mkfile line %d: lacks name\n", no); return (-1); } ret = open(arg, O_CREAT | O_WRONLY, 0666); if (ret < 0) { fprintf(stderr, "mkfile line %d: failed to open %s\n", no, arg); return (-1); } close(ret); printf("mkfile %s\n", arg); } else if (!strcmp(command, "append")) { if (args != 2) { fprintf(stderr, "mkfile line %d: lacks name\n", no); return (-1); } ret = open(arg, O_RDWR | O_APPEND); if (ret < 0) { fprintf(stderr, "append line %d: failed to open %s\n", no, arg); return (-1); } write(ret, "a", 1); close(ret); printf("append %s\n", arg); } else if (!strcmp(command, "rmdir")) { if (args != 2) { fprintf(stderr, "rmdir line %d: lacks name\n", no); return (-1); } ret = rmdir(arg); if (ret < 0) { fprintf(stderr, "rmdir line %d: failed to remove %s\n", no, arg); return (-1); } printf("rmdir %s\n", arg); } else if (!strcmp(command, "rmfile")) { if (args != 2) { fprintf(stderr, "rmfile line %d: lacks name\n", no); return (-1); } ret = unlink(arg); if (ret < 0) { fprintf(stderr, "rmfile line %d: failed to unlink %s\n", no, arg); return (-1); } printf("rmfile %s\n", arg); } else if (!strcmp(command, "move")) { if (args != 3) { fprintf(stderr, "move line %d: lacks something\n", no); return (-1); } ret = rename(arg, arg2); if (ret < 0) { fprintf(stderr, "move line %d: failed to move %s\n", no, arg); return (-1); } printf("move %s %s\n", arg, arg2); } else if (!strcmp(command, "link")) { if (args != 3) { fprintf(stderr, "link line %d: lacks target and name\n", no); return (-1); } ret = symlink(arg, arg2); if (ret < 0) { fprintf(stderr, "link line %d: failed to link to %s\n", no, arg); return (-1); } printf("link %s to %s\n", arg2, arg); } else if (!strcmp(command, "event")) { printEvent(no); } else if (!strcmp(command, "events")) { printEvents(no); } else if (!strcmp(command, "expect")) { int count; int delay = 0; int nb_events = testState.nb_events; if (args != 2) { fprintf(stderr, "expect line %d: lacks number\n", no); return (-1); } if (sscanf(arg, "%d", &count) <= 0) { fprintf(stderr, "expect line %d: invalid number value %s\n", no, arg); return (-1); } /* * wait at most 3 secs before declaring failure */ while ((delay < 30) && (testState.nb_events < nb_events + count)) { debugLoop(100); /* printf("+"); fflush(stdout); */ delay++; } if (testState.nb_events < nb_events + count) { printf("expect line %d: got %d of %d expected events\n", no, testState.nb_events - nb_events, count); return (-1); } } else if (!strcmp(command, "sleep")) { int i; for (i = 0; (i < 30) && (FAMPending(&(testState.fc)) == 0); i++) usleep(50000); } else if (!strcmp(command, "wait")) { sleep(1); } else if (!strcmp(command, "cancel")) { if (args == 2) { int req_index = 0; if (sscanf(arg, "%d", &req_index) <= 0 || req_index >= testState.nb_requests) { fprintf(stderr, "cancel line %d: invalid req_index value %s\n", no, arg); return (-1); } ret = FAMCancelMonitor(&(testState.fc), &(testState.fr[req_index])); } else { fprintf(stderr, "cancel line %d: invalid format\n", no); return (-1); } if (ret < 0) { fprintf(stderr, "cancel line %d: failed to cancel req_index %s\n", no, arg); return (-1); } printf("cancel %s %d\n", arg, testState.nb_requests); } else { fprintf(stderr, "Unable to parse line %d: %s\n", no, line); return (-1); } return (0); }
int main(int argc, char **argv) { vector<string> cfg; size_t cfg_num = 0; if(argc==2) { cfg.push_back(argv[1]); } else if(argc==3) { cfg.push_back(argv[1]); cfg.push_back(argv[2]); } else { cfg.push_back(CONFIG_FILE); } time_t mtime; struct stat s; if (stat(cfg[cfg_num].c_str(), &s) == 0) { mtime = s.st_mtime; } else { mtime = 0; } cout << "BBC MDI Generator Rev " << svn_version() << ", using libsdixml Rev " << libsdixml::svn_version() << endl << "Implementing SDI Schema version " << libsdixml::SDI_Schema_version() << endl << "Reading config from " << cfg[cfg_num] << endl; cout.flush(); Mdigen mdigen; /* DcpIn dcpin; dcpin.ReConfigure("dcp.udp://:9998"); tagpacketlist t; dcpin.getFrame(t); for(tagpacketlist::iterator i=t.begin(); i!=t.end(); i++) cout << i->first << " " << i->second.size() << endl; */ #ifdef WIN32 int iResult; WSADATA wsaData; // Initialize Winsock iResult = WSAStartup(MAKEWORD(2,2), &wsaData); if (iResult != 0) { printf("WSAStartup failed: %d\n", iResult); exit(1); } #else struct sigaction sa; sa.sa_flags = SA_SIGINFO; sigemptyset(&sa.sa_mask); sa.sa_sigaction = signal_handler; if (sigaction(SIGHUP, &sa, NULL) == -1) { cerr << "error assigning signal handler" << endl; exit(1); } FAMConnection fc; if(FAMOpen(&fc)==0) { FAMRequest fr; if(cfg[0][0]!='/') { string path = getenv("PWD"); cerr << path << endl; cfg[0] = path + "/" + cfg[0]; } if(FAMMonitorFile(&fc, cfg[0].c_str(), &fr, NULL)) cerr << "can't monitor " << cfg[0] << endl; else cout << "FAM Monitoring " << cfg[0] << endl; } else { cerr << "can't connect to file alteration monitor " << endl; } #endif bool ok = true; int max_frames = -1; int reconf_interval = 32; int reconf = reconf_interval; ReConfigure(mdigen, cfg[cfg_num], ok, max_frames); while(ok) { try { mdigen.eachframe(); //cout << "Frame: " << mdigen.transmitted_frames << endl; #ifndef WIN32 while(FAMPending(&fc)) { FAMEvent fe; FAMNextEvent(&fc, &fe); switch(fe.code) { case FAMDeleted: break; case FAMChanged: cout << "file alteration monitor detected config change" << endl; reconfiguration_requested = true; break; case FAMCreated: case FAMExists: break; case FAMEndExist: cout << "FAM initialised " << fe.filename << endl; break; case FAMAcknowledge: cout << "FAM cancel acknowledged " << fe.filename << endl; break; case FAMStartExecuting: case FAMStopExecuting: case FAMMoved: cout << "unexpected fam event " << fe.code << " '" << fe.filename << "'" << endl; break; default: cout << "unknown fam event " << fe.code << " '" << fe.filename << "'" << endl; } } #endif } catch(char const* e) { cerr << e << endl; cerr.flush(); } if(reconfiguration_requested) { ReConfigure(mdigen, cfg[cfg_num], ok, max_frames); } if(cfg.size()>1) { reconf--; if(reconf==0) { cfg_num = 1 - cfg_num; ReConfigure(mdigen, cfg[cfg_num], ok, max_frames); reconf = reconf_interval; } } if(max_frames!=-1 && mdigen.transmitted_frames > max_frames) break; } }